diff --git a/.github/actions/download-artifact/action.yml b/.github/actions/download-artifact/action.yml index 58c2aa90607..534b3251c5c 100644 --- a/.github/actions/download-artifact/action.yml +++ b/.github/actions/download-artifact/action.yml @@ -12,7 +12,7 @@ runs: using: "composite" steps: - name: Download Godot Artifact - uses: actions/download-artifact@v3 + uses: actions/download-artifact@v4 with: name: ${{ inputs.name }} path: ${{ inputs.path }} diff --git a/.github/actions/godot-cache/action.yml b/.github/actions/godot-cache/action.yml index 09ad2099cc3..b7ca01bb47d 100644 --- a/.github/actions/godot-cache/action.yml +++ b/.github/actions/godot-cache/action.yml @@ -12,7 +12,7 @@ runs: steps: # Upload cache on completion and check it out now - name: Load .scons_cache directory - uses: actions/cache@v3 + uses: actions/cache@v4 with: path: ${{inputs.scons-cache}} key: ${{inputs.cache-name}}-${{env.GODOT_BASE_BRANCH}}-${{github.ref}}-${{github.sha}} diff --git a/.github/actions/godot-deps/action.yml b/.github/actions/godot-deps/action.yml index 38731db5d6b..881eb7d1f68 100644 --- a/.github/actions/godot-deps/action.yml +++ b/.github/actions/godot-deps/action.yml @@ -12,7 +12,7 @@ runs: steps: # Use python 3.x release (works cross platform) - name: Set up Python 3.x - uses: actions/setup-python@v4 + uses: actions/setup-python@v5 with: # Semantic version range syntax or exact version of a Python version python-version: ${{ inputs.python-version }} diff --git a/.github/actions/upload-artifact/action.yml b/.github/actions/upload-artifact/action.yml index ae0e634cbf4..8033839a7c2 100644 --- a/.github/actions/upload-artifact/action.yml +++ b/.github/actions/upload-artifact/action.yml @@ -12,7 +12,7 @@ runs: using: "composite" steps: - name: Upload Godot Artifact - uses: actions/upload-artifact@v3 + uses: actions/upload-artifact@v4 with: name: ${{ inputs.name }} path: ${{ inputs.path }} diff --git a/.github/workflows/android_builds.yml b/.github/workflows/android_builds.yml index 6a9b1238878..7596c0efec0 100644 --- a/.github/workflows/android_builds.yml +++ b/.github/workflows/android_builds.yml @@ -21,7 +21,7 @@ jobs: - uses: actions/checkout@v4 - name: Set up Java 17 - uses: actions/setup-java@v3 + uses: actions/setup-java@v4 with: distribution: temurin java-version: 17 diff --git a/.github/workflows/web_builds.yml b/.github/workflows/web_builds.yml index a2a5e87943f..598ff3cf7c1 100644 --- a/.github/workflows/web_builds.yml +++ b/.github/workflows/web_builds.yml @@ -23,10 +23,11 @@ jobs: - uses: actions/checkout@v4 - name: Set up Emscripten latest - uses: mymindstorm/setup-emsdk@v12 + uses: mymindstorm/setup-emsdk@v14 with: version: ${{env.EM_VERSION}} actions-cache-folder: ${{env.EM_CACHE_FOLDER}} + cache-key: emsdk-${{ matrix.cache-name }}-${{env.GODOT_BASE_BRANCH}}-${{github.ref}}-${{github.sha}} - name: Verify Emscripten setup run: | diff --git a/.gitignore b/.gitignore index 61ea171b8b8..cb9ca14fe8d 100644 --- a/.gitignore +++ b/.gitignore @@ -132,6 +132,10 @@ cppcheck-cppcheck-build-dir/ *.pydevproject *.launch +# Emacs +\#*\# +.\#* + # GCOV code coverage *.gcda *.gcno diff --git a/COPYRIGHT.txt b/COPYRIGHT.txt index 91f227d4050..a23164fe00a 100644 --- a/COPYRIGHT.txt +++ b/COPYRIGHT.txt @@ -296,8 +296,8 @@ License: BSD-3-clause Files: ./thirdparty/libpng/ Comment: libpng -Copyright: 1995-2019, The PNG Reference Library Authors. - 2018-2019, Cosmin Truta. +Copyright: 1995-2024, The PNG Reference Library Authors. + 2018-2024, Cosmin Truta. 2000-2002, 2004, 2006-2018 Glenn Randers-Pehrson. 1996-1997, Andreas Dilger. 1995-1996, Guy Eric Schalnat, Group 42, Inc. @@ -340,7 +340,7 @@ License: CC0-1.0 Files: ./thirdparty/miniupnpc/ Comment: MiniUPnP Project -Copyright: 2005-2023, Thomas Bernard +Copyright: 2005-2024, Thomas Bernard License: BSD-3-clause Files: ./thirdparty/minizip/ diff --git a/SConstruct b/SConstruct index 534d5bd95d2..0afdb07b356 100644 --- a/SConstruct +++ b/SConstruct @@ -152,7 +152,7 @@ env_base["x86_libtheora_opt_gcc"] = False env_base["x86_libtheora_opt_vc"] = False # avoid issues when building with different versions of python out of the same directory -env_base.SConsignFile(".sconsign{0}.dblite".format(pickle.HIGHEST_PROTOCOL)) +env_base.SConsignFile(File("#.sconsign{0}.dblite".format(pickle.HIGHEST_PROTOCOL)).abspath) # Build options diff --git a/core/error/error_macros.h b/core/error/error_macros.h index c8182975d57..8138fd30ac1 100644 --- a/core/error/error_macros.h +++ b/core/error/error_macros.h @@ -730,6 +730,16 @@ void _err_flush_stdout(); } else \ ((void)0) +/** + * Warns about `m_msg` only when verbose mode is enabled. + */ +#define WARN_VERBOSE(m_msg) \ + { \ + if (is_print_verbose_enabled()) { \ + WARN_PRINT(m_msg); \ + } \ + } + // Print deprecated warning message macros. /** diff --git a/core/extension/gdextension.cpp b/core/extension/gdextension.cpp index e2af1970b64..82100f7b50f 100644 --- a/core/extension/gdextension.cpp +++ b/core/extension/gdextension.cpp @@ -794,6 +794,9 @@ void GDExtension::deinitialize_library(InitializationLevel p_level) { ERR_FAIL_COND(p_level > int32_t(level_initialized)); level_initialized = int32_t(p_level) - 1; + + ERR_FAIL_NULL(initialization.deinitialize); + initialization.deinitialize(initialization.userdata, GDExtensionInitializationLevel(p_level)); } diff --git a/core/extension/gdextension_compat_hashes.cpp b/core/extension/gdextension_compat_hashes.cpp index dd4cd20d09b..ebbf795070f 100644 --- a/core/extension/gdextension_compat_hashes.cpp +++ b/core/extension/gdextension_compat_hashes.cpp @@ -65,7 +65,7 @@ bool GDExtensionCompatHashes::get_legacy_hashes(const StringName &p_class, const if (p_check_valid) { MethodBind *mb = ClassDB::get_method_with_compatibility(p_class, p_method, mapping.current_hash); if (!mb) { - WARN_PRINT(vformat("Compatibility hash %d mapped to non-existent hash %d. Please update gdextension_compat_hashes.cpp.", mapping.legacy_hash, mapping.current_hash)); + WARN_PRINT(vformat("Compatibility hash %d for %s::%s() mapped to non-existent hash %d. Please update gdextension_compat_hashes.cpp.", mapping.legacy_hash, p_class, p_method, mapping.current_hash)); continue; } } @@ -107,7 +107,11 @@ void GDExtensionCompatHashes::initialize() { { "add_track", 2393815928, 3843682357 }, { "track_insert_key", 1985425300, 808952278 }, { "track_find_key", 3898229885, 3245197284 }, +#ifdef REAL_T_IS_DOUBLE + { "bezier_track_insert_key", 1057544502, 3767441357 }, +#else { "bezier_track_insert_key", 1057544502, 3656773645 }, +#endif { "bezier_track_set_key_in_handle", 1028302688, 1719223284 }, { "bezier_track_set_key_out_handle", 1028302688, 1719223284 }, { "audio_track_insert_key", 3489962123, 4021027286 }, @@ -125,10 +129,18 @@ void GDExtensionCompatHashes::initialize() { { "add_triangle", 642454959, 753017335 }, }); mappings.insert("AnimationNodeBlendTree", { +#ifdef REAL_T_IS_DOUBLE + { "add_node", 2055804584, 1407702499 }, +#else { "add_node", 2055804584, 1980270704 }, +#endif }); mappings.insert("AnimationNodeStateMachine", { +#ifdef REAL_T_IS_DOUBLE + { "add_node", 2055804584, 1407702499 }, +#else { "add_node", 2055804584, 1980270704 }, +#endif }); mappings.insert("AnimationNodeStateMachinePlayback", { { "travel", 3683006648, 3823612587 }, @@ -177,8 +189,13 @@ void GDExtensionCompatHashes::initialize() { { "draw_multiline_string_outline", 3717870722, 1912318525 }, { "draw_char", 2329089032, 3339793283 }, { "draw_char_outline", 419453826, 3302344391 }, +#ifdef REAL_T_IS_DOUBLE + { "draw_mesh", 1634855856, 4036154158 }, + { "draw_set_transform", 3283884939, 156553079 }, +#else { "draw_mesh", 1634855856, 153818295 }, { "draw_set_transform", 3283884939, 288975085 }, +#endif { "draw_animation_slice", 2295343543, 3112831842 }, }); mappings.insert("CodeEdit", { @@ -210,10 +227,18 @@ void GDExtensionCompatHashes::initialize() { { "add_point", 2766148617, 434072736 }, }); mappings.insert("Curve2D", { +#ifdef REAL_T_IS_DOUBLE + { "add_point", 529706502, 3343370600 }, +#else { "add_point", 2437345566, 4175465202 }, +#endif }); mappings.insert("Curve3D", { +#ifdef REAL_T_IS_DOUBLE + { "add_point", 3544159631, 917388502 }, +#else { "add_point", 3836314258, 2931053748 }, +#endif }); mappings.insert("DirAccess", { { "list_dir_begin", 2018049411, 2610976713 }, @@ -253,8 +278,13 @@ void GDExtensionCompatHashes::initialize() { { "window_set_ime_active", 450484987, 1661950165 }, { "window_set_ime_position", 3614040015, 2019273902 }, { "window_set_vsync_mode", 1708924624, 2179333492 }, - { "virtual_keyboard_show", 860410478, 3042891259 }, +#ifdef REAL_T_IS_DOUBLE + { "cursor_set_custom_image", 1358907026, 4163678968 }, + { "virtual_keyboard_show", 384539973, 1323934605 }, +#else { "cursor_set_custom_image", 1358907026, 1816663697 }, + { "virtual_keyboard_show", 860410478, 3042891259 }, +#endif }); mappings.insert("ENetConnection", { { "create_host_bound", 866250949, 1515002313 }, @@ -289,7 +319,11 @@ void GDExtensionCompatHashes::initialize() { }); mappings.insert("EditorNode3DGizmo", { { "add_lines", 302451090, 2910971437 }, + #ifdef REAL_T_IS_DOUBLE + { "add_mesh", 3332776472, 2161761131 }, + #else { "add_mesh", 1868867708, 1579955111 }, + #endif { "add_unscaled_billboard", 3719733075, 520007164 }, }); mappings.insert("EditorNode3DGizmoPlugin", { @@ -316,7 +350,6 @@ void GDExtensionCompatHashes::initialize() { { "add_filter", 233059325, 3388804757 }, }); mappings.insert("Font", { - { "find_variation", 1222433716, 3344325384 }, { "get_string_size", 3678918099, 1868866121 }, { "get_multiline_string_size", 2427690650, 519636710 }, { "draw_string", 2565402639, 1983721962 }, @@ -325,8 +358,13 @@ void GDExtensionCompatHashes::initialize() { { "draw_multiline_string_outline", 1649790182, 3206388178 }, { "draw_char", 1462476057, 3815617597 }, { "draw_char_outline", 4161008124, 209525354 }, + #ifdef REAL_T_IS_DOUBLE + { "find_variation", 625117670, 2196349508 }, + #else + { "find_variation", 1222433716, 3344325384 }, // Pre-existing compatibility hash. { "find_variation", 1149405976, 1851767612 }, + #endif }); mappings.insert("GLTFDocument", { { "append_from_file", 1862991421, 866380864 }, @@ -380,11 +418,19 @@ void GDExtensionCompatHashes::initialize() { { "get_vector", 1517139831, 2479607902 }, { "start_joy_vibration", 1890603622, 2576575033 }, { "action_press", 573731101, 1713091165 }, +#ifdef REAL_T_IS_DOUBLE + { "set_custom_mouse_cursor", 3489634142, 1277868338 }, +#else { "set_custom_mouse_cursor", 3489634142, 703945977 }, +#endif }); mappings.insert("InputEvent", { { "is_match", 3392494811, 1754951977 }, +#ifdef REAL_T_IS_DOUBLE + { "xformed_by", 2747409789, 3242949850 }, +#else { "xformed_by", 2747409789, 1282766827 }, +#endif }); mappings.insert("InputMap", { { "add_action", 573731101, 4100757082 }, @@ -429,8 +475,13 @@ void GDExtensionCompatHashes::initialize() { { "set_multiplayer_authority", 4023243586, 972357352 }, }); mappings.insert("Node3D", { +#ifdef REAL_T_IS_DOUBLE + { "look_at", 136915519, 819337406 }, + { "look_at_from_position", 4067663783, 1809580162 }, +#else { "look_at", 3123400617, 2882425029 }, { "look_at_from_position", 4067663783, 2086826090 }, +#endif }); mappings.insert("Noise", { { "get_image", 2569233413, 3180683109 }, @@ -470,7 +521,11 @@ void GDExtensionCompatHashes::initialize() { { "add_custom_monitor", 2865980031, 4099036814 }, }); mappings.insert("PhysicalBone3D", { +#ifdef REAL_T_IS_DOUBLE + { "apply_impulse", 1002852006, 2485728502 }, +#else { "apply_impulse", 1002852006, 2754756483 }, +#endif }); mappings.insert("PhysicsBody2D", { { "move_and_collide", 1529961754, 3681923724 }, @@ -481,14 +536,26 @@ void GDExtensionCompatHashes::initialize() { { "test_move", 680299713, 2481691619 }, }); mappings.insert("PhysicsDirectBodyState2D", { +#ifdef REAL_T_IS_DOUBLE + { "apply_impulse", 496058220, 1271588277 }, + { "apply_force", 496058220, 1271588277 }, + { "add_constant_force", 496058220, 1271588277 }, +#else { "apply_impulse", 496058220, 4288681949 }, { "apply_force", 496058220, 4288681949 }, { "add_constant_force", 496058220, 4288681949 }, +#endif }); mappings.insert("PhysicsDirectBodyState3D", { +#ifdef REAL_T_IS_DOUBLE + { "apply_impulse", 1002852006, 2485728502 }, + { "apply_force", 1002852006, 2485728502 }, + { "add_constant_force", 1002852006, 2485728502 }, +#else { "apply_impulse", 1002852006, 2754756483 }, { "apply_force", 1002852006, 2754756483 }, { "add_constant_force", 1002852006, 2754756483 }, +#endif }); mappings.insert("PhysicsDirectSpaceState2D", { { "intersect_point", 3278207904, 2118456068 }, @@ -507,21 +574,37 @@ void GDExtensionCompatHashes::initialize() { { "create", 680321959, 3110599579 }, }); mappings.insert("PhysicsServer2D", { +#ifdef REAL_T_IS_DOUBLE + { "area_add_shape", 754862190, 3597527023 }, + { "body_add_shape", 754862190, 3597527023 }, + { "body_apply_impulse", 34330743, 1124035137 }, + { "body_apply_force", 34330743, 1124035137 }, + { "body_add_constant_force", 34330743, 1124035137 }, +#else { "area_add_shape", 754862190, 339056240 }, { "body_add_shape", 754862190, 339056240 }, { "body_apply_impulse", 34330743, 205485391 }, { "body_apply_force", 34330743, 205485391 }, { "body_add_constant_force", 34330743, 205485391 }, +#endif { "joint_make_pin", 2288600450, 1612646186 }, { "joint_make_groove", 3573265764, 481430435 }, { "joint_make_damped_spring", 206603952, 1994657646 }, }); mappings.insert("PhysicsServer3D", { +#ifdef REAL_T_IS_DOUBLE + { "area_add_shape", 4040559639, 183938777 }, + { "body_add_shape", 4040559639, 183938777 }, + { "body_apply_impulse", 110375048, 2238283471 }, + { "body_apply_force", 110375048, 2238283471 }, + { "body_add_constant_force", 110375048, 2238283471 }, +#else { "area_add_shape", 4040559639, 3711419014 }, { "body_add_shape", 4040559639, 3711419014 }, { "body_apply_impulse", 110375048, 390416203 }, { "body_apply_force", 110375048, 390416203 }, { "body_add_constant_force", 110375048, 390416203 }, +#endif }); mappings.insert("PopupMenu", { { "add_item", 3224536192, 3674230041 }, @@ -581,10 +664,16 @@ void GDExtensionCompatHashes::initialize() { { "buffer_get_data", 125363422, 3101830688 }, { "render_pipeline_create", 2911419500, 2385451958 }, { "compute_pipeline_create", 403593840, 1448838280 }, + { "draw_list_draw", 3710874499, 4230067973 }, +#ifdef REAL_T_IS_DOUBLE + { "draw_list_begin", 4252992020, 848735039 }, + { "draw_list_begin_split", 832527510, 2228306807 }, + { "draw_list_enable_scissor", 338791288, 730833978 }, +#else { "draw_list_begin", 4252992020, 2468082605 }, { "draw_list_begin_split", 832527510, 2406300660 }, - { "draw_list_draw", 3710874499, 4230067973 }, { "draw_list_enable_scissor", 338791288, 244650101 }, +#endif }); mappings.insert("RenderingServer", { { "texture_rd_create", 3291180269, 1434128712 }, @@ -592,12 +681,10 @@ void GDExtensionCompatHashes::initialize() { { "shader_get_default_texture_parameter", 2523186822, 1464608890 }, { "mesh_create_from_surfaces", 4007581507, 4291747531 }, { "mesh_add_surface_from_arrays", 1247008646, 2342446560 }, - { "viewport_attach_to_screen", 1278520651, 1062245816 }, { "environment_set_ambient_light", 491659071, 1214961493 }, { "instances_cull_aabb", 2031554939, 2570105777 }, { "instances_cull_ray", 3388524336, 2208759584 }, { "instances_cull_convex", 3690700105, 2488539944 }, - { "canvas_item_set_custom_rect", 2180266943, 1333997032 }, { "canvas_item_add_line", 2843922985, 1819681853 }, { "canvas_item_add_polyline", 3438017257, 3098767073 }, { "canvas_item_add_multiline", 3176074788, 2088642721 }, @@ -607,11 +694,19 @@ void GDExtensionCompatHashes::initialize() { { "canvas_item_add_nine_patch", 904428547, 389957886 }, { "canvas_item_add_polygon", 2907936855, 3580000528 }, { "canvas_item_add_triangle_array", 749685193, 660261329 }, - { "canvas_item_add_mesh", 3548053052, 316450961 }, { "canvas_item_add_multimesh", 1541595251, 2131855138 }, { "canvas_item_add_animation_slice", 4107531031, 2646834499 }, { "canvas_item_set_canvas_group_mode", 41973386, 3973586316 }, { "set_boot_image", 2244367877, 3759744527 }, +#ifdef REAL_T_IS_DOUBLE + { "viewport_attach_to_screen", 1410474027, 2248302004 }, + { "canvas_item_set_custom_rect", 2180266943, 1134449082 }, + { "canvas_item_add_mesh", 3877492181, 3024949314 }, +#else + { "viewport_attach_to_screen", 1278520651, 1062245816 }, + { "canvas_item_set_custom_rect", 2180266943, 1333997032 }, + { "canvas_item_add_mesh", 3548053052, 316450961 }, +#endif }); mappings.insert("ResourceLoader", { { "load_threaded_request", 1939848623, 3614384323 }, @@ -623,23 +718,40 @@ void GDExtensionCompatHashes::initialize() { { "save", 2303056517, 2983274697 }, }); mappings.insert("RichTextLabel", { - { "add_image", 3346058748, 3580801207 }, { "push_font", 814287596, 2347424842 }, { "push_paragraph", 3218895358, 3089306873 }, { "push_list", 4036303897, 3017143144 }, { "push_table", 1125058220, 2623499273 }, - { "push_dropcap", 311501835, 4061635501 }, { "set_table_column_expand", 4132157579, 2185176273 }, +#ifdef REAL_T_IS_DOUBLE + { "add_image", 3346058748, 1507062345 }, + { "push_dropcap", 981432822, 763534173 }, +#else + { "add_image", 3346058748, 3580801207 }, + { "push_dropcap", 311501835, 4061635501 }, +#endif }); mappings.insert("RigidBody2D", { +#ifdef REAL_T_IS_DOUBLE + { "apply_impulse", 496058220, 1271588277 }, + { "apply_force", 496058220, 1271588277 }, + { "add_constant_force", 496058220, 1271588277 }, +#else { "apply_impulse", 496058220, 4288681949 }, { "apply_force", 496058220, 4288681949 }, { "add_constant_force", 496058220, 4288681949 }, +#endif }); mappings.insert("RigidBody3D", { +#ifdef REAL_T_IS_DOUBLE + { "apply_impulse", 1002852006, 2485728502 }, + { "apply_force", 1002852006, 2485728502 }, + { "add_constant_force", 1002852006, 2485728502 }, +#else { "apply_impulse", 1002852006, 2754756483 }, { "apply_force", 1002852006, 2754756483 }, { "add_constant_force", 1002852006, 2754756483 }, +#endif }); mappings.insert("SceneMultiplayer", { { "send_bytes", 2742700601, 1307428718 }, @@ -699,7 +811,11 @@ void GDExtensionCompatHashes::initialize() { { "draw_outline", 1364491366, 1343401456 }, }); mappings.insert("TextParagraph", { +#ifdef REAL_T_IS_DOUBLE + { "set_dropcap", 2613124475, 2897844600 }, +#else { "set_dropcap", 2613124475, 2498990330 }, +#endif { "add_string", 867188035, 621426851 }, { "add_object", 735420116, 1316529304 }, { "resize_object", 960819067, 2095776372 }, diff --git a/core/input/gamecontrollerdb.txt b/core/input/gamecontrollerdb.txt index 77655e9b6a0..420de7f9b78 100644 --- a/core/input/gamecontrollerdb.txt +++ b/core/input/gamecontrollerdb.txt @@ -314,6 +314,7 @@ 03000000242e00000b20000000000000,Hyperkin Admiral N64 Controller,+rightx:b11,+righty:b13,-rightx:b8,-righty:b12,a:b1,b:b0,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,lefttrigger:b14,leftx:a0,lefty:a1,rightshoulder:b5,start:b9,platform:Windows, 03000000242e0000ff0b000000000000,Hyperkin N64 Adapter,a:b1,b:b2,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightx:a2,righty:a3,start:b9,platform:Windows, 03000000790000004e95000000000000,Hyperkin N64 Controller Adapter,a:b1,b:b2,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b7,lefttrigger:b4,leftx:a0,lefty:a1,rightshoulder:b5,rightx:a5,righty:a2,start:b9,platform:Windows, +03000000242e00006a48000000000000,Hyperkin RetroN Sq,a:b3,b:b7,back:b5,dpdown:+a4,dpleft:-a0,dpright:+a0,dpup:-a4,leftshoulder:b0,rightshoulder:b1,start:b4,x:b2,y:b6,platform:Windows, 03000000242e00006a38000000000000,Hyperkin Trooper 2,a:b0,b:b1,back:b4,leftshoulder:b2,leftx:a0,lefty:a1,rightshoulder:b3,start:b5,platform:Windows, 03000000d81d00000e00000000000000,iBuffalo AC02 Arcade Joystick,a:b0,b:b1,back:b9,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b6,leftstick:b10,lefttrigger:b7,leftx:a0,lefty:a1,rightshoulder:b2,rightstick:b11,righttrigger:b3,rightx:a2,righty:a5,start:b8,x:b4,y:b5,platform:Windows, 03000000d81d00000f00000000000000,iBuffalo BSGP1204 Series,a:b2,b:b1,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b6,leftstick:b10,lefttrigger:b4,leftx:a0,lefty:a1,rightshoulder:b7,rightstick:b11,righttrigger:b5,rightx:a2,righty:a3,start:b9,x:b3,y:b0,platform:Windows, @@ -352,7 +353,7 @@ 030000006d040000d2ca000000000000,Logitech Cordless Precision,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, 030000006d04000011c2000000000000,Logitech Cordless Wingman,a:b0,b:b1,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b9,leftstick:b5,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b10,rightstick:b2,righttrigger:b7,rightx:a3,righty:a4,x:b4,platform:Windows, 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, -030000006d0400001dc2000000000000,Logitech F310,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,rightx:a3,righty:a4,start:b7,x:b2,y:b3,platform:Windows, +030000006d0400001dc2000000000000,Logitech F310,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, 030000006d04000018c2000000000000,Logitech F510,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, 030000006d0400001ec2000000000000,Logitech F510,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,rightx:a3,righty:a4,start:b7,x:b2,y:b3,platform:Windows, 030000006d04000019c2000000000000,Logitech F710,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, @@ -429,6 +430,8 @@ 03000000f70600000100000000000000,N64 Adaptoid,+rightx:b2,+righty:b1,-rightx:b4,-righty:b5,a:b0,b:b3,dpdown:b11,dpleft:b12,dpright:b13,dpup:b10,leftshoulder:b6,lefttrigger:b9,leftx:a0,lefty:a1,rightshoulder:b7,start:b8,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, 030000006b1400001106000000000000,Nacon Revolution 3 PS4 Controller,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a5,start:b9,x:b0,y:b3,platform:Windows, +0300000085320000170d000000000000,Nacon Revolution 5 Pro,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,touchpad:b13,x:b0,y:b3,platform:Windows, +0300000085320000190d000000000000,Nacon Revolution 5 Pro,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,touchpad:b13,x:b0,y:b3,platform:Windows, 030000006b140000100d000000000000,Nacon Revolution Infinity PS4 Controller,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b0,y:b3,platform:Windows, 030000006b140000080d000000000000,Nacon Revolution Unlimited Pro 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:Windows, 03000000bd12000001c0000000000000,Nebular,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:a5,righty:a2,start:b9,x:b3,y:b0,platform:Windows, @@ -450,7 +453,7 @@ 03000000550900001072000000000000,NVIDIA Shield,a:b9,b:b8,back:b11,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b5,leftstick:b3,lefttrigger:a3,leftx:a0,lefty:a1,rightshoulder:b4,rightstick:b2,righttrigger:a4,rightx:a2,righty:a5,start:b0,x:b7,y:b6,platform:Windows, 030000005509000000b4000000000000,NVIDIA Virtual,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, 03000000120c00000288000000000000,Nyko Air Flo Xbox Controller,a:b0,b:b1,back:b7,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b8,lefttrigger:b10,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b9,righttrigger:b11,rightx:a3,righty:a4,start:b6,x:b2,y:b3,platform:Windows, -030000004b120000014d000000000000,Nyko Airflo,a:b0,b:b1,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b10,leftshoulder:a3,leftstick:a0,lefttrigger:b6,rightshoulder:b5,rightstick:a2,righttrigger:b7,start:b9,x:b2,y:b3,platform:Windows, +030000004b120000014d000000000000,NYKO Airflo EX,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:a3,righty:a2,start:b9,x:b2,y:b3,platform:Windows, 03000000d62000001d57000000000000,Nyko Airflo 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, 03000000791d00000900000000000000,Nyko Playpad,a:b0,b:b1,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b6,leftstick:b13,leftx:a0,lefty:a1,rightshoulder:b7,rightstick:b14,rightx:a2,righty:a5,start:b11,x:b3,y:b4,platform:Windows, 03000000782300000a10000000000000,Onlive Controller,a:b15,b:b14,back:b7,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b5,leftshoulder:b11,leftstick:b9,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b10,rightstick:b8,righttrigger:a5,rightx:a3,righty:a4,start:b6,x:b13,y:b12,platform:Windows, @@ -459,7 +462,7 @@ 030000008916000000fd000000000000,Onza TE,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, 03000000d62000006d57000000000000,OPP PS3 Controller,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b0,y:b3,platform:Windows, 030000006b14000001a1000000000000,Orange Controller,a:b0,b:b1,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b10,leftshoulder:b4,leftstick:b6,lefttrigger:a3,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b7,righttrigger:a4,rightx:a5,righty:a2,start:b9,x:b2,y:b3,platform:Windows, -03000000362800000100000000000000,OUYA Controller,a:b0,b:b3,dpdown:b9,dpleft:b10,dpright:b11,dpup:b8,guide:b14,leftshoulder:b4,leftstick:b6,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b7,righttrigger:b13,rightx:a3,righty:a4,x:b1,y:b2,platform:Windows, +03000000362800000100000000000000,OUYA Controller,a:b0,b:b3,dpdown:b9,dpleft:b10,dpright:b11,dpup:b8,guide:b14,leftshoulder:b4,leftstick:b6,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b7,righttrigger:a5,rightx:a3,righty:a4,x:b1,y:b2,platform:Windows, 03000000120c0000f60e000000000000,P4 Gamepad,a:b1,b:b2,back:b12,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b8,leftshoulder:b5,lefttrigger:b7,rightshoulder:b4,righttrigger:b6,start:b9,x:b0,y:b3,platform:Windows, 03000000790000002201000000000000,PC Controller,a:b2,b:b1,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b3,y:b0,platform:Windows, 030000006f0e00008501000000000000,PDP Fightpad Pro GameCube Controller,a:b1,b:b0,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,misc1:b13,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b2,y:b3,platform:Windows, @@ -532,6 +535,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,touchpad:b13,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, +030000004c0500005f0e000000000000,PS5 Access 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:b14,rightshoulder:b5,rightstick:b11,righttrigger:a4,rightx:a2,righty:a5,start:b9,touchpad:b13,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:b14,rightshoulder:b5,rightstick:b11,righttrigger:a4,rightx:a2,righty:a5,start:b9,touchpad:b13,x:b0,y:b3,platform:Windows, 030000004c050000f20d000000000000,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:b14,rightshoulder:b5,rightstick:b11,righttrigger:a4,rightx:a2,righty:a5,start:b9,touchpad:b13,x:b0,y:b3,platform:Windows, 03000000830500005020000000000000,PSX,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:Windows, @@ -556,6 +560,7 @@ 030000009b2800003200000000000000,Raphnet GC and N64 Adapter,a:b0,b:b7,dpdown:b11,dpleft:b12,dpright:b13,dpup:b10,lefttrigger:+a5,leftx:a0,lefty:a1,rightshoulder:b2,righttrigger:+a2,rightx:a3,righty:a4,start:b3,x:b1,y:b8,platform:Windows, 030000009b2800006000000000000000,Raphnet GC and N64 Adapter,a:b0,b:b7,dpdown:b11,dpleft:b12,dpright:b13,dpup:b10,lefttrigger:+a5,leftx:a0,lefty:a1,rightshoulder:b2,righttrigger:+a2,rightx:a3,righty:a4,start:b3,x:b1,y:b8,platform:Windows, 030000009b2800001800000000000000,Raphnet Jaguar Adapter,a:b2,b:b1,back:b4,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b13,lefttrigger:b8,leftx:a0,lefty:a1,rightshoulder:b0,righttrigger:b10,start:b3,x:b11,y:b12,platform:Windows, +030000009b2800006100000000000000,Raphnet N64 Adapter,+rightx:b9,+righty:b7,-rightx:b8,-righty:b6,a:b0,b:b1,dpdown:b11,dpleft:b12,dpright:b13,dpup:b10,leftshoulder:b4,lefttrigger:b2,leftx:a0,lefty:a1,rightshoulder:b5,start:b3,platform:Windows, 030000009b2800006300000000000000,Raphnet N64 Adapter,+rightx:b9,+righty:b7,-rightx:b8,-righty:b6,a:b0,b:b1,dpdown:b11,dpleft:b12,dpright:b13,dpup:b10,leftshoulder:b4,lefttrigger:b2,leftx:a0,lefty:a1,rightshoulder:b5,start:b3,platform:Windows, 030000009b2800000200000000000000,Raphnet NES Adapter,a:b7,b:b6,back:b5,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftx:a0,lefty:a1,start:b4,platform:Windows, 030000009b2800004400000000000000,Raphnet PS1 and PS2 Adapter,a:b1,b:b2,back:b5,dpdown:b13,dpleft:b14,dpright:b15,dpup:b12,leftshoulder:b6,leftstick:b10,lefttrigger:b8,leftx:a0,lefty:a1,rightshoulder:b7,rightstick:b11,righttrigger:b9,rightx:a3,righty:a4,start:b4,x:b0,y:b3,platform:Windows, @@ -608,6 +613,7 @@ 03000000050b00001a1a000000000000,ROG Chakram X,a:b1,b:b0,leftx:a0,lefty:a1,x:b2,y:b3,platform:Windows, 03000000050b00001c1a000000000000,ROG Chakram X,a:b1,b:b0,leftx:a0,lefty:a1,x:b2,y:b3,platform:Windows, 030000004f04000001d0000000000000,Rumble Force,a:b0,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b10,lefttrigger:b5,leftx:a0,lefty:a1,rightshoulder:b6,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b1,y:b3,platform:Windows, +030000000d0f0000ad00000000000000,RX Gamepad,a:b0,b:b4,back:b11,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b3,rightshoulder:b6,start:b9,x:b2,y:b1,platform:Windows, 030000008916000000fe000000000000,Sabertooth,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, 03000000c6240000045d000000000000,Sabertooth,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, 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, @@ -674,6 +680,7 @@ 03000000457500002211000000000000,Szmy Power PC Gamepad,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b0,y:b3,platform:Windows, 030000004f0400000ab1000000000000,T16000M,a:b0,b:b1,back:b12,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b11,leftshoulder:b4,lefttrigger:b9,leftx:a0,lefty:a1,rightshoulder:b6,righttrigger:b7,start:b10,x:b2,y:b3,platform:Windows, 030000000d0f00007b00000000000000,TAC GEAR,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a5,start:b9,x:b0,y:b3,platform:Windows, +03000000e40a00000307000000000000,Taito Egret II Mini Control Panel,a:b4,b:b2,back:b6,guide:b9,leftx:a0,lefty:a1,rightshoulder:b0,righttrigger:b1,start:b7,x:b8,y:b3,platform:Windows, 03000000e40a00000207000000000000,Taito Egret II Mini Controller,a:b4,b:b2,back:b6,dpdown:+a1,dpleft:-a0,dpright:+a0,dpup:-a1,guide:b9,rightshoulder:b0,righttrigger:b1,start:b7,x:b8,y:b3,platform:Windows, 03000000d814000001a0000000000000,TE Kitty,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, 03000000fa1900000706000000000000,Team 5,a:b2,b:b1,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b3,y:b0,platform:Windows, @@ -961,6 +968,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, +0300004b4c0500005f0e000000010000,PS5 Access 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:b14,rightshoulder:b5,rightstick:b11,righttrigger:a4,rightx:a2,righty:a5,start:b9,touchpad:b13,x:b0,y:b3,platform:Mac OS X, 030000004c050000e60c000000010000,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:b14,rightshoulder:b5,rightstick:b11,righttrigger:a4,rightx:a2,righty:a5,start:b9,touchpad:b13,x:b0,y:b3,platform:Mac OS X, 030000004c050000f20d000000010000,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:b14,rightshoulder:b5,rightstick:b11,righttrigger:a4,rightx:a2,righty:a5,start:b9,touchpad:b13,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,rightshoulder:b5,rightstick:b11,righttrigger:a4,rightx:a2,righty:a5,start:b9,touchpad:b13,x:b0,y:b3,platform:Mac OS X, @@ -1013,6 +1021,8 @@ xinput,XInput Controller,a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2, 03000000110100001714000020010000,SteelSeries Stratus XL,a:b0,b:b1,dpdown:b9,dpleft:b11,dpright:b10,dpup:b8,leftshoulder:b4,lefttrigger:b6,leftx:a0,lefty:a1~,rightshoulder:b5,righttrigger:b7,rightx:a2,righty:a3~,start:b12,x:b2,y:b3,platform:Mac OS X, 030000000d0f0000f600000000010000,Switch Hori Pad,a:b0,b:b1,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b2,y:b3,platform:Mac OS X, 03000000457500002211000000010000,SZMY Power PC Gamepad,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b0,y:b3,platform:Mac OS X, +03000000e40a00000307000001000000,Taito Egret II Mini Control Panel,a:b4,b:b2,back:b6,guide:b9,leftx:a0,lefty:a1,rightshoulder:b0,righttrigger:b1,start:b7,x:b8,y:b3,platform:Mac OS X, +03000000e40a00000207000001000000,Taito Egret II Mini Controller,a:b4,b:b2,back:b6,guide:b9,leftx:a0,lefty:a1,rightshoulder:b0,righttrigger:b1,start:b7,x:b8,y:b3,platform:Mac OS X, 03000000790000001c18000003100000,TGZ Controller,a:b0,b:b1,back:b10,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b6,leftstick:b13,lefttrigger:a5,leftx:a0,lefty:a1,rightshoulder:b7,rightstick:b14,righttrigger:a4,rightx:a2,righty:a3,start:b11,x:b3,y:b4,platform:Mac OS X, 03000000591c00002400000021000000,THEC64 Joystick,a:b0,b:b1,back:b6,leftshoulder:b4,leftx:a0,lefty:a4,rightshoulder:b5,start:b7,x:b2,y:b3,platform:Mac OS X, 03000000591c00002600000021000000,THEGamepad,a:b2,b:b1,back:b6,dpdown:+a4,dpleft:-a0,dpright:+a0,dpup:-a4,leftshoulder:b4,rightshoulder:b5,start:b7,x:b3,y:b0,platform:Mac OS X, @@ -1164,14 +1174,15 @@ xinput,XInput Controller,a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2, 03000000c21100000791000011010000,Be1 GC101 Controller 1.03,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 Controller 1.03,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,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, -03000000bc2000004d50000011010000,BEITONG A1T2 BFM,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:a2,righty:a3,start:b11,x:b3,y:b4,platform:Linux, -05000000bc2000000055000001000000,BETOP AX1 BFM,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:a2,righty:a3,start:b11,x:b3,y:b4,platform:Linux, +03000000bc2000004d50000011010000,Beitong A1T2 BFM,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:a2,righty:a3,start:b11,x:b3,y:b4,platform:Linux, +05000000bc2000000055000001000000,Betop AX1 BFM,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:a2,righty:a3,start:b11,x:b3,y:b4,platform:Linux, 03000000bc2000006412000011010000,Betop Controller,a:b2,b:b1,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b30,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, 030000006b1400000209000011010000,Bigben,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, 03000000120c0000200e000011010000,Brook Mars 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, 03000000120c0000210e000011010000,Brook Mars 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:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b0,y:b3,platform:Linux, 03000000120c0000f70e000011010000,Brook Universal Fighting Board,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:b6,rightshoulder:b5,rightstick:b11,righttrigger:b7,start:b9,x:b0,y:b3,platform: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, +03000000af1e00002400000010010000,Clockwork Pi DevTerm,a:b2,b:b1,back:b8,dpdown:+a1,dpleft:-a0,dpright:+a0,dpup:-a1,start:b9,x:b3,y:b0,platform:Linux, 030000000b0400003365000000010000,Competition Pro,a:b0,b:b1,back:b2,leftx:a0,lefty:a1,start:b3,platform:Linux, 03000000260900008888000000010000,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:Linux, 03000000a306000022f6000011010000,Cyborg V3 Rumble,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:+a3,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:-a3,rightx:a2,righty:a4,start:b9,x:b0,y:b3,platform:Linux, @@ -1218,7 +1229,6 @@ xinput,XInput Controller,a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2, 06000000adde0000efbe000002010000,Hidromancer 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, 03000000d81400000862000011010000,HitBox PS3 PC Analog Mode,a:b1,b:b2,back:b8,dpdown:+a1,dpleft:-a0,dpright:+a0,dpup:-a1,guide:b9,leftshoulder:b4,lefttrigger:b6,rightshoulder:b5,righttrigger:b7,start:b12,x:b0,y:b3,platform:Linux, 03000000c9110000f055000011010000,HJC Gamepad,a:b0,b:b1,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b2,y:b3,platform:Linux, -03000000632500002605000010010000,HJDX,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:a4,leftx:a0,lefty:a1,rightshoulder:b7,rightstick:b14,righttrigger:a5,rightx:a2,righty:a3,start:b11,x:b3,y:b4,platform:Linux, 030000000d0f00000d00000000010000,Hori,a:b0,b:b6,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b10,leftshoulder:b3,rightshoulder:b7,start:b9,x:b1,y:b2,platform:Linux, 030000000d0f00006d00000020010000,Hori EDGE 301,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, 030000000d0f00008400000011010000,Hori Fighting Commander,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:a3,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:a4,rightx:a2,righty:a5,start:b9,x:b0,y:b3,platform:Linux, @@ -1256,6 +1266,7 @@ xinput,XInput Controller,a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2, 03000000242e00008816000001010000,Hyperkin X91,a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b8,leftshoulder:b4,leftstick:b9,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b10,righttrigger:a5,rightx:a3,righty:a4,start:b7,x:b2,y:b3,platform:Linux, 03000000f00300008d03000011010000,HyperX Clutch,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, 03000000830500006020000010010000,iBuffalo Super Famicom Controller,a:b1,b:b0,back:b6,dpdown:+a1,dpleft:-a0,dpright:+a0,dpup:-a1,leftshoulder:b4,rightshoulder:b5,start:b7,x:b3,y:b2,platform:Linux, +030000008f0e00001330000001010000,iCode Retro Adapter,b:b3,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b8,leftshoulder:b9,lefttrigger:b10,leftx:a0,lefty:a1,rightshoulder:b5,righttrigger:b1,start:b7,x:b2,y:b0,platform:Linux, 050000006964726f69643a636f6e0000,idroidcon 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, 03000000b50700001503000010010000,Impact,a:b2,b:b3,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b10,lefttrigger:b5,leftx:a0,lefty:a1,rightshoulder:b6,rightstick:b11,righttrigger:b7,rightx:a3,righty:a2,start:b9,x:b0,y:b1,platform:Linux, 03000000d80400008200000003000000,IMS PCU0,a:b1,b:b0,back:b4,dpdown:+a1,dpleft:-a0,dpright:+a0,dpup:-a1,start:b5,x:b3,y:b2,platform:Linux, @@ -1389,6 +1400,7 @@ xinput,XInput Controller,a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2, 03000000550900001072000011010000,NVIDIA Controller,a:b0,b:b1,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b13,leftshoulder:b4,leftstick:b8,lefttrigger:a5,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b9,righttrigger:a4,rightx:a2,righty:a3,start:b7,x:b2,y:b3,platform:Linux, 03000000550900001472000011010000,NVIDIA Controller v01.04,a:b0,b:b1,back:b14,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b16,leftshoulder:b4,leftstick:b7,lefttrigger:a3,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b8,righttrigger:a4,rightx:a2,righty:a5,start:b6,x:b2,y:b3,platform:Linux, 05000000550900001472000001000000,NVIDIA Controller v01.04,a:b0,b:b1,back:b14,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b16,leftshoulder:b4,leftstick:b7,lefttrigger:a3,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b8,righttrigger:a4,rightx:a2,righty:a5,start:b6,x:b2,y:b3,platform:Linux, +030000004b120000014d000000010000,NYKO Airflo EX,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:a3,righty:a2,start:b9,x:b2,y:b3,platform:Linux, 03000000451300000830000010010000,NYKO CORE,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a5,start:b9,x:b0,y:b3,platform:Linux, 19000000010000000100000001010000,ODROID Go 2,a:b1,b:b0,dpdown:b7,dpleft:b8,dpright:b9,dpup:b6,guide:b10,leftshoulder:b4,leftstick:b12,lefttrigger:b11,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b13,righttrigger:b14,start:b15,x:b2,y:b3,platform:Linux, 19000000010000000200000011000000,ODROID Go 2,a:b1,b:b0,dpdown:b9,dpleft:b10,dpright:b11,dpup:b8,guide:b12,leftshoulder:b4,leftstick:b14,lefttrigger:b13,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b15,righttrigger:b16,start:b17,x:b2,y:b3,platform:Linux, @@ -1407,6 +1419,7 @@ xinput,XInput Controller,a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2, 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, 030000006f0e00002801000011010000,PDP PS3 Rock Candy 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, 030000006f0e00000901000011010000,PDP PS3 Versus Fighting,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, +030000006f0e00002f01000011010000,PDP Wired 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, 03000000ad1b000004f9000000010000,PDP Xbox 360 Versus Fighting,a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b8,leftshoulder:b4,lefttrigger:a2,rightshoulder:b5,righttrigger:a5,start:b7,x:b2,y:b3,platform:Linux, 030000006f0e0000a802000023020000,PDP Xbox One 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:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b12,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b2,y:b3,platform:Linux, 030000006f0e0000a702000023020000,PDP Xbox One Raven Black,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, @@ -1463,6 +1476,7 @@ 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, +0300004b4c0500005f0e000011010000,PS5 Access 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:b14,rightshoulder:b5,rightstick:b11,righttrigger:a4,rightx:a2,righty:a5,start:b9,touchpad:b13,x:b0,y:b3,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:b14,rightshoulder:b5,rightstick:b11,righttrigger:a4,rightx:a2,righty:a5,start:b9,touchpad:b13,x:b0,y:b3,platform:Linux, 030000004c050000e60c000011810000,PS5 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, 030000004c050000f20d000011010000,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:b14,rightshoulder:b5,rightstick:b11,righttrigger:a4,rightx:a2,righty:a5,start:b9,touchpad:b13,x:b0,y:b3,platform:Linux, @@ -1528,9 +1542,10 @@ xinput,XInput Controller,a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2, 03000000b40400000a01000000010000,Sega Saturn,a:b0,b:b1,dpdown:+a1,dpleft:-a0,dpright:+a0,dpup:-a1,leftshoulder:b6,lefttrigger:b7,rightshoulder:b5,righttrigger:b2,start:b8,x:b3,y:b4,platform:Linux, 030000001f08000001e4000010010000,SFC Controller,a:b2,b:b1,back:b8,dpdown:+a1,dpleft:-a0,dpright:+a0,dpup:-a1,leftshoulder:b4,rightshoulder:b5,start:b9,x:b3,y:b0,platform:Linux, 03000000632500002305000010010000,ShanWan Gamepad,a:b2,b:b1,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b3,y:b0,platform:Linux, +03000000632500002605000010010000,Shanwan Gamepad,a:b0,b:b1,back:b10,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b6,leftstick:b13,lefttrigger:a5,leftx:a0,lefty:a1,rightshoulder:b7,rightstick:b14,righttrigger:a4,rightx:a2,righty:a3,start:b11,x:b3,y:b4,platform:Linux, +03000000632500007505000010010000,Shanwan Gamepad,a:b2,b:b1,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b3,y:b0,platform:Linux, +03000000bc2000000055000010010000,Shanwan Gamepad,a:b0,b:b1,back:b10,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b6,leftstick:b13,lefttrigger:a5,leftx:a0,lefty:a1,rightshoulder:b7,rightstick:b14,righttrigger:a4,rightx:a2,righty:a3,start:b11,x:b3,y:b4,platform:Linux, 03000000f025000021c1000010010000,Shanwan Gioteck PS3 Controller,a:b2,b:b1,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b3,y:b0,platform:Linux, -03000000632500007505000010010000,Shanwan PS3 PC,a:b2,b:b1,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b3,y:b0,platform:Linux, -03000000bc2000000055000010010000,Shanwan PS3 PC ,a:b0,b:b1,back:b10,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b6,leftstick:b13,lefttrigger:a5,leftx:a0,lefty:a1,rightshoulder:b7,rightstick:b14,righttrigger:a4,rightx:a2,righty:a3,start:b11,x:b3,y:b4,platform:Linux, 03000000341a00000908000010010000,SL6566,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, 050000004c050000cc09000001000000,Sony DualShock 4,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:a3,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:a4,rightx:a2,righty:a5,start:b9,x:b0,y:b3,platform:Linux, 03000000ff000000cb01000010010000,Sony PlayStation Portable,a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftx:a0,lefty:a1,rightshoulder:b5,start:b7,x:b2,y:b3,platform:Linux, @@ -1564,6 +1579,8 @@ xinput,XInput Controller,a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2, 03000000457500000401000011010000,SZMY Power DS4 Wired Controller,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger: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, 03000000457500002211000010010000,SZMY Power 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, 030000008f0e00001431000010010000,SZMY Power 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, +03000000e40a00000307000011010000,Taito Egret II Mini Control Panel,a:b4,b:b2,back:b6,guide:b9,leftx:a0,lefty:a1,rightshoulder:b0,righttrigger:b1,start:b7,x:b8,y:b3,platform:Linux, +03000000e40a00000207000011010000,Taito Egret II Mini Controller,a:b4,b:b2,back:b6,guide:b9,leftx:a0,lefty:a1,rightshoulder:b0,righttrigger:b1,start:b7,x:b8,y:b3,platform:Linux, 03000000ba2200000701000001010000,Technology Innovation PS2 Adapter,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:a5,righty:a2,start:b9,x:b3,y:b2,platform:Linux, 03000000790000001c18000011010000,TGZ Controller,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, 03000000591c00002400000010010000,THEC64 Joystick,a:b0,b:b1,back:b6,leftshoulder:b4,leftx:a0,lefty:a1,rightshoulder:b5,start:b7,x:b2,y:b3,platform:Linux, @@ -1871,9 +1888,9 @@ xinput,XInput Controller,a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2, 36313938306539326233393732613361,Retro Bit SNES Controller,a:b0,b:b1,back:b15,dpdown:+a1,dpleft:-a0,dpright:+a0,dpup:-a1,leftshoulder:b9,rightshoulder:b10,start:b6,x:b2,y:b3,platform:Android, 526574726f466c616720576972656420,Retro Controller,a:b0,b:b1,back:b9,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b17,rightshoulder:b18,start:b10,x:b2,y:b3,platform:Android, 61343739353764363165343237303336,Retro Controller,a:b0,b:b1,back:b9,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b17,lefttrigger:b18,leftx:a0,lefty:a1,start:b10,x:b2,y:b3,platform:Android, +526574726f696420506f636b65742043,Retroid Pocket,a:b1,b:b0,back:b4,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b9,leftstick:b7,lefttrigger:a5,leftx:a0,lefty:a1,paddle1:b17,paddle2:b18,rightshoulder:b10,rightstick:b8,righttrigger:a4,rightx:a2,righty:a3,start:b6,x:b3,y:b2,platform:Android, +582d426f7820436f6e74726f6c6c6572,Retroid Pocket,a:b0,b:b1,back:b4,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b9,leftstick:b7,lefttrigger:a5,leftx:a0,lefty:a1,paddle1:b17,paddle2:b18,rightshoulder:b10,rightstick:b8,righttrigger:a4,rightx:a2,righty:a3,start:b6,x:b2,y:b3,platform:Android, 38653130373365613538333235303036,Retroid Pocket 2,a:b0,b:b1,back:b15,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b9,lefttrigger:b17,leftx:a0,lefty:a1,rightshoulder:b10,righttrigger:b18,rightx:a2,righty:a3,start:b6,x:b2,y:b3,platform:Android, -526574726f696420506f636b65742043,Retroid Pocket Flip,a:b1,b:b0,back:b4,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b9,leftstick:b7,lefttrigger:a5,leftx:a0,lefty:a1,paddle1:b17,paddle2:b18,rightshoulder:b10,rightstick:b8,righttrigger:a4,rightx:a2,righty:a3,start:b6,x:b3,y:b2,platform:Android, -582d426f7820436f6e74726f6c6c6572,Retroid Pocket Flip,a:b0,b:b1,back:b4,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b9,leftstick:b7,lefttrigger:a5,leftx:a0,lefty:a1,paddle1:b17,paddle2:b18,rightshoulder:b10,rightstick:b8,righttrigger:a4,rightx:a2,righty:a3,start:b6,x:b2,y:b3,platform:Android, 64363363336633363736393038313463,Retrolink,a:b1,b:b0,back:b15,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,start:b6,platform:Android, 37393234373533633333323633646531,RetroUSB N64 RetroPort,+rightx:b17,+righty:b15,-rightx:b18,-righty:b6,a:b10,b:b9,dpdown:b19,dpleft:b1,dpright:b0,dpup:b2,leftshoulder:b7,lefttrigger:b20,leftx:a0,lefty:a1,rightshoulder:b5,start:b3,platform:Android, 5365616c6965436f6d707574696e6720,RetroUSB N64 RetroPort,+rightx:b17,+righty:b15,-rightx:b18,-righty:b6,a:b10,b:b9,dpdown:b19,dpleft:b1,dpright:b0,dpup:b2,leftshoulder:b7,lefttrigger:b20,leftx:a0,lefty:a1,rightshoulder:b5,start:b3,platform:Android, @@ -1902,6 +1919,7 @@ xinput,XInput Controller,a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2, 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, 0500000011010000201400000f7e0f00,SteelSeries Nimbus,a:b0,b:b1,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b3,lefttrigger:b9,leftx:a0,lefty:a1,rightshoulder:b20,righttrigger:b10,rightx:a2,righty:a3,x:b19,y:b2,platform:Android, 35306436396437373135383665646464,SteelSeries Nimbus Plus,a:b0,b:b1,leftshoulder:b3,leftstick:b17,lefttrigger:b9,leftx:a0,rightshoulder:b20,rightstick:b18,righttrigger:b10,rightx:a2,x:b19,y:b2,platform:Android, +33313930373536613937326534303931,Taito Egret II Mini Control Panel,a:b25,b:b23,back:b27,guide:b30,leftx:a0,lefty:a1,rightshoulder:b21,righttrigger:b22,start:b28,x:b29,y:b24,platform:Android, 54475a20436f6e74726f6c6c65720000,TGZ Controller,a:b0,b:b1,back:b15,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b9,leftstick:b7,lefttrigger:b17,leftx:a0,lefty:a1,rightshoulder:b10,rightstick:b8,righttrigger:b18,rightx:a2,righty:a3,start:b6,x:b2,y:b3,platform:Android, 62363434353532386238336663643836,TGZ Controller,a:b0,b:b1,back:b15,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b9,leftstick:b7,lefttrigger:b17,leftx:a0,lefty:a1,rightshoulder:b10,rightstick:b8,righttrigger:b18,rightx:a2,righty:a3,start:b6,x:b2,y:b3,platform:Android, 37323236633763666465316365313236,THEC64 Joystick,a:b21,b:b22,back:b27,leftshoulder:b25,leftx:a0,lefty:a1,rightshoulder:b26,start:b27,x:b23,y:b24,platform:Android, diff --git a/core/io/file_access.cpp b/core/io/file_access.cpp index 6026dbf8962..55286277fa4 100644 --- a/core/io/file_access.cpp +++ b/core/io/file_access.cpp @@ -38,7 +38,7 @@ #include "core/io/marshalls.h" #include "core/os/os.h" -FileAccess::CreateFunc FileAccess::create_func[ACCESS_MAX] = { nullptr, nullptr }; +FileAccess::CreateFunc FileAccess::create_func[ACCESS_MAX] = {}; FileAccess::FileCloseFailNotify FileAccess::close_fail_notify = nullptr; diff --git a/core/io/file_access_memory.cpp b/core/io/file_access_memory.cpp index 0983920b94a..da02c883e89 100644 --- a/core/io/file_access_memory.cpp +++ b/core/io/file_access_memory.cpp @@ -119,7 +119,7 @@ uint64_t FileAccessMemory::get_length() const { } bool FileAccessMemory::eof_reached() const { - return pos > length; + return pos >= length; } uint8_t FileAccessMemory::get_8() const { diff --git a/core/io/resource_loader.cpp b/core/io/resource_loader.cpp index 1fbb6ff2ed2..6b91cb0c8fa 100644 --- a/core/io/resource_loader.cpp +++ b/core/io/resource_loader.cpp @@ -244,11 +244,11 @@ Ref ResourceLoader::_load(const String &p_path, const String &p_origin thread_load_mutex.lock(); HashMap::Iterator E = thread_load_tasks.find(load_paths_stack->get(load_paths_stack->size() - 1)); if (E) { - E->value.sub_tasks.insert(p_path); + E->value.sub_tasks.insert(p_original_path); } thread_load_mutex.unlock(); } - load_paths_stack->push_back(p_path); + load_paths_stack->push_back(p_original_path); // Try all loaders and pick the first match for the type hint bool found = false; @@ -509,20 +509,20 @@ Ref ResourceLoader::_load_start(const String &p_path, float ResourceLoader::_dependency_get_progress(const String &p_path) { if (thread_load_tasks.has(p_path)) { ThreadLoadTask &load_task = thread_load_tasks[p_path]; + float current_progress = 0.0; int dep_count = load_task.sub_tasks.size(); if (dep_count > 0) { - float dep_progress = 0; for (const String &E : load_task.sub_tasks) { - dep_progress += _dependency_get_progress(E); + current_progress += _dependency_get_progress(E); } - dep_progress /= float(dep_count); - dep_progress *= 0.5; - dep_progress += load_task.progress * 0.5; - return dep_progress; + current_progress /= float(dep_count); + current_progress *= 0.5; + current_progress += load_task.progress * 0.5; } else { - return load_task.progress; + current_progress = load_task.progress; } - + load_task.max_reported_progress = MAX(load_task.max_reported_progress, current_progress); + return load_task.max_reported_progress; } else { return 1.0; //assume finished loading it so it no longer exists } diff --git a/core/io/resource_loader.h b/core/io/resource_loader.h index 3c32a19066b..0ab81cd0a8f 100644 --- a/core/io/resource_loader.h +++ b/core/io/resource_loader.h @@ -167,7 +167,8 @@ private: String remapped_path; String dependent_path; String type_hint; - float progress = 0.0; + float progress = 0.0f; + float max_reported_progress = 0.0f; ThreadLoadStatus status = THREAD_LOAD_IN_PROGRESS; ResourceFormatLoader::CacheMode cache_mode = ResourceFormatLoader::CACHE_MODE_REUSE; Error error = OK; diff --git a/core/io/stream_peer_gzip.cpp b/core/io/stream_peer_gzip.cpp index 4daa71a22ac..514bcf59b8e 100644 --- a/core/io/stream_peer_gzip.cpp +++ b/core/io/stream_peer_gzip.cpp @@ -76,6 +76,7 @@ Error StreamPeerGZIP::start_decompression(bool p_is_deflate, int buffer_size) { Error StreamPeerGZIP::_start(bool p_compress, bool p_is_deflate, int buffer_size) { ERR_FAIL_COND_V(ctx != nullptr, ERR_ALREADY_IN_USE); + ERR_FAIL_COND_V_MSG(buffer_size <= 0, ERR_INVALID_PARAMETER, "Invalid buffer size. It should be a positive integer."); clear(); compressing = p_compress; rb.resize(nearest_shift(buffer_size - 1)); diff --git a/core/math/a_star.cpp b/core/math/a_star.cpp index f0f160940d9..fb54058bd9e 100644 --- a/core/math/a_star.cpp +++ b/core/math/a_star.cpp @@ -69,7 +69,7 @@ void AStar3D::add_point(int64_t p_id, const Vector3 &p_pos, real_t p_weight_scal } Vector3 AStar3D::get_point_position(int64_t p_id) const { - Point *p; + Point *p = nullptr; bool p_exists = points.lookup(p_id, p); ERR_FAIL_COND_V_MSG(!p_exists, Vector3(), vformat("Can't get point's position. Point with id: %d doesn't exist.", p_id)); @@ -77,7 +77,7 @@ Vector3 AStar3D::get_point_position(int64_t p_id) const { } void AStar3D::set_point_position(int64_t p_id, const Vector3 &p_pos) { - Point *p; + Point *p = nullptr; bool p_exists = points.lookup(p_id, p); ERR_FAIL_COND_MSG(!p_exists, vformat("Can't set point's position. Point with id: %d doesn't exist.", p_id)); @@ -85,7 +85,7 @@ void AStar3D::set_point_position(int64_t p_id, const Vector3 &p_pos) { } real_t AStar3D::get_point_weight_scale(int64_t p_id) const { - Point *p; + Point *p = nullptr; bool p_exists = points.lookup(p_id, p); ERR_FAIL_COND_V_MSG(!p_exists, 0, vformat("Can't get point's weight scale. Point with id: %d doesn't exist.", p_id)); @@ -93,7 +93,7 @@ real_t AStar3D::get_point_weight_scale(int64_t p_id) const { } void AStar3D::set_point_weight_scale(int64_t p_id, real_t p_weight_scale) { - Point *p; + Point *p = nullptr; bool p_exists = points.lookup(p_id, p); ERR_FAIL_COND_MSG(!p_exists, vformat("Can't set point's weight scale. Point with id: %d doesn't exist.", p_id)); ERR_FAIL_COND_MSG(p_weight_scale < 0.0, vformat("Can't set point's weight scale less than 0.0: %f.", p_weight_scale)); @@ -102,7 +102,7 @@ void AStar3D::set_point_weight_scale(int64_t p_id, real_t p_weight_scale) { } void AStar3D::remove_point(int64_t p_id) { - Point *p; + Point *p = nullptr; bool p_exists = points.lookup(p_id, p); ERR_FAIL_COND_MSG(!p_exists, vformat("Can't remove point. Point with id: %d doesn't exist.", p_id)); @@ -130,11 +130,11 @@ void AStar3D::remove_point(int64_t p_id) { void AStar3D::connect_points(int64_t p_id, int64_t p_with_id, bool bidirectional) { ERR_FAIL_COND_MSG(p_id == p_with_id, vformat("Can't connect point with id: %d to itself.", p_id)); - Point *a; + Point *a = nullptr; bool from_exists = points.lookup(p_id, a); ERR_FAIL_COND_MSG(!from_exists, vformat("Can't connect points. Point with id: %d doesn't exist.", p_id)); - Point *b; + Point *b = nullptr; bool to_exists = points.lookup(p_with_id, b); ERR_FAIL_COND_MSG(!to_exists, vformat("Can't connect points. Point with id: %d doesn't exist.", p_with_id)); @@ -166,11 +166,11 @@ void AStar3D::connect_points(int64_t p_id, int64_t p_with_id, bool bidirectional } void AStar3D::disconnect_points(int64_t p_id, int64_t p_with_id, bool bidirectional) { - Point *a; + Point *a = nullptr; bool a_exists = points.lookup(p_id, a); ERR_FAIL_COND_MSG(!a_exists, vformat("Can't disconnect points. Point with id: %d doesn't exist.", p_id)); - Point *b; + Point *b = nullptr; bool b_exists = points.lookup(p_with_id, b); ERR_FAIL_COND_MSG(!b_exists, vformat("Can't disconnect points. Point with id: %d doesn't exist.", p_with_id)); @@ -220,7 +220,7 @@ PackedInt64Array AStar3D::get_point_ids() { } Vector AStar3D::get_point_connections(int64_t p_id) { - Point *p; + Point *p = nullptr; bool p_exists = points.lookup(p_id, p); ERR_FAIL_COND_V_MSG(!p_exists, Vector(), vformat("Can't get point's connections. Point with id: %d doesn't exist.", p_id)); @@ -386,11 +386,11 @@ real_t AStar3D::_estimate_cost(int64_t p_from_id, int64_t p_to_id) { return scost; } - Point *from_point; + Point *from_point = nullptr; bool from_exists = points.lookup(p_from_id, from_point); ERR_FAIL_COND_V_MSG(!from_exists, 0, vformat("Can't estimate cost. Point with id: %d doesn't exist.", p_from_id)); - Point *to_point; + Point *to_point = nullptr; bool to_exists = points.lookup(p_to_id, to_point); ERR_FAIL_COND_V_MSG(!to_exists, 0, vformat("Can't estimate cost. Point with id: %d doesn't exist.", p_to_id)); @@ -403,11 +403,11 @@ real_t AStar3D::_compute_cost(int64_t p_from_id, int64_t p_to_id) { return scost; } - Point *from_point; + Point *from_point = nullptr; bool from_exists = points.lookup(p_from_id, from_point); ERR_FAIL_COND_V_MSG(!from_exists, 0, vformat("Can't compute cost. Point with id: %d doesn't exist.", p_from_id)); - Point *to_point; + Point *to_point = nullptr; bool to_exists = points.lookup(p_to_id, to_point); ERR_FAIL_COND_V_MSG(!to_exists, 0, vformat("Can't compute cost. Point with id: %d doesn't exist.", p_to_id)); @@ -415,11 +415,11 @@ real_t AStar3D::_compute_cost(int64_t p_from_id, int64_t p_to_id) { } Vector AStar3D::get_point_path(int64_t p_from_id, int64_t p_to_id) { - Point *a; + Point *a = nullptr; bool from_exists = points.lookup(p_from_id, a); ERR_FAIL_COND_V_MSG(!from_exists, Vector(), vformat("Can't get point path. Point with id: %d doesn't exist.", p_from_id)); - Point *b; + Point *b = nullptr; bool to_exists = points.lookup(p_to_id, b); ERR_FAIL_COND_V_MSG(!to_exists, Vector(), vformat("Can't get point path. Point with id: %d doesn't exist.", p_to_id)); @@ -464,11 +464,11 @@ Vector AStar3D::get_point_path(int64_t p_from_id, int64_t p_to_id) { } Vector AStar3D::get_id_path(int64_t p_from_id, int64_t p_to_id) { - Point *a; + Point *a = nullptr; bool from_exists = points.lookup(p_from_id, a); ERR_FAIL_COND_V_MSG(!from_exists, Vector(), vformat("Can't get id path. Point with id: %d doesn't exist.", p_from_id)); - Point *b; + Point *b = nullptr; bool to_exists = points.lookup(p_to_id, b); ERR_FAIL_COND_V_MSG(!to_exists, Vector(), vformat("Can't get id path. Point with id: %d doesn't exist.", p_to_id)); @@ -513,7 +513,7 @@ Vector AStar3D::get_id_path(int64_t p_from_id, int64_t p_to_id) { } void AStar3D::set_point_disabled(int64_t p_id, bool p_disabled) { - Point *p; + Point *p = nullptr; bool p_exists = points.lookup(p_id, p); ERR_FAIL_COND_MSG(!p_exists, vformat("Can't set if point is disabled. Point with id: %d doesn't exist.", p_id)); @@ -521,7 +521,7 @@ void AStar3D::set_point_disabled(int64_t p_id, bool p_disabled) { } bool AStar3D::is_point_disabled(int64_t p_id) const { - Point *p; + Point *p = nullptr; bool p_exists = points.lookup(p_id, p); ERR_FAIL_COND_V_MSG(!p_exists, false, vformat("Can't get if point is disabled. Point with id: %d doesn't exist.", p_id)); @@ -660,11 +660,11 @@ real_t AStar2D::_estimate_cost(int64_t p_from_id, int64_t p_to_id) { return scost; } - AStar3D::Point *from_point; + AStar3D::Point *from_point = nullptr; bool from_exists = astar.points.lookup(p_from_id, from_point); ERR_FAIL_COND_V_MSG(!from_exists, 0, vformat("Can't estimate cost. Point with id: %d doesn't exist.", p_from_id)); - AStar3D::Point *to_point; + AStar3D::Point *to_point = nullptr; bool to_exists = astar.points.lookup(p_to_id, to_point); ERR_FAIL_COND_V_MSG(!to_exists, 0, vformat("Can't estimate cost. Point with id: %d doesn't exist.", p_to_id)); @@ -677,11 +677,11 @@ real_t AStar2D::_compute_cost(int64_t p_from_id, int64_t p_to_id) { return scost; } - AStar3D::Point *from_point; + AStar3D::Point *from_point = nullptr; bool from_exists = astar.points.lookup(p_from_id, from_point); ERR_FAIL_COND_V_MSG(!from_exists, 0, vformat("Can't compute cost. Point with id: %d doesn't exist.", p_from_id)); - AStar3D::Point *to_point; + AStar3D::Point *to_point = nullptr; bool to_exists = astar.points.lookup(p_to_id, to_point); ERR_FAIL_COND_V_MSG(!to_exists, 0, vformat("Can't compute cost. Point with id: %d doesn't exist.", p_to_id)); @@ -689,11 +689,11 @@ real_t AStar2D::_compute_cost(int64_t p_from_id, int64_t p_to_id) { } Vector AStar2D::get_point_path(int64_t p_from_id, int64_t p_to_id) { - AStar3D::Point *a; + AStar3D::Point *a = nullptr; bool from_exists = astar.points.lookup(p_from_id, a); ERR_FAIL_COND_V_MSG(!from_exists, Vector(), vformat("Can't get point path. Point with id: %d doesn't exist.", p_from_id)); - AStar3D::Point *b; + AStar3D::Point *b = nullptr; bool to_exists = astar.points.lookup(p_to_id, b); ERR_FAIL_COND_V_MSG(!to_exists, Vector(), vformat("Can't get point path. Point with id: %d doesn't exist.", p_to_id)); @@ -737,11 +737,11 @@ Vector AStar2D::get_point_path(int64_t p_from_id, int64_t p_to_id) { } Vector AStar2D::get_id_path(int64_t p_from_id, int64_t p_to_id) { - AStar3D::Point *a; + AStar3D::Point *a = nullptr; bool from_exists = astar.points.lookup(p_from_id, a); ERR_FAIL_COND_V_MSG(!from_exists, Vector(), vformat("Can't get id path. Point with id: %d doesn't exist.", p_from_id)); - AStar3D::Point *b; + AStar3D::Point *b = nullptr; bool to_exists = astar.points.lookup(p_to_id, b); ERR_FAIL_COND_V_MSG(!to_exists, Vector(), vformat("Can't get id path. Point with id: %d doesn't exist.", p_to_id)); diff --git a/core/object/object.cpp b/core/object/object.cpp index 40df13849bd..05a6ac6cee8 100644 --- a/core/object/object.cpp +++ b/core/object/object.cpp @@ -1687,6 +1687,7 @@ void Object::_bind_methods() { BIND_CONSTANT(NOTIFICATION_POSTINITIALIZE); BIND_CONSTANT(NOTIFICATION_PREDELETE); + BIND_CONSTANT(NOTIFICATION_EXTENSION_RELOADED); BIND_ENUM_CONSTANT(CONNECT_DEFERRED); BIND_ENUM_CONSTANT(CONNECT_PERSIST); @@ -2226,8 +2227,9 @@ void ObjectDB::cleanup() { extra_info = " - Resource path: " + String(resource_get_path->call(obj, nullptr, 0, call_error)); } - uint64_t id = uint64_t(i) | (uint64_t(object_slots[i].validator) << OBJECTDB_VALIDATOR_BITS) | (object_slots[i].is_ref_counted ? OBJECTDB_REFERENCE_BIT : 0); - print_line("Leaked instance: " + String(obj->get_class()) + ":" + itos(id) + extra_info); + uint64_t id = uint64_t(i) | (uint64_t(object_slots[i].validator) << OBJECTDB_SLOT_MAX_COUNT_BITS) | (object_slots[i].is_ref_counted ? OBJECTDB_REFERENCE_BIT : 0); + DEV_ASSERT(id == (uint64_t)obj->get_instance_id()); // We could just use the id from the object, but this check may help catching memory corruption catastrophes. + print_line("Leaked instance: " + String(obj->get_class()) + ":" + uitos(id) + extra_info); count--; } diff --git a/core/object/object.h b/core/object/object.h index fdd1c0b2676..d697f14b7e8 100644 --- a/core/object/object.h +++ b/core/object/object.h @@ -235,7 +235,7 @@ struct MethodInfo { return arguments_metadata.size() > p_arg ? arguments_metadata[p_arg] : 0; } - inline bool operator==(const MethodInfo &p_method) const { return id == p_method.id; } + inline bool operator==(const MethodInfo &p_method) const { return id == p_method.id && name == p_method.name; } inline bool operator<(const MethodInfo &p_method) const { return id == p_method.id ? (name < p_method.name) : (id < p_method.id); } operator Dictionary() const; diff --git a/core/object/script_language.cpp b/core/object/script_language.cpp index 3b274ecc2f2..aa9ee688215 100644 --- a/core/object/script_language.cpp +++ b/core/object/script_language.cpp @@ -694,7 +694,12 @@ void PlaceHolderScriptInstance::property_set_fallback(const StringName &p_name, } } if (!found) { - properties.push_back(PropertyInfo(p_value.get_type(), p_name, PROPERTY_HINT_NONE, "", PROPERTY_USAGE_NO_EDITOR | PROPERTY_USAGE_SCRIPT_VARIABLE)); + PropertyHint hint = PROPERTY_HINT_NONE; + const Object *obj = p_value.get_validated_object(); + if (obj && obj->is_class("Node")) { + hint = PROPERTY_HINT_NODE_TYPE; + } + properties.push_back(PropertyInfo(p_value.get_type(), p_name, hint, "", PROPERTY_USAGE_NO_EDITOR | PROPERTY_USAGE_SCRIPT_VARIABLE)); } } diff --git a/core/string/translation.cpp b/core/string/translation.cpp index 8fcf2b24b58..829c9bf7777 100644 --- a/core/string/translation.cpp +++ b/core/string/translation.cpp @@ -881,7 +881,7 @@ StringName TranslationServer::tool_pseudolocalize(const StringName &p_message) c String TranslationServer::get_override_string(String &p_message) const { String res; - for (int i = 0; i < p_message.size(); i++) { + for (int i = 0; i < p_message.length(); i++) { if (pseudolocalization_skip_placeholders_enabled && is_placeholder(p_message, i)) { res += p_message[i]; res += p_message[i + 1]; @@ -895,7 +895,7 @@ String TranslationServer::get_override_string(String &p_message) const { String TranslationServer::double_vowels(String &p_message) const { String res; - for (int i = 0; i < p_message.size(); i++) { + for (int i = 0; i < p_message.length(); i++) { if (pseudolocalization_skip_placeholders_enabled && is_placeholder(p_message, i)) { res += p_message[i]; res += p_message[i + 1]; @@ -913,7 +913,7 @@ String TranslationServer::double_vowels(String &p_message) const { String TranslationServer::replace_with_accented_string(String &p_message) const { String res; - for (int i = 0; i < p_message.size(); i++) { + for (int i = 0; i < p_message.length(); i++) { if (pseudolocalization_skip_placeholders_enabled && is_placeholder(p_message, i)) { res += p_message[i]; res += p_message[i + 1]; @@ -936,7 +936,7 @@ String TranslationServer::wrap_with_fakebidi_characters(String &p_message) const char32_t fakebidisuffix = U'\u202c'; res += fakebidiprefix; // The fake bidi unicode gets popped at every newline so pushing it back at every newline. - for (int i = 0; i < p_message.size(); i++) { + for (int i = 0; i < p_message.length(); i++) { if (p_message[i] == '\n') { res += fakebidisuffix; res += p_message[i]; @@ -978,7 +978,7 @@ const char32_t *TranslationServer::get_accented_version(char32_t p_character) co } bool TranslationServer::is_placeholder(String &p_message, int p_index) const { - return p_index < p_message.size() - 1 && p_message[p_index] == '%' && + return p_index < p_message.length() - 1 && p_message[p_index] == '%' && (p_message[p_index + 1] == 's' || p_message[p_index + 1] == 'c' || p_message[p_index + 1] == 'd' || p_message[p_index + 1] == 'o' || p_message[p_index + 1] == 'x' || p_message[p_index + 1] == 'X' || p_message[p_index + 1] == 'f'); } diff --git a/core/string/ustring.cpp b/core/string/ustring.cpp index be829502efc..874025bea24 100644 --- a/core/string/ustring.cpp +++ b/core/string/ustring.cpp @@ -3329,10 +3329,14 @@ bool String::begins_with(const String &p_string) const { bool String::begins_with(const char *p_string) const { int l = length(); - if (l == 0 || !p_string) { + if (!p_string) { return false; } + if (l == 0) { + return *p_string == 0; + } + const char32_t *str = &operator[](0); int i = 0; diff --git a/core/templates/paged_array.h b/core/templates/paged_array.h index 863e3eef116..69a792958a6 100644 --- a/core/templates/paged_array.h +++ b/core/templates/paged_array.h @@ -53,7 +53,12 @@ class PagedArrayPool { SpinLock spin_lock; public: - uint32_t alloc_page() { + struct PageInfo { + T *page = nullptr; + uint32_t page_id = 0; + }; + + PageInfo alloc_page() { spin_lock.lock(); if (unlikely(pages_available == 0)) { uint32_t pages_used = pages_allocated; @@ -69,13 +74,11 @@ public: } pages_available--; - uint32_t page = available_page_pool[pages_available]; + uint32_t page_id = available_page_pool[pages_available]; + T *page = page_pool[page_id]; spin_lock.unlock(); - return page; - } - T *get_page(uint32_t p_page_id) { - return page_pool[p_page_id]; + return PageInfo{ page, page_id }; } void free_page(uint32_t p_page_id) { @@ -190,9 +193,9 @@ public: _grow_page_array(); //keep out of inline } - uint32_t page_id = page_pool->alloc_page(); - page_data[page_count] = page_pool->get_page(page_id); - page_ids[page_count] = page_id; + typename PagedArrayPool::PageInfo page_info = page_pool->alloc_page(); + page_data[page_count] = page_info.page; + page_ids[page_count] = page_info.page_id; } // place the new value diff --git a/core/typedefs.h b/core/typedefs.h index 24c247fd388..9fa5ba320c0 100644 --- a/core/typedefs.h +++ b/core/typedefs.h @@ -92,6 +92,7 @@ #undef Error #undef OK #undef CONNECT_DEFERRED // override from Windows SDK, clashes with Object enum +#undef MONO_FONT #endif // Make room for our constexpr's below by overriding potential system-specific macros. diff --git a/doc/classes/@GlobalScope.xml b/doc/classes/@GlobalScope.xml index 0e2d8ba374a..e4064589239 100644 --- a/doc/classes/@GlobalScope.xml +++ b/doc/classes/@GlobalScope.xml @@ -2521,61 +2521,66 @@ The maximum number of game controller axes: OpenVR supports up to 5 Joysticks making a total of 10 axes. - Enum value which doesn't correspond to any MIDI message. This is used to initialize [enum MIDIMessage] properties with a generic state. + Does not correspond to any MIDI message. This is the default value of [member InputEventMIDI.message]. - MIDI note OFF message. Not all MIDI devices send this event; some send [constant MIDI_MESSAGE_NOTE_ON] with zero velocity instead. See the documentation of [InputEventMIDI] for information of how to use MIDI inputs. + MIDI message sent when a note is released. + [b]Note:[/b] Not all MIDI devices send this message; some may send [constant MIDI_MESSAGE_NOTE_ON] with [member InputEventMIDI.velocity] set to [code]0[/code]. - MIDI note ON message. Some MIDI devices send this event with velocity zero instead of [constant MIDI_MESSAGE_NOTE_OFF], but implementations vary. See the documentation of [InputEventMIDI] for information of how to use MIDI inputs. + MIDI message sent when a note is pressed. - MIDI aftertouch message. This message is most often sent by pressing down on the key after it "bottoms out". + MIDI message sent to indicate a change in pressure while a note is being pressed down, also called aftertouch. - MIDI control change message. This message is sent when a controller value changes. Controllers include devices such as pedals and levers. + MIDI message sent when a controller value changes. In a MIDI device, a controller is any input that doesn't play notes. These may include sliders for volume, balance, and panning, as well as switches and pedals. See the [url=https://en.wikipedia.org/wiki/General_MIDI#Controller_events]General MIDI specification[/url] for a small list. - MIDI program change message. This message sent when the program patch number changes. + MIDI message sent when the MIDI device changes its current instrument (also called [i]program[/i] or [i]preset[/i]). - MIDI channel pressure message. This message is most often sent by pressing down on the key after it "bottoms out". This message is different from polyphonic after-touch as it indicates the highest pressure across all keys. + MIDI message sent to indicate a change in pressure for the whole channel. Some MIDI devices may send this instead of [constant MIDI_MESSAGE_AFTERTOUCH]. - MIDI pitch bend message. This message is sent to indicate a change in the pitch bender (wheel or lever, typically). + MIDI message sent when the value of the pitch bender changes, usually a wheel on the MIDI device. - MIDI system exclusive message. This has behavior exclusive to the device you're receiving input from. Getting this data is not implemented in Godot. + MIDI system exclusive (SysEx) message. This type of message is not standardized and it's highly dependent on the MIDI device sending it. + [b]Note:[/b] Getting this message's data from [InputEventMIDI] is not implemented. - MIDI quarter frame message. Contains timing information that is used to synchronize MIDI devices. Getting this data is not implemented in Godot. + MIDI message sent every quarter frame to keep connected MIDI devices synchronized. Related to [constant MIDI_MESSAGE_TIMING_CLOCK]. + [b]Note:[/b] Getting this message's data from [InputEventMIDI] is not implemented. - MIDI song position pointer message. Gives the number of 16th notes since the start of the song. Getting this data is not implemented in Godot. + MIDI message sent to jump onto a new position in the current sequence or song. + [b]Note:[/b] Getting this message's data from [InputEventMIDI] is not implemented. - MIDI song select message. Specifies which sequence or song is to be played. Getting this data is not implemented in Godot. + MIDI message sent to select a sequence or song to play. + [b]Note:[/b] Getting this message's data from [InputEventMIDI] is not implemented. - MIDI tune request message. Upon receiving a tune request, all analog synthesizers should tune their oscillators. + MIDI message sent to request a tuning calibration. Used on analog synthesizers. Most modern MIDI devices do not need this message. - MIDI timing clock message. Sent 24 times per quarter note when synchronization is required. + MIDI message sent 24 times after [constant MIDI_MESSAGE_QUARTER_FRAME], to keep connected MIDI devices synchronized. - MIDI start message. Start the current sequence playing. This message will be followed with Timing Clocks. + MIDI message sent to start the current sequence or song from the beginning. - MIDI continue message. Continue at the point the sequence was stopped. + MIDI message sent to resume from the point the current sequence or song was paused. - MIDI stop message. Stop the current sequence. + MIDI message sent to pause the current sequence or song. - MIDI active sensing message. This message is intended to be sent repeatedly to tell the receiver that a connection is alive. + MIDI message sent repeatedly while the MIDI device is idle, to tell the receiver that the connection is alive. Most MIDI devices do not send this message. - MIDI system reset message. Reset all receivers in the system to power-up status. It should not be sent on power-up itself. + MIDI message sent to reset a MIDI device to its default state, as if it was just turned on. It should not be sent when the MIDI device is being turned on. Methods that return [enum Error] return [constant OK] when no error occurred. diff --git a/doc/classes/AnimationNode.xml b/doc/classes/AnimationNode.xml index a028d0bb4f4..d7fb735b4d4 100644 --- a/doc/classes/AnimationNode.xml +++ b/doc/classes/AnimationNode.xml @@ -27,7 +27,7 @@ - When inheriting from [AnimationRootNode], implement this virtual method to return all children animation nodes in order as a [code]name: node[/code] dictionary. + When inheriting from [AnimationRootNode], implement this virtual method to return all child animation nodes in order as a [code]name: node[/code] dictionary. @@ -115,7 +115,7 @@ - Blend another animation node (in case this animation node contains children animation nodes). This function is only useful if you inherit from [AnimationRootNode] instead, else editors will not display your animation node for addition. + Blend another animation node (in case this animation node contains child animation nodes). This function is only useful if you inherit from [AnimationRootNode] instead, otherwise editors will not display your animation node for addition. diff --git a/doc/classes/AnimationNodeTimeScale.xml b/doc/classes/AnimationNodeTimeScale.xml index d7d48145065..4cb8ccb962b 100644 --- a/doc/classes/AnimationNodeTimeScale.xml +++ b/doc/classes/AnimationNodeTimeScale.xml @@ -4,7 +4,7 @@ A time-scaling animation node used in [AnimationTree]. - Allows to scale the speed of the animation (or reverse it) in any children [AnimationNode]s. Setting it to [code]0.0[/code] will pause the animation. + Allows to scale the speed of the animation (or reverse it) in any child [AnimationNode]s. Setting it to [code]0.0[/code] will pause the animation. $DOCS_URL/tutorials/animation/animation_tree.html diff --git a/doc/classes/Array.xml b/doc/classes/Array.xml index 39b9dde0437..eb385389c1e 100644 --- a/doc/classes/Array.xml +++ b/doc/classes/Array.xml @@ -218,6 +218,11 @@ 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. Optionally, a [param before] specifier can be passed. If [code]false[/code], the returned index comes after all existing entries of the value in the array. + [codeblock] + var array = ["a", "b", "c", "c", "d", "e"] + print(array.bsearch("c", true)) # Prints 2, at the first matching element. + print(array.bsearch("c", false)) # Prints 4, after the last matching element, pointing to "d". + [/codeblock] [b]Note:[/b] Calling [method bsearch] on an unsorted array results in unexpected behavior. @@ -228,6 +233,7 @@ 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 [param before] 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] The custom method must accept the two arguments in any order, you cannot rely on that the first argument will always be from the array. [b]Note:[/b] Calling [method bsearch_custom] on an unsorted array results in unexpected behavior. diff --git a/doc/classes/AudioServer.xml b/doc/classes/AudioServer.xml index 21ad817c6c9..1e2b1d18397 100644 --- a/doc/classes/AudioServer.xml +++ b/doc/classes/AudioServer.xml @@ -281,6 +281,8 @@ + If set to [code]true[/code], all instances of [AudioStreamPlayback] will call [method AudioStreamPlayback._tag_used_streams] every mix step. + [b]Note:[/b] This is enabled by default in the editor, as it is used by editor plugins for the audio stream previews. diff --git a/doc/classes/AudioStream.xml b/doc/classes/AudioStream.xml index 12e09b235fe..a9e14899368 100644 --- a/doc/classes/AudioStream.xml +++ b/doc/classes/AudioStream.xml @@ -16,31 +16,39 @@ + Overridable method. Should return the total number of beats of this audio stream. Used by the engine to determine the position of every beat. + Ideally, the returned value should be based off the stream's sample rate ([member AudioStreamWAV.mix_rate], for example). + Overridable method. Should return the tempo of this audio stream, in beats per minute (BPM). Used by the engine to determine the position of every beat. + Ideally, the returned value should be based off the stream's sample rate ([member AudioStreamWAV.mix_rate], for example). + Override this method to customize the returned value of [method get_length]. Should return the length of this audio stream, in seconds. + Override this method to customize the name assigned to this audio stream. Unused by the engine. + Override this method to customize the returned value of [method instantiate_playback]. Should returned a new [AudioStreamPlayback] created when the stream is played (such as by an [AudioStreamPlayer]).. + Override this method to customize the returned value of [method is_monophonic]. Should return [code]true[/code] if this audio stream only supports one channel. @@ -52,13 +60,13 @@ - Returns an AudioStreamPlayback. Useful for when you want to extend [method _instantiate_playback] but call [method instantiate_playback] from an internally held AudioStream subresource. An example of this can be found in the source files for [code]AudioStreamRandomPitch::instantiate_playback[/code]. + Returns a newly created [AudioStreamPlayback] intended to play this audio stream. Useful for when you want to extend [method _instantiate_playback] but call [method instantiate_playback] from an internally held AudioStream subresource. An example of this can be found in the source code for [code]AudioStreamRandomPitch::instantiate_playback[/code]. - Returns true if this audio stream only supports monophonic playback, or false if the audio stream supports polyphony. + Returns [code]true[/code] if this audio stream only supports one channel ([i]monophony[/i]), or [code]false[/code] if the audio stream supports two or more channels ([i]polyphony[/i]). diff --git a/doc/classes/AudioStreamPlayback.xml b/doc/classes/AudioStreamPlayback.xml index 7692690b5ed..1997407916d 100644 --- a/doc/classes/AudioStreamPlayback.xml +++ b/doc/classes/AudioStreamPlayback.xml @@ -13,16 +13,19 @@ + Overridable method. Should return how many times this audio stream has looped. Most built-in playbacks always return [code]0[/code]. + Overridable method. Should return the current progress along the audio stream, in seconds. + Overridable method. Should return [code]true[/code] if this playback is active and playing its audio stream. @@ -31,28 +34,34 @@ + Override this method to customize how the audio stream is mixed. This method is called even if the playback is not active. + [b]Note:[/b] It is not useful to override this method in GDScript or C#. Only GDExtension can take advantage of it. + Override this method to customize what happens when seeking this audio stream at the given [param position], such as by calling [method AudioStreamPlayer.seek]. + Override this method to customize what happens when the playback starts at the given position, such as by calling [method AudioStreamPlayer.play]. + Override this method to customize what happens when the playback is stopped, such as by calling [method AudioStreamPlayer.stop]. + Overridable method. Called whenever the audio stream is mixed if the playback is active and [method AudioServer.set_enable_tagging_used_audio_streams] has been set to [code]true[/code]. Editor plugins may use this method to "tag" the current position along the audio stream and display it in a preview. diff --git a/doc/classes/Basis.xml b/doc/classes/Basis.xml index fb6cf5a2587..1bd57088774 100644 --- a/doc/classes/Basis.xml +++ b/doc/classes/Basis.xml @@ -4,10 +4,12 @@ A 3×3 matrix for representing 3D rotation and scale. - A 3×3 matrix used for representing 3D rotation and scale. Usually used as an orthogonal basis for a [Transform3D]. - Contains 3 vector fields X, Y and Z as its columns, which are typically interpreted as the local basis vectors of a transformation. For such use, it is composed of a scaling and a rotation matrix, in that order (M = R.S). - Basis can also be accessed as an array of 3D vectors. These vectors are usually orthogonal to each other, but are not necessarily normalized (due to scaling). + The [Basis] built-in [Variant] type is a 3x3 [url=https://en.wikipedia.org/wiki/Matrix_(mathematics)]matrix[/url] used to represent 3D rotation, scale, and shear. It is frequently used within a [Transform3D]. + A [Basis] is composed by 3 axis vectors, each representing a column of the matrix: [member x], [member y], and [member z]. The length of each axis ([method Vector3.length]) influences the basis's scale, while the direction of all axes influence the rotation. Usually, these axes are perpendicular to one another. However, when you rotate any axis individually, the basis becomes sheared. Applying a sheared basis to a 3D model will make the model appear distorted. + A [Basis] is [b]orthogonal[/b] if its axes are perpendicular to each other. A basis is [b]normalized[/b] if the length of every axis is [code]1[/code]. A basis is [b]uniform[/b] if all axes share the same length (see [method get_scale]). A basis is [b]orthonormal[/b] if it is both orthogonal and normalized, which allows it to only represent rotations. A basis is [b]conformal[/b] if it is both orthogonal and uniform, which ensures it is not distorted. For a general introduction, see the [url=$DOCS_URL/tutorials/math/matrices_and_transforms.html]Matrices and transforms[/url] tutorial. + [b]Note:[/b] Godot uses a [url=https://en.wikipedia.org/wiki/Right-hand_rule]right-handed coordinate system[/url], which is a common standard. For directions, the convention for built-in types like [Camera3D] is for -Z to point forward (+X is right, +Y is up, and +Z is back). Other objects may use different direction conventions. For more information, see the [url=$DOCS_URL/tutorials/assets_pipeline/importing_scenes.html#d-asset-direction-conventions]Importing 3D Scenes[/url] tutorial. + [b]Note:[/b] The basis matrices are exposed as [url=https://www.mindcontrol.org/~hplus/graphics/matrix-layout.html]column-major[/url] order, which is the same as OpenGL. However, they are stored internally in row-major order, which is the same as DirectX. $DOCS_URL/tutorials/math/index.html @@ -22,7 +24,7 @@ - Constructs a default-initialized [Basis] set to [constant IDENTITY]. + Constructs a [Basis] identical to the [constant IDENTITY]. @@ -37,14 +39,16 @@ - Constructs a pure rotation basis matrix, rotated around the given [param axis] by [param angle] (in radians). The axis must be a normalized vector. + Constructs a [Basis] that only represents rotation, rotated around the [param axis] by the given [param angle], in radians. The axis must be a normalized vector. + [b]Note:[/b] This is the same as using [method rotated] on the [constant IDENTITY] basis. With more than one angle consider using [method from_euler], instead. - Constructs a pure rotation basis matrix from the given quaternion. + Constructs a [Basis] that only represents rotation from the given [Quaternion]. + [b]Note:[/b] Quaternions [i]only[/i] store rotation, not scale. Because of this, conversions from [Basis] to [Quaternion] cannot always be reversed. @@ -53,7 +57,7 @@ - Constructs a basis matrix from 3 axis vectors (matrix columns). + Constructs a [Basis] from 3 axis vectors. These are the columns of the basis matrix. @@ -61,8 +65,10 @@ - Returns the determinant of the basis matrix. If the basis is uniformly scaled, its determinant is the square of the scale. - A negative determinant means the basis has a negative scale. A zero determinant means the basis isn't invertible, and is usually considered invalid. + Returns the [url=https://en.wikipedia.org/wiki/Determinant]determinant[/url] of this basis's matrix. For advanced math, this number can be used to determine a few attributes: + - If the determinant is exactly [code]0[/code], the basis is not invertible (see [method inverse]). + - If the determinant is a negative number, the basis represents a negative scale. + [b]Note:[/b] If the basis's scale is the same for every axis, its determinant is always that scale by the power of 2. @@ -70,46 +76,114 @@ - Constructs a pure rotation Basis matrix from Euler angles in the specified Euler rotation order. By default, use YXZ order (most common). See the [enum EulerOrder] enum for possible values. + Constructs a new [Basis] that only represents rotation from the given [Vector3] of [url=https://en.wikipedia.org/wiki/Euler_angles]Euler angles[/url], in radians. + - The [member Vector3.x] should contain the angle around the [member x] axis (pitch). + - The [member Vector3.y] should contain the angle around the [member y] axis (yaw). + - The [member Vector3.z] should contain the angle around the [member z] axis (roll). + [codeblocks] + [gdscript] + # Creates a Basis whose z axis points down. + var my_basis = Basis.from_euler(Vector3(TAU / 4, 0, 0)) + + print(my_basis.z) # Prints (0, -1, 0). + [/gdscript] + [csharp] + // Creates a Basis whose z axis points down. + var myBasis = Basis.FromEuler(new Vector3(Mathf.Tau / 4.0f, 0.0f, 0.0f)); + + GD.Print(myBasis.Z); // Prints (0, -1, 0). + [/csharp] + [/codeblocks] + The order of each consecutive rotation can be changed with [param order] (see [enum EulerOrder] constants). By default, the YXZ convention is used ([constant EULER_ORDER_YXZ]): the basis rotates first around the Y axis (yaw), then X (pitch), and lastly Z (roll). When using the opposite method [method get_euler], this order is reversed. - Constructs a pure scale basis matrix with no rotation or shearing. The scale values are set as the diagonal of the matrix, and the other parts of the matrix are zero. + Constructs a new [Basis] that only represents scale, with no rotation or shear, from the given [param scale] vector. + [codeblocks] + [gdscript] + var my_basis = Basis.from_scale(Vector3(2, 4, 8)) + + print(my_basis.x) # Prints (2, 0, 0). + print(my_basis.y) # Prints (0, 4, 0). + print(my_basis.z) # Prints (0, 0, 8). + [/gdscript] + [csharp] + var myBasis = Basis.FromScale(new Vector3(2.0f, 4.0f, 8.0f)); + + GD.Print(myBasis.X); // Prints (2, 0, 0). + GD.Print(myBasis.Y); // Prints (0, 4, 0). + GD.Print(myBasis.Z); // Prints (0, 0, 8). + [/csharp] + [/codeblocks] + [b]Note:[/b] In linear algebra, the matrix of this basis is also known as a [url=https://en.wikipedia.org/wiki/Diagonal_matrix]diagonal matrix[/url]. - Returns the basis's rotation in the form of Euler angles. The Euler order depends on the [param order] parameter, by default it uses the YXZ convention: when decomposing, first Z, then X, and Y last. The returned vector contains the rotation angles in the format (X angle, Y angle, Z angle). - Consider using the [method get_rotation_quaternion] method instead, which returns a [Quaternion] quaternion instead of Euler angles. + Returns this basis's rotation as a [Vector3] of [url=https://en.wikipedia.org/wiki/Euler_angles]Euler angles[/url], in radians. + - The [member Vector3.x] contains the angle around the [member x] axis (pitch); + - The [member Vector3.y] contains the angle around the [member y] axis (yaw); + - The [member Vector3.z] contains the angle around the [member z] axis (roll). + The order of each consecutive rotation can be changed with [param order] (see [enum EulerOrder] constants). By default, the YXZ convention is used ([constant EULER_ORDER_YXZ]): Z (roll) is calculated first, then X (pitch), and lastly Y (yaw). When using the opposite method [method from_euler], this order is reversed. + [b]Note:[/b] Euler angles are much more intuitive but are not suitable for 3D math. Because of this, consider using the [method get_rotation_quaternion] method instead, which returns a [Quaternion]. + [b]Note:[/b] In the Inspector dock, a basis's rotation is often displayed in Euler angles (in degrees), as is the case with the [member Node3D.rotation] property. - Returns the basis's rotation in the form of a quaternion. See [method get_euler] if you need Euler angles, but keep in mind quaternions should generally be preferred to Euler angles. + Returns this basis's rotation as a [Quaternion]. + [b]Note:[/b] Quatenions are much more suitable for 3D math but are less intuitive. For user interfaces, consider using the [method get_euler] method, which returns Euler angles. - Assuming that the matrix is the combination of a rotation and scaling, return the absolute value of scaling factors along each axis. + Returns the length of each axis of this basis, as a [Vector3]. If the basis is not sheared, this is the scaling factor. It is not affected by rotation. + [codeblocks] + [gdscript] + var my_basis = Basis( + Vector3(2, 0, 0), + Vector3(0, 4, 0), + Vector3(0, 0, 8) + ) + # Rotating the Basis in any way preserves its scale. + my_basis = my_basis.rotated(Vector3.UP, TAU / 2) + my_basis = my_basis.rotated(Vector3.RIGHT, TAU / 4) + + print(my_basis.get_scale()) # Prints (2, 4, 8). + [/gdscript] + [csharp] + var myBasis = new Basis( + Vector3(2.0f, 0.0f, 0.0f), + Vector3(0.0f, 4.0f, 0.0f), + Vector3(0.0f, 0.0f, 8.0f) + ); + // Rotating the Basis in any way preserves its scale. + myBasis = myBasis.Rotated(Vector3.Up, Mathf.Tau / 2.0f); + myBasis = myBasis.Rotated(Vector3.Right, Mathf.Tau / 4.0f); + + GD.Print(myBasis.Scale); // Prints (2, 4, 8). + [/csharp] + [/codeblocks] + [b]Note:[/b] If the value returned by [method determinant] is negative, the scale is also negative. - Returns the inverse of the matrix. + Returns the [url=https://en.wikipedia.org/wiki/Invertible_matrix]inverse of this basis's matrix[/url]. - Returns [code]true[/code] if the basis is conformal, meaning it preserves angles and distance ratios, and may only be composed of rotation and uniform scale. Returns [code]false[/code] if the basis has non-uniform scale or shear/skew. This can be used to validate if the basis is non-distorted, which is important for physics and other use cases. + Returns [code]true[/code] if this basis is conformal. A conformal basis is both [i]orthogonal[/i] (the axes are perpendicular to each other) and [i]uniform[/i] (the axes share the same length). This method can be especially useful during physics calculations. @@ -131,15 +205,35 @@ - Creates a Basis with a rotation such that the forward axis (-Z) points towards the [param target] position. - The up axis (+Y) points as close to the [param up] vector as possible while staying perpendicular to the forward axis. The resulting Basis is orthonormalized. The [param target] and [param up] vectors cannot be zero, and cannot be parallel to each other. - If [param use_model_front] is [code]true[/code], the +Z axis (asset front) is treated as forward (implies +X is left) and points toward the [param target] position. By default, the -Z axis (camera forward) is treated as forward (implies +X is right). + Creates a new [Basis] with a rotation such that the forward axis (-Z) points towards the [param target] position. + By default, the -Z axis (camera forward) is treated as forward (implies +X is right). If [param use_model_front] is [code]true[/code], the +Z axis (asset front) is treated as forward (implies +X is left) and points toward the [param target] position. + The up axis (+Y) points as close to the [param up] vector as possible while staying perpendicular to the forward axis. The returned basis is orthonormalized (see [method orthonormalized]). The [param target] and [param up] vectors cannot be [constant Vector3.ZERO], and cannot be parallel to each other. - Returns the orthonormalized version of the matrix (useful to call from time to time to avoid rounding error for orthogonal matrices). This performs a Gram-Schmidt orthonormalization on the basis of the matrix. + Returns the orthonormalized version of this basis. An orthonormal basis is both [i]orthogonal[/i] (the axes are perpendicular to each other) and [i]normalized[/i] (the axes have a length of [code]1[/code]), which also means it can only represent rotation. + It is often useful to call this method to avoid rounding errors on a rotating basis: + [codeblocks] + [gdscript] + # Rotate this Node3D every frame. + func _process(delta): + basis = basis.rotated(Vector3.UP, TAU * delta) + basis = basis.rotated(Vector3.RIGHT, TAU * delta) + + basis = basis.orthonormalized() + [/gdscript] + [csharp] + // Rotate this Node3D every frame. + public override void _Process(double delta) + { + Basis = Basis.Rotated(Vector3.Up, Mathf.Tau * (float)delta) + .Rotated(Vector3.Right, Mathf.Tau * (float)delta) + .Orthonormalized(); + } + [/csharp] + [/codeblocks] @@ -147,14 +241,60 @@ - Introduce an additional rotation around the given axis by [param angle] (in radians). The axis must be a normalized vector. + Returns this basis rotated around the given [param axis] by [param angle] (in radians). The [param axis] must be a normalized vector (see [method Vector3.normalized]). + Positive values rotate this basis clockwise around the axis, while negative values rotate it counterclockwise. + [codeblocks] + [gdscript] + var my_basis = Basis.IDENTITY + var angle = TAU / 2 + + my_basis = my_basis.rotated(Vector3.UP, angle) # Rotate around the up axis (yaw). + my_basis = my_basis.rotated(Vector3.RIGHT, angle) # Rotate around the right axis (pitch). + my_basis = my_basis.rotated(Vector3.BACK, angle) # Rotate around the back axis (roll). + [/gdscript] + [csharp] + var myBasis = Basis.Identity; + var angle = Mathf.Tau / 2.0f; + + myBasis = myBasis.Rotated(Vector3.Up, angle); // Rotate around the up axis (yaw). + myBasis = myBasis.Rotated(Vector3.Right, angle); // Rotate around the right axis (pitch). + myBasis = myBasis.Rotated(Vector3.Back, angle); // Rotate around the back axis (roll). + [/csharp] + [/codeblocks] - Introduce an additional scaling specified by the given 3D scaling factor. + Returns this basis with each axis's components scaled by the given [param scale]'s components. + The basis matrix's rows are multiplied by [param scale]'s components. This operation is a global scale (relative to the parent). + [codeblocks] + [gdscript] + var my_basis = Basis( + Vector3(1, 1, 1), + Vector3(2, 2, 2), + Vector3(3, 3, 3) + ) + my_basis = my_basis.scaled(Vector3(0, 2, -2)) + + print(my_basis.x) # Prints (0, 2, -2). + print(my_basis.y) # Prints (0, 4, -4). + print(my_basis.z) # Prints (0, 6, -6). + [/gdscript] + [csharp] + var myBasis = new Basis( + new Vector3(1.0f, 1.0f, 1.0f), + new Vector3(2.0f, 2.0f, 2.0f), + new Vector3(3.0f, 3.0f, 3.0f) + ); + myBasis = myBasis.Scaled(new Vector3(0.0f, 2.0f, -2.0f)); + + GD.Print(myBasis.X); // Prints (0, 2, -2). + GD.Print(myBasis.Y); // Prints (0, 4, -4). + GD.Print(myBasis.Z); // Prints (0, 6, -6). + [/csharp] + [/codeblocks] @@ -162,61 +302,122 @@ - Assuming that the matrix is a proper rotation matrix, slerp performs a spherical-linear interpolation with another rotation matrix. + Performs a spherical-linear interpolation with the [param to] basis, given a [param weight]. Both this basis and [param to] should represent a rotation. + [b]Example:[/b] Smoothly rotate a [Node3D] to the target basis over time, with a [Tween]. + [codeblock] + var start_basis = Basis.IDENTITY + var target_basis = Basis.IDENTITY.rotated(Vector3.UP, TAU / 2) + + func _ready(): + create_tween().tween_method(interpolate, 0.0, 1.0, 5.0).set_trans(Tween.TRANS_EXPO) + + func interpolate(weight): + basis = start_basis.slerp(target_basis, weight) + [/codeblock] - Transposed dot product with the X axis of the matrix. + Returns the transposed dot product between [param with] and the [member x] axis (see [method transposed]). + This is equivalent to [code]basis.x.dot(vector)[/code]. - Transposed dot product with the Y axis of the matrix. + Returns the transposed dot product between [param with] and the [member y] axis (see [method transposed]). + This is equivalent to [code]basis.y.dot(vector)[/code]. - Transposed dot product with the Z axis of the matrix. + Returns the transposed dot product between [param with] and the [member z] axis (see [method transposed]). + This is equivalent to [code]basis.z.dot(vector)[/code]. - Returns the transposed version of the matrix. + Returns the transposed version of this basis. This turns the basis matrix's columns into rows, and its rows into columns. + [codeblocks] + [gdscript] + var my_basis = Basis( + Vector3(1, 2, 3), + Vector3(4, 5, 6), + Vector3(7, 8, 9) + ) + my_basis = my_basis.transposed() + + print(my_basis.x) # Prints (1, 4, 7). + print(my_basis.y) # Prints (2, 5, 8). + print(my_basis.z) # Prints (3, 6, 9). + [/gdscript] + [csharp] + var myBasis = new Basis( + new Vector3(1.0f, 2.0f, 3.0f), + new Vector3(4.0f, 5.0f, 6.0f), + new Vector3(7.0f, 8.0f, 9.0f) + ); + myBasis = myBasis.Transposed(); + + GD.Print(myBasis.X); // Prints (1, 4, 7). + GD.Print(myBasis.Y); // Prints (2, 5, 8). + GD.Print(myBasis.Z); // Prints (3, 6, 9). + [/csharp] + [/codeblocks] - The basis matrix's X vector (column 0). Equivalent to array index [code]0[/code]. + The basis's X axis, and the column [code]0[/code] of the matrix. + On the identity basis, this vector points right ([constant Vector3.RIGHT]). - The basis matrix's Y vector (column 1). Equivalent to array index [code]1[/code]. + The basis's Y axis, and the column [code]1[/code] of the matrix. + On the identity basis, this vector points up ([constant Vector3.UP]). - The basis matrix's Z vector (column 2). Equivalent to array index [code]2[/code]. + The basis's Z axis, and the column [code]2[/code] of the matrix. + On the identity basis, this vector points back ([constant Vector3.BACK]). - The identity basis, with no rotation or scaling applied. + The identity basis. This is a basis with no rotation, no shear, and its scale being [code]1[/code]. This means that: + - The [member x] points right ([constant Vector3.RIGHT]); + - The [member y] points up ([constant Vector3.UP]); + - The [member z] points back ([constant Vector3.BACK]). + [codeblock] + var basis := Basis.IDENTITY + print("| X | Y | Z") + print("| %s | %s | %s" % [basis.x.x, basis.y.x, basis.z.x]) + print("| %s | %s | %s" % [basis.x.y, basis.y.y, basis.z.y]) + print("| %s | %s | %s" % [basis.x.z, basis.y.z, basis.z.z]) + # Prints: + # | X | Y | Z + # | 1 | 0 | 0 + # | 0 | 1 | 0 + # | 0 | 0 | 1 + [/codeblock] This is identical to creating [constructor Basis] without any parameters. This constant can be used to make your code clearer, and for consistency with C#. - The basis that will flip something along the X axis when used in a transformation. + When any basis is multiplied by [constant FLIP_X], it negates all components of the [member x] axis (the X column). + When [constant FLIP_X] is multiplied by any basis, it negates the [member Vector3.x] component of all axes (the X row). - The basis that will flip something along the Y axis when used in a transformation. + When any basis is multiplied by [constant FLIP_Y], it negates all components of the [member y] axis (the Y column). + When [constant FLIP_Y] is multiplied by any basis, it negates the [member Vector3.y] component of all axes (the Y row). - The basis that will flip something along the Z axis when used in a transformation. + When any basis is multiplied by [constant FLIP_Z], it negates all components of the [member z] axis (the Z column). + When [constant FLIP_Z] is multiplied by any basis, it negates the [member Vector3.z] component of all axes (the Z row). @@ -224,7 +425,7 @@ - Returns [code]true[/code] if the [Basis] matrices are not equal. + Returns [code]true[/code] if the components of both [Basis] matrices are not equal. [b]Note:[/b] Due to floating-point precision errors, consider using [method is_equal_approx] instead, which is more reliable. @@ -232,35 +433,46 @@ - Composes these two basis matrices by multiplying them together. This has the effect of transforming the second basis (the child) by the first basis (the parent). + Transforms (multiplies) the [param right] basis by this basis. + This is the operation performed between parent and child [Node3D]s. - Transforms (multiplies) the [Vector3] by the given [Basis] matrix. + Transforms (multiplies) the [param right] vector by this basis, returning a [Vector3]. + [codeblocks] + [gdscript] + var my_basis = Basis(Vector3(1, 1, 1), Vector3(1, 1, 1), Vector3(0, 2, 5)) + print(my_basis * Vector3(1, 2, 3)) # Prints (7, 3, 16) + [/gdscript] + [csharp] + var myBasis = new Basis(new Vector3(1, 1, 1), new Vector3(1, 1, 1), new Vector3(0, 2, 5)); + GD.Print(my_basis * new Vector3(1, 2, 3)); // Prints (7, 3, 16) + [/csharp] + [/codeblocks] - This operator multiplies all components of the [Basis], which scales it uniformly. + Multiplies all components of the [Basis] by the given [float]. This affects the basis's scale uniformly, resizing all 3 axes by the [param right] value. - This operator multiplies all components of the [Basis], which scales it uniformly. + Multiplies all components of the [Basis] by the given [int]. This affects the basis's scale uniformly, resizing all 3 axes by the [param right] value. - Returns [code]true[/code] if the [Basis] matrices are exactly equal. + Returns [code]true[/code] if the components of both [Basis] matrices are exactly equal. [b]Note:[/b] Due to floating-point precision errors, consider using [method is_equal_approx] instead, which is more reliable. @@ -268,7 +480,8 @@ - Access basis components using their index. [code]b[0][/code] is equivalent to [code]b.x[/code], [code]b[1][/code] is equivalent to [code]b.y[/code], and [code]b[2][/code] is equivalent to [code]b.z[/code]. + Accesses each axis (column) of this basis by their index. Index [code]0[/code] is the same as [member x], index [code]1[/code] is the same as [member y], and index [code]2[/code] is the same as [member z]. + [b]Note:[/b] In C++, this operator accesses the rows of the basis matrix, [i]not[/i] the columns. For the same behavior as scripting languages, use the [code]set_column[/code] and [code]get_column[/code] methods. diff --git a/doc/classes/Bone2D.xml b/doc/classes/Bone2D.xml index a62c160080e..da7f08e53d7 100644 --- a/doc/classes/Bone2D.xml +++ b/doc/classes/Bone2D.xml @@ -15,7 +15,7 @@ - Stores the node's current transforms in [member rest]. + Resets the bone to the rest pose. This is equivalent to setting [member Node2D.transform] to [member rest]. diff --git a/doc/classes/Callable.xml b/doc/classes/Callable.xml index b903e98319d..5af0597e20b 100644 --- a/doc/classes/Callable.xml +++ b/doc/classes/Callable.xml @@ -113,6 +113,7 @@ func _ready(): grab_focus.call_deferred() [/codeblock] + [b]Note:[/b] Deferred calls are processed at idle time. Idle time happens mainly at the end of process and physics frames. In it, deferred calls will be run until there are none left, which means you can defer calls from other deferred calls and they'll still be run in the current idle time cycle. This means you should not call a method deferred from itself (or from a method called by it), as this causes infinite recursion the same way as if you had called the method directly. See also [method Object.call_deferred]. diff --git a/doc/classes/CanvasItem.xml b/doc/classes/CanvasItem.xml index 6f4dc47fb94..076c637ac6f 100644 --- a/doc/classes/CanvasItem.xml +++ b/doc/classes/CanvasItem.xml @@ -522,7 +522,7 @@ Moves this node to display on top of its siblings. - Internally, the node is moved to the bottom of parent's children list. The method has no effect on nodes without a parent. + Internally, the node is moved to the bottom of parent's child list. The method has no effect on nodes without a parent. @@ -562,7 +562,7 @@ - Allows the current node to clip children nodes, essentially acting as a mask. + Allows the current node to clip child nodes, essentially acting as a mask. The rendering layers in which this [CanvasItem] responds to [Light2D] nodes. diff --git a/doc/classes/Color.xml b/doc/classes/Color.xml index 86e421b5b82..393e8525844 100644 --- a/doc/classes/Color.xml +++ b/doc/classes/Color.xml @@ -4,7 +4,7 @@ A color represented in RGBA format. - A color represented in RGBA format by a red ([member r]), green ([member g]), blue ([member b]), and alpha ([member a]) component. Each component is a 16-bit floating-point value, usually ranging from [code]0.0[/code] to [code]1.0[/code]. Some properties (such as [member CanvasItem.modulate]) may support values greater than [code]1.0[/code], for overbright or HDR (High Dynamic Range) colors. + A color represented in RGBA format by a red ([member r]), green ([member g]), blue ([member b]), and alpha ([member a]) component. Each component is a 32-bit floating-point value, usually ranging from [code]0.0[/code] to [code]1.0[/code]. Some properties (such as [member CanvasItem.modulate]) may support values greater than [code]1.0[/code], for overbright or HDR (High Dynamic Range) colors. Colors can be created in various ways: By the various [Color] constructors, by static methods such as [method from_hsv], and by using a name from the set of standardized colors based on [url=https://en.wikipedia.org/wiki/X11_color_names]X11 color names[/url] with the addition of [constant TRANSPARENT]. GDScript also provides [method @GDScript.Color8], which uses integers from [code]0[/code] to [code]255[/code] and doesn't support overbright colors. [b]Note:[/b] In a boolean context, a Color will evaluate to [code]false[/code] if it is 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] diff --git a/doc/classes/DisplayServer.xml b/doc/classes/DisplayServer.xml index 57259e98eef..491b64a4ee2 100644 --- a/doc/classes/DisplayServer.xml +++ b/doc/classes/DisplayServer.xml @@ -1646,7 +1646,7 @@ Display server supports setting the mouse cursor shape to a custom image. [b]Windows, macOS, Linux (X11), Web[/b] - Display server supports spawning dialogs using the operating system's native look-and-feel. [b]macOS[/b] + Display server supports spawning dialogs using the operating system's native look-and-feel. [b]Windows, macOS, Linux (X11)[/b] Display server supports [url=https://en.wikipedia.org/wiki/Input_method]Input Method Editor[/url], which is commonly used for inputting Chinese/Japanese/Korean text. This is handled by the operating system, rather than by Godot. [b]Windows, macOS, Linux (X11)[/b] diff --git a/doc/classes/EditorExportPlatform.xml b/doc/classes/EditorExportPlatform.xml index 6801ac672c5..0e5de79b25d 100644 --- a/doc/classes/EditorExportPlatform.xml +++ b/doc/classes/EditorExportPlatform.xml @@ -8,7 +8,7 @@ Used in scripting by [EditorExportPlugin] to configure platform-specific customization of scenes and resources. See [method EditorExportPlugin._begin_customize_scenes] and [method EditorExportPlugin._begin_customize_resources] for more details. - Console support in Godot + $DOCS_URL/tutorials/platform/consoles.html diff --git a/doc/classes/EditorNode3DGizmo.xml b/doc/classes/EditorNode3DGizmo.xml index 16804003843..7597489601e 100644 --- a/doc/classes/EditorNode3DGizmo.xml +++ b/doc/classes/EditorNode3DGizmo.xml @@ -9,6 +9,13 @@ + + + + + + + diff --git a/doc/classes/EditorNode3DGizmoPlugin.xml b/doc/classes/EditorNode3DGizmoPlugin.xml index da7ee173353..8fd7c167d90 100644 --- a/doc/classes/EditorNode3DGizmoPlugin.xml +++ b/doc/classes/EditorNode3DGizmoPlugin.xml @@ -11,6 +11,14 @@ $DOCS_URL/tutorials/plugins/editor/3d_gizmos.html + + + + + + + + diff --git a/doc/classes/FileAccess.xml b/doc/classes/FileAccess.xml index df8ebc12fa8..2abd9974ca5 100644 --- a/doc/classes/FileAccess.xml +++ b/doc/classes/FileAccess.xml @@ -517,12 +517,14 @@ Opens the file for write operations. The file is created if it does not exist, and truncated if it does. + [b]Note:[/b] When creating a file it must be in an already existing directory. To recursively create directories for a file path, see [method DirAccess.make_dir_recursive]). Opens the file for read and write operations. Does not truncate the file. The cursor is positioned at the beginning of the file. Opens the file for read and write operations. The file is created if it does not exist, and truncated if it does. The cursor is positioned at the beginning of the file. + [b]Note:[/b] When creating a file it must be in an already existing directory. To recursively create directories for a file path, see [method DirAccess.make_dir_recursive]). Uses the [url=https://fastlz.org/]FastLZ[/url] compression method. diff --git a/doc/classes/FlowContainer.xml b/doc/classes/FlowContainer.xml index 14e84b40e63..62fa213d2bf 100644 --- a/doc/classes/FlowContainer.xml +++ b/doc/classes/FlowContainer.xml @@ -39,10 +39,10 @@ - The horizontal separation of children nodes. + The horizontal separation of child nodes. - The vertical separation of children nodes. + The vertical separation of child nodes. diff --git a/doc/classes/Font.xml b/doc/classes/Font.xml index 63e7d80737b..119c7fd6a58 100644 --- a/doc/classes/Font.xml +++ b/doc/classes/Font.xml @@ -135,7 +135,7 @@ - Returns the size of a character, optionally taking kerning into account if the next character is provided. + Returns the size of a character. Does not take kerning into account. [b]Note:[/b] Do not use this function to calculate width of the string character by character, use [method get_string_size] or [TextLine] instead. The height returned is the font height (see also [method get_height]) and has no relation to the glyph height. diff --git a/doc/classes/GridContainer.xml b/doc/classes/GridContainer.xml index cd96bd49d95..d69f4a10d27 100644 --- a/doc/classes/GridContainer.xml +++ b/doc/classes/GridContainer.xml @@ -18,10 +18,10 @@ - The horizontal separation of children nodes. + The horizontal separation of child nodes. - The vertical separation of children nodes. + The vertical separation of child nodes. diff --git a/doc/classes/Input.xml b/doc/classes/Input.xml index 334b04a79c1..7d59f6a8d89 100644 --- a/doc/classes/Input.xml +++ b/doc/classes/Input.xml @@ -295,6 +295,7 @@ Input.ParseInputEvent(cancelEvent); [/csharp] [/codeblocks] + [b]Note:[/b] Calling this function has no influence on the operating system. So for example sending an [InputEventMouseMotion] will not move the OS mouse cursor to the specified position (use [method warp_mouse] instead) and sending [kbd]Alt/Cmd + Tab[/kbd] as [InputEventKey] won't toggle between active windows. diff --git a/doc/classes/InputEventJoypadButton.xml b/doc/classes/InputEventJoypadButton.xml index 4a1ecb962c0..2516ef67dd3 100644 --- a/doc/classes/InputEventJoypadButton.xml +++ b/doc/classes/InputEventJoypadButton.xml @@ -16,8 +16,9 @@ If [code]true[/code], the button's state is pressed. If [code]false[/code], the button's state is released. - - Represents the pressure the user puts on the button with their finger, if the controller supports it. Ranges from [code]0[/code] to [code]1[/code]. + + Represents the pressure the user puts on a pressure-sensitive button. + [i]Deprecated.[/i] This property is never set by the engine and is always [code]0[/code]. diff --git a/doc/classes/InputEventMIDI.xml b/doc/classes/InputEventMIDI.xml index 8e2ad528018..0f0b7566512 100644 --- a/doc/classes/InputEventMIDI.xml +++ b/doc/classes/InputEventMIDI.xml @@ -1,12 +1,12 @@ - Represents an input event from a MIDI device, such as a piano. + Represents a MIDI message from a MIDI device, such as a musical keyboard. - InputEventMIDI allows receiving input events from MIDI (Musical Instrument Digital Interface) devices such as a piano. - MIDI signals can be sent over a 5-pin MIDI connector or over USB, if your device supports both be sure to check the settings in the device to see which output it's using. - To receive input events from MIDI devices, you need to call [method OS.open_midi_inputs]. You can check which devices are detected using [method OS.get_connected_midi_inputs]. + InputEventMIDI stores information about messages from [url=https://en.wikipedia.org/wiki/MIDI]MIDI[/url] (Musical Instrument Digital Interface) devices. These may include musical keyboards, synthesizers, and drum machines. + MIDI messages can be received over a 5-pin MIDI connector or over USB. If your device supports both be sure to check the settings in the device to see which output it is using. + By default, Godot does not detect MIDI devices. You need to call [method OS.open_midi_inputs], first. You can check which devices are detected with [method OS.get_connected_midi_inputs], and close the connection with [method OS.close_midi_inputs]. [codeblocks] [gdscript] func _ready(): @@ -17,16 +17,16 @@ if input_event is InputEventMIDI: _print_midi_info(input_event) - func _print_midi_info(midi_event: InputEventMIDI): + func _print_midi_info(midi_event): print(midi_event) - print("Channel " + str(midi_event.channel)) - print("Message " + str(midi_event.message)) - print("Pitch " + str(midi_event.pitch)) - print("Velocity " + str(midi_event.velocity)) - print("Instrument " + str(midi_event.instrument)) - print("Pressure " + str(midi_event.pressure)) - print("Controller number: " + str(midi_event.controller_number)) - print("Controller value: " + str(midi_event.controller_value)) + print("Channel ", midi_event.channel) + print("Message ", midi_event.message) + print("Pitch ", midi_event.pitch) + print("Velocity ", midi_event.velocity) + print("Instrument ", midi_event.instrument) + print("Pressure ", midi_event.pressure) + print("Controller number: ", midi_event.controller_number) + print("Controller value: ", midi_event.controller_value) [/gdscript] [csharp] public override void _Ready() @@ -35,9 +35,9 @@ GD.Print(OS.GetConnectedMidiInputs()); } - public override void _Input(InputEvent @event) + public override void _Input(InputEvent inputEvent) { - if (@event is InputEventMIDI midiEvent) + if (inputEvent is InputEventMIDI midiEvent) { PrintMIDIInfo(midiEvent); } @@ -57,7 +57,7 @@ } [/csharp] [/codeblocks] - Note that Godot does not currently support MIDI output, so there is no way to emit MIDI signals from Godot. Only MIDI input works. + [b]Note:[/b] Godot does not support MIDI output, so there is no way to emit MIDI messages from Godot. Only MIDI input is supported. https://www.midi.org/specifications-old/item/table-2-expanded-messages-list-status-bytes @@ -66,33 +66,39 @@ - The MIDI channel of this input event. There are 16 channels, so this value ranges from 0 to 15. MIDI channel 9 is reserved for the use with percussion instruments, the rest of the channels are for non-percussion instruments. + The MIDI channel of this message, ranging from [code]0[/code] to [code]15[/code]. MIDI channel [code]9[/code] is reserved for percussion instruments. - If the message is [constant MIDI_MESSAGE_CONTROL_CHANGE], this indicates the controller number, otherwise this is zero. Controllers include devices such as pedals and levers. + The unique number of the controller, if [member message] is [constant MIDI_MESSAGE_CONTROL_CHANGE], otherwise this is [code]0[/code]. This value can be used to identify sliders for volume, balance, and panning, as well as switches and pedals on the MIDI device. See the [url=https://en.wikipedia.org/wiki/General_MIDI#Controller_events]General MIDI specification[/url] for a small list. - If the message is [constant MIDI_MESSAGE_CONTROL_CHANGE], this indicates the controller value, otherwise this is zero. Controllers include devices such as pedals and levers. + The value applied to the controller. If [member message] is [constant MIDI_MESSAGE_CONTROL_CHANGE], this value ranges from [code]0[/code] to [code]127[/code], otherwise it is [code]0[/code]. See also [member controller_value]. - The instrument of this input event. This value ranges from 0 to 127. Refer to the instrument list for [url=https://en.wikipedia.org/wiki/General_MIDI#Program_change_events]General MIDI[/url] to see a list of instruments, except that this value is 0-index, so subtract one from every number on that chart. A standard piano will have an instrument number of 0. + The instrument (also called [i]program[/i] or [i]preset[/i]) used on this MIDI message. This value ranges from [code]0[/code] to [code]127[/code]. + To see what each value means, refer to the [url=https://en.wikipedia.org/wiki/General_MIDI#Program_change_events]General MIDI's instrument list[/url]. Keep in mind that the list is off by 1 because it does not begin from 0. A value of [code]0[/code] corresponds to the acoustic grand piano. - Returns a value indicating the type of message for this MIDI signal. This is a member of the [enum MIDIMessage] enum. - For MIDI messages between 0x80 and 0xEF, only the left half of the bits are returned as this value, as the other part is the channel (ex: 0x94 becomes 0x9). For MIDI messages from 0xF0 to 0xFF, the value is returned as-is. - Notes will return [constant MIDI_MESSAGE_NOTE_ON] when activated, but they might not always return [constant MIDI_MESSAGE_NOTE_OFF] when deactivated, therefore your code should treat the input as stopped if some period of time has passed. - Some MIDI devices may send [constant MIDI_MESSAGE_NOTE_ON] with zero velocity instead of [constant MIDI_MESSAGE_NOTE_OFF]. - For more information, see the note in [member velocity] and the MIDI message status byte list chart linked above. + Represents the type of MIDI message (see the [enum MIDIMessage] enum). + For more information, see the [url=https://www.midi.org/specifications-old/item/table-2-expanded-messages-list-status-bytes]MIDI message status byte list chart[/url]. - The pitch index number of this MIDI signal. This value ranges from 0 to 127. On a piano, middle C is 60, and A440 is 69, see the "MIDI note" column of the piano key frequency chart on Wikipedia for more information. + The pitch index number of this MIDI message. This value ranges from [code]0[/code] to [code]127[/code]. + On a piano, the [b]middle C[/b] is [code]60[/code], followed by a [b]C-sharp[/b] ([code]61[/code]), then a [b]D[/b] ([code]62[/code]), and so on. Each octave is split in offsets of 12. See the "MIDI note number" column of the [url=https://en.wikipedia.org/wiki/Piano_key_frequencies]piano key frequency chart[/url] a full list. - The pressure of the MIDI signal. This value ranges from 0 to 127. For many devices, this value is always zero. + The strength of the key being pressed. This value ranges from [code]0[/code] to [code]127[/code]. + [b]Note:[/b] For many devices, this value is always [code]0[/code]. Other devices such as musical keyboards may simulate pressure by changing the [member velocity], instead. - The velocity of the MIDI signal. This value ranges from 0 to 127. For a piano, this corresponds to how quickly the key was pressed, and is rarely above about 110 in practice. - [b]Note:[/b] Some MIDI devices may send a [constant MIDI_MESSAGE_NOTE_ON] message with zero velocity and expect this to be treated the same as a [constant MIDI_MESSAGE_NOTE_OFF] message, but device implementations vary so Godot reports event data exactly as received. Depending on the hardware and the needs of the game/app, this MIDI quirk can be handled robustly with a couple lines of script (check for [constant MIDI_MESSAGE_NOTE_ON] with velocity zero). + The velocity of the MIDI message. This value ranges from [code]0[/code] to [code]127[/code]. For a musical keyboard, this corresponds to how quickly the key was pressed, and is rarely above [code]110[/code] in practice. + [b]Note:[/b] Some MIDI devices may send a [constant MIDI_MESSAGE_NOTE_ON] message with [code]0[/code] velocity and expect it to be treated the same as a [constant MIDI_MESSAGE_NOTE_OFF] message. If necessary, this can be handled with a few lines of code: + [codeblock] + func _input(event): + if event is InputEventMIDI: + if event.message == MIDI_MESSAGE_NOTE_ON and event.velocity > 0: + print("Note pressed!") + [/codeblock] diff --git a/doc/classes/MainLoop.xml b/doc/classes/MainLoop.xml index b01a3f7a0e6..b4ad26d5a39 100644 --- a/doc/classes/MainLoop.xml +++ b/doc/classes/MainLoop.xml @@ -30,6 +30,7 @@ [csharp] using Godot; + [GlobalClass] public partial class CustomMainLoop : MainLoop { private double _timeElapsed = 0; diff --git a/doc/classes/Mesh.xml b/doc/classes/Mesh.xml index 2b2dc63a336..3f8ed91ad76 100644 --- a/doc/classes/Mesh.xml +++ b/doc/classes/Mesh.xml @@ -237,16 +237,16 @@ [PackedVector2Array] for second UV coordinates. - Contains custom color channel 0. [PackedByteArray] if [code](format >> Mesh.ARRAY_FORMAT_CUSTOM0_SHIFT) & Mesh.ARRAY_FORMAT_CUSTOM_MASK[/code] is [constant ARRAY_CUSTOM_RGBA8_UNORM], [constant ARRAY_CUSTOM_RGBA8_UNORM], [constant ARRAY_CUSTOM_RG_HALF] or [constant ARRAY_CUSTOM_RGBA_HALF]. [PackedFloat32Array] otherwise. + Contains custom color channel 0. [PackedByteArray] if [code](format >> Mesh.ARRAY_FORMAT_CUSTOM0_SHIFT) & Mesh.ARRAY_FORMAT_CUSTOM_MASK[/code] is [constant ARRAY_CUSTOM_RGBA8_UNORM], [constant ARRAY_CUSTOM_RGBA8_SNORM], [constant ARRAY_CUSTOM_RG_HALF], or [constant ARRAY_CUSTOM_RGBA_HALF]. [PackedFloat32Array] otherwise. - Contains custom color channel 1. [PackedByteArray] if [code](format >> Mesh.ARRAY_FORMAT_CUSTOM1_SHIFT) & Mesh.ARRAY_FORMAT_CUSTOM_MASK[/code] is [constant ARRAY_CUSTOM_RGBA8_UNORM], [constant ARRAY_CUSTOM_RGBA8_UNORM], [constant ARRAY_CUSTOM_RG_HALF] or [constant ARRAY_CUSTOM_RGBA_HALF]. [PackedFloat32Array] otherwise. + Contains custom color channel 1. [PackedByteArray] if [code](format >> Mesh.ARRAY_FORMAT_CUSTOM1_SHIFT) & Mesh.ARRAY_FORMAT_CUSTOM_MASK[/code] is [constant ARRAY_CUSTOM_RGBA8_UNORM], [constant ARRAY_CUSTOM_RGBA8_SNORM], [constant ARRAY_CUSTOM_RG_HALF], or [constant ARRAY_CUSTOM_RGBA_HALF]. [PackedFloat32Array] otherwise. - Contains custom color channel 2. [PackedByteArray] if [code](format >> Mesh.ARRAY_FORMAT_CUSTOM2_SHIFT) & Mesh.ARRAY_FORMAT_CUSTOM_MASK[/code] is [constant ARRAY_CUSTOM_RGBA8_UNORM], [constant ARRAY_CUSTOM_RGBA8_UNORM], [constant ARRAY_CUSTOM_RG_HALF] or [constant ARRAY_CUSTOM_RGBA_HALF]. [PackedFloat32Array] otherwise. + Contains custom color channel 2. [PackedByteArray] if [code](format >> Mesh.ARRAY_FORMAT_CUSTOM2_SHIFT) & Mesh.ARRAY_FORMAT_CUSTOM_MASK[/code] is [constant ARRAY_CUSTOM_RGBA8_UNORM], [constant ARRAY_CUSTOM_RGBA8_SNORM], [constant ARRAY_CUSTOM_RG_HALF], or [constant ARRAY_CUSTOM_RGBA_HALF]. [PackedFloat32Array] otherwise. - Contains custom color channel 3. [PackedByteArray] if [code](format >> Mesh.ARRAY_FORMAT_CUSTOM3_SHIFT) & Mesh.ARRAY_FORMAT_CUSTOM_MASK[/code] is [constant ARRAY_CUSTOM_RGBA8_UNORM], [constant ARRAY_CUSTOM_RGBA8_UNORM], [constant ARRAY_CUSTOM_RG_HALF] or [constant ARRAY_CUSTOM_RGBA_HALF]. [PackedFloat32Array] otherwise. + Contains custom color channel 3. [PackedByteArray] if [code](format >> Mesh.ARRAY_FORMAT_CUSTOM3_SHIFT) & Mesh.ARRAY_FORMAT_CUSTOM_MASK[/code] is [constant ARRAY_CUSTOM_RGBA8_UNORM], [constant ARRAY_CUSTOM_RGBA8_SNORM], [constant ARRAY_CUSTOM_RG_HALF], or [constant ARRAY_CUSTOM_RGBA_HALF]. [PackedFloat32Array] otherwise. [PackedFloat32Array] or [PackedInt32Array] of bone indices. Contains either 4 or 8 numbers per vertex depending on the presence of the [constant ARRAY_FLAG_USE_8_BONE_WEIGHTS] flag. diff --git a/doc/classes/Node.xml b/doc/classes/Node.xml index d660b94ef9d..58f46310e0b 100644 --- a/doc/classes/Node.xml +++ b/doc/classes/Node.xml @@ -933,7 +933,7 @@ Set the process thread group for this node (basically, whether it receives [constant NOTIFICATION_PROCESS], [constant NOTIFICATION_PHYSICS_PROCESS], [method _process] or [method _physics_process] (and the internal versions) on the main thread or in a sub-thread. By default, the thread group is [constant PROCESS_THREAD_GROUP_INHERIT], which means that this node belongs to the same thread group as the parent node. The thread groups means that nodes in a specific thread group will process together, separate to other thread groups (depending on [member process_thread_group_order]). If the value is set is [constant PROCESS_THREAD_GROUP_SUB_THREAD], this thread group will occur on a sub thread (not the main thread), otherwise if set to [constant PROCESS_THREAD_GROUP_MAIN_THREAD] it will process on the main thread. If there is not a parent or grandparent node set to something other than inherit, the node will belong to the [i]default thread group[/i]. This default group will process on the main thread and its group order is 0. During processing in a sub-thread, accessing most functions in nodes outside the thread group is forbidden (and it will result in an error in debug mode). Use [method Object.call_deferred], [method call_thread_safe], [method call_deferred_thread_group] and the likes in order to communicate from the thread groups to the main thread (or to other thread groups). - To better understand process thread groups, the idea is that any node set to any other value than [constant PROCESS_THREAD_GROUP_INHERIT] will include any children (and grandchildren) nodes set to inherit into its process thread group. this means that the processing of all the nodes in the group will happen together, at the same time as the node including them. + To better understand process thread groups, the idea is that any node set to any other value than [constant PROCESS_THREAD_GROUP_INHERIT] will include any child (and grandchild) nodes set to inherit into its process thread group. This means that the processing of all the nodes in the group will happen together, at the same time as the node including them. Change the process thread group order. Groups with a lesser order will process before groups with a greater order. This is useful when a large amount of nodes process in sub thread and, afterwards, another group wants to collect their result in the main thread, as an example. @@ -1170,13 +1170,13 @@ Never process. Completely disables processing, ignoring [member SceneTree.paused]. This is the inverse of [constant PROCESS_MODE_ALWAYS]. - If the [member process_thread_group] property is sent to this, the node will belong to any parent (or grandparent) node that has a thread group mode that is not inherit. See [member process_thread_group] for more information. + Process this node based on the thread group mode of the first parent (or grandparent) node that has a thread group mode that is not inherit. See [member process_thread_group] for more information. - Process this node (and children nodes set to inherit) on the main thread. See [member process_thread_group] for more information. + Process this node (and child nodes set to inherit) on the main thread. See [member process_thread_group] for more information. - Process this node (and children nodes set to inherit) on a sub-thread. See [member process_thread_group] for more information. + Process this node (and child nodes set to inherit) on a sub-thread. See [member process_thread_group] for more information. @@ -1200,10 +1200,10 @@ The node will not be internal. - The node will be placed at the beginning of the parent's children list, before any non-internal sibling. + The node will be placed at the beginning of the parent's children, before any non-internal sibling. - The node will be placed at the end of the parent's children list, after any non-internal sibling. + The node will be placed at the end of the parent's children, after any non-internal sibling. diff --git a/doc/classes/Node3D.xml b/doc/classes/Node3D.xml index 0b7b982e52d..4a289f9cab2 100644 --- a/doc/classes/Node3D.xml +++ b/doc/classes/Node3D.xml @@ -49,7 +49,8 @@ - Returns the parent [Node3D], or an empty [Object] if no parent exists or parent is not of type [Node3D]. + Returns the parent [Node3D], or [code]null[/code] if no parent exists, the parent is not of type [Node3D], or [member top_level] is [code]true[/code]. + [b]Note:[/b] Calling this method is not equivalent to [code]get_parent() as Node3D[/code], which does not take [member top_level] into account. diff --git a/doc/classes/OS.xml b/doc/classes/OS.xml index ad89efb2563..b21d6ab991e 100644 --- a/doc/classes/OS.xml +++ b/doc/classes/OS.xml @@ -122,6 +122,7 @@ [b]Note:[/b] To execute a PowerShell built-in command, specify [code]powershell.exe[/code] in [param path], [code]-Command[/code] as the first argument, and the desired command as the second argument. [b]Note:[/b] To execute a Unix shell built-in command, specify shell executable name in [param path], [code]-c[/code] as the first argument, and the desired command as the second argument. [b]Note:[/b] On macOS, sandboxed applications are limited to run only embedded helper executables, specified during export. + [b]Note:[/b] On Android, system commands such as [code]dumpsys[/code] can only be run on a rooted device. @@ -185,9 +186,11 @@ Similar to [method get_cmdline_args], but this returns the user arguments (any argument passed after the double dash [code]--[/code] or double plus [code]++[/code] argument). These are left untouched by Godot for the user. [code]++[/code] can be used in situations where [code]--[/code] is intercepted by another program (such as [code]startx[/code]). For example, in the command line below, [code]--fullscreen[/code] will not be returned in [method get_cmdline_user_args] and [code]--level 1[/code] will only be returned in [method get_cmdline_user_args]: [codeblock] - godot --fullscreen -- --level 1 - # Or: - godot --fullscreen ++ --level 1 + # Godot has been executed with the following command: + # godot --fullscreen -- --level=2 --hardcore + + OS.get_cmdline_args() # Returns ["--fullscreen", "--level=2", "--hardcore"] + OS.get_cmdline_user_args() # Returns ["--level=2", "--hardcore"] [/codeblock] diff --git a/doc/classes/Object.xml b/doc/classes/Object.xml index e4f4d7682b9..97e3a799a85 100644 --- a/doc/classes/Object.xml +++ b/doc/classes/Object.xml @@ -377,7 +377,7 @@ Calls the [param method] on the object during idle time. Always returns null, [b]not[/b] the method's result. - Idle time happens mainly at the end of process and physics frames. In it, deferred calls will be run until there are none left, which means you can defer calls from other deferred calls and they'll still be run in the current idle time cycle. If not done carefully, this can result in infinite recursion without causing a stack overflow, which will hang the game similarly to an infinite loop. + Idle time happens mainly at the end of process and physics frames. In it, deferred calls will be run until there are none left, which means you can defer calls from other deferred calls and they'll still be run in the current idle time cycle. This means you should not call a method deferred from itself (or from a method called by it), as this causes infinite recursion the same way as if you had called the method directly. This method supports a variable number of arguments, so parameters can be passed as a comma separated list. [codeblocks] [gdscript] @@ -614,7 +614,7 @@ [csharp] var node = new Node2D(); node.Rotation = 1.5f; - var a = node.Get("rotation"); // a is 1.5 + var a = node.Get(Node2D.PropertyName.Rotation); // a is 1.5 [/csharp] [/codeblocks] [b]Note:[/b] In C#, [param property] must be in snake_case when referring to built-in Godot properties. Prefer using the names exposed in the [code]PropertyName[/code] class to avoid allocating a new [StringName] on each call. @@ -882,7 +882,7 @@ [/gdscript] [csharp] var node = new Node2D(); - node.Set("global_scale", new Vector2(8, 2.5)); + node.Set(Node2D.PropertyName.GlobalScale, new Vector2(8, 2.5)); GD.Print(node.GlobalScale); // Prints Vector2(8, 2.5) [/csharp] [/codeblocks] @@ -907,21 +907,21 @@ var node = Node2D.new() add_child(node) - node.rotation = 45.0 - node.set_deferred("rotation", 90.0) - print(node.rotation) # Prints 45.0 + node.rotation = 1.5 + node.set_deferred("rotation", 3.0) + print(node.rotation) # Prints 1.5 await get_tree().process_frame - print(node.rotation) # Prints 90.0 + print(node.rotation) # Prints 3.0 [/gdscript] [csharp] var node = new Node2D(); - node.Rotation = 45f; - node.SetDeferred("rotation", 90f); - GD.Print(node.Rotation); // Prints 45.0 + node.Rotation = 1.5f; + node.SetDeferred(Node2D.PropertyName.Rotation, 3f); + GD.Print(node.Rotation); // Prints 1.5 await ToSignal(GetTree(), SceneTree.SignalName.ProcessFrame); - GD.Print(node.Rotation); // Prints 90.0 + GD.Print(node.Rotation); // Prints 3.0 [/csharp] [/codeblocks] [b]Note:[/b] In C#, [param property] must be in snake_case when referring to built-in Godot properties. Prefer using the names exposed in the [code]PropertyName[/code] class to avoid allocating a new [StringName] on each call. @@ -1027,6 +1027,9 @@ Notification received when the object is about to be deleted. Can act as the deconstructor of some programming languages. + + Notification received when the object finishes hot reloading. This notification is only sent for extensions classes and derived. + Deferred connections trigger their [Callable]s on idle time (at the end of the frame), rather than instantly. diff --git a/doc/classes/PackedScene.xml b/doc/classes/PackedScene.xml index a8cfc288f34..6101b640f40 100644 --- a/doc/classes/PackedScene.xml +++ b/doc/classes/PackedScene.xml @@ -106,7 +106,7 @@ A dictionary representation of the scene contents. - Available keys include "rnames" and "variants" for resources, "node_count", "nodes", "node_paths" for nodes, "editable_instances" for base scene children overrides, "conn_count" and "conns" for signal connections, and "version" for the format style of the PackedScene. + Available keys include "rnames" and "variants" for resources, "node_count", "nodes", "node_paths" for nodes, "editable_instances" for paths to overridden nodes, "conn_count" and "conns" for signal connections, and "version" for the format style of the PackedScene. diff --git a/doc/classes/ParallaxLayer.xml b/doc/classes/ParallaxLayer.xml index 86ac2165d8b..fb92c9d85f9 100644 --- a/doc/classes/ParallaxLayer.xml +++ b/doc/classes/ParallaxLayer.xml @@ -12,9 +12,10 @@ - The ParallaxLayer's [Texture2D] repeating. Useful for creating an infinite scrolling background. If an axis is set to [code]0[/code], the [Texture2D] will not be repeated. - If the length of the viewport axis is bigger than twice the repeated axis size, it will not repeat infinitely, as the parallax layer only draws 2 instances of the texture at any given time. - [b]Note:[/b] Despite its name, the texture will not be mirrored, it will simply be repeated. + The interval, in pixels, at which the [ParallaxLayer] is drawn repeatedly. Useful for creating an infinitely scrolling background. If an axis is set to [code]0[/code], the [ParallaxLayer] will be drawn only once along that direction. + [b]Note:[/b] If you want the repetition to pixel-perfect match a [Texture2D] displayed by a child node, you should account for any scale applied to the texture when defining this interval. For example, if you use a child [Sprite2D] scaled to [code]0.5[/code] to display a 600x600 texture, and want this sprite to be repeated continuously horizontally, you should set the mirroring to [code]Vector2(300, 0)[/code]. + [b]Note:[/b] If the length of the viewport axis is bigger than twice the repeated axis size, it will not repeat infinitely, as the parallax layer only draws 2 instances of the layer at any given time. The visibility window is calculated from the parent [ParallaxBackground]'s position, not the layer's own position. So, if you use mirroring, [b]do not[/b] change the [ParallaxLayer] position relative to its parent. Instead, if you need to adjust the background's position, set the [member CanvasLayer.offset] property in the parent [ParallaxBackground]. + [b]Note:[/b] Despite the name, the layer will not be mirrored, it will only be repeated. The ParallaxLayer's offset relative to the parent ParallaxBackground's [member ParallaxBackground.scroll_offset]. diff --git a/doc/classes/PhysicalBone3D.xml b/doc/classes/PhysicalBone3D.xml index b69fb7050e7..282c0f2cb03 100644 --- a/doc/classes/PhysicalBone3D.xml +++ b/doc/classes/PhysicalBone3D.xml @@ -61,6 +61,7 @@ The body's bounciness. Values range from [code]0[/code] (no bounce) to [code]1[/code] (full bounciness). + [b]Note:[/b] Even with [member bounce] set to [code]1.0[/code], some energy will be lost over time due to linear and angular damping. To have a [PhysicalBone3D] that preserves all its energy over time, set [member bounce] to [code]1.0[/code], [member linear_damp_mode] to [constant DAMP_MODE_REPLACE], [member linear_damp] to [code]0.0[/code], [member angular_damp_mode] to [constant DAMP_MODE_REPLACE], and [member angular_damp] to [code]0.0[/code]. If [code]true[/code], the body is deactivated when there is no movement, so it will not take part in the simulation until it is awakened by an external force. diff --git a/doc/classes/PhysicsMaterial.xml b/doc/classes/PhysicsMaterial.xml index 30c24007753..1601a1040e3 100644 --- a/doc/classes/PhysicsMaterial.xml +++ b/doc/classes/PhysicsMaterial.xml @@ -14,6 +14,7 @@ The body's bounciness. Values range from [code]0[/code] (no bounce) to [code]1[/code] (full bounciness). + [b]Note:[/b] Even with [member bounce] set to [code]1.0[/code], some energy will be lost over time due to linear and angular damping. To have a [PhysicsBody3D] that preserves all its energy over time, set [member bounce] to [code]1.0[/code], the body's linear damp mode to [b]Replace[/b] (if applicable), its linear damp to [code]0.0[/code], its angular damp mode to [b]Replace[/b] (if applicable), and its angular damp to [code]0.0[/code]. The body's friction. Values range from [code]0[/code] (frictionless) to [code]1[/code] (maximum friction). diff --git a/doc/classes/ProjectSettings.xml b/doc/classes/ProjectSettings.xml index 94a9e1864f9..b29c9458067 100644 --- a/doc/classes/ProjectSettings.xml +++ b/doc/classes/ProjectSettings.xml @@ -793,15 +793,18 @@ Main window initial position (in virtual desktop coordinates), this setting is used only if [member display/window/size/initial_position_type] is set to "Absolute" ([code]0[/code]). + [b]Note:[/b] This setting only affects the exported project, or when the project is run from the command line. In the editor, the value of [member EditorSettings.run/window_placement/rect_custom_position] is used instead. Main window initial position. [code]0[/code] - "Absolute", [member display/window/size/initial_position] is used to set window position. [code]1[/code] - "Primary Screen Center". [code]2[/code] - "Other Screen Center", [member display/window/size/initial_screen] is used to set the screen. + [b]Note:[/b] This setting only affects the exported project, or when the project is run from the command line. In the editor, the value of [member EditorSettings.run/window_placement/rect] is used instead. Main window initial screen, this setting is used only if [member display/window/size/initial_position_type] is set to "Other Screen Center" ([code]2[/code]). + [b]Note:[/b] This setting only affects the exported project, or when the project is run from the command line. In the editor, the value of [member EditorSettings.run/window_placement/screen] is used instead. Main window mode. See [enum DisplayServer.WindowMode] for possible values and how each mode behaves. @@ -875,6 +878,9 @@ If [code]true[/code], text resources are converted to a binary format on export. This decreases file sizes and speeds up loading slightly. [b]Note:[/b] If [member editor/export/convert_text_resources_to_binary] is [code]true[/code], [method @GDScript.load] will not be able to return the converted files in an exported project. Some file paths within the exported PCK will also change, such as [code]project.godot[/code] becoming [code]project.binary[/code]. If you rely on run-time loading of files present within the PCK, set [member editor/export/convert_text_resources_to_binary] to [code]false[/code]. + + The maximum width to use when importing textures as an atlas. The value will be rounded to the nearest power of two when used. Use this to prevent imported textures from growing too large in the other direction. + diff --git a/doc/classes/Quaternion.xml b/doc/classes/Quaternion.xml index 61bc4f47204..46533e8a742 100644 --- a/doc/classes/Quaternion.xml +++ b/doc/classes/Quaternion.xml @@ -4,19 +4,24 @@ A unit quaternion used for representing 3D rotations. - Quaternions are similar to [Basis], which implements the matrix representation of rotations. Unlike [Basis], which stores rotation, scale, and shearing, quaternions only store rotation. - Quaternions can be parametrized using both an axis-angle pair or Euler angles. Due to their compactness and the way they are stored in memory, certain operations (obtaining axis-angle and performing SLERP, in particular) are more efficient and robust against floating-point errors. - [b]Note:[/b] Quaternions need to be normalized before being used for rotation. + The [Quaternion] built-in [Variant] type is a 4D data structure that represents rotation in the form of a [url=https://en.wikipedia.org/wiki/Quaternions_and_spatial_rotation]Hamilton convention quaternion[/url]. Compared to the [Basis] type which can store both rotation and scale, quaternions can [i]only[/i] store rotation. + A [Quaternion] is composed by 4 floating-point components: [member w], [member x], [member y], and [member z]. These components are very compact in memory, and because of this some operations are more efficient and less likely to cause floating-point errors. Methods such as [method get_angle], [method get_axis], and [method slerp] are faster than their [Basis] counterparts. + For a great introduction to quaternions, see [url=https://www.youtube.com/watch?v=d4EgbgTm0Bg]this video by 3Blue1Brown[/url]. You do not need to know the math behind quaternions, as Godot provides several helper methods that handle it for you. These include [method slerp] and [method spherical_cubic_interpolate], as well as the [code]*[/code] operator. + [b]Note:[/b] Quaternions must be normalized before being used for rotation (see [method normalized]). + [b]Note:[/b] Similarly to [Vector2] and [Vector3], the components of a quaternion use 32-bit precision by default, unlike [float] which is always 64-bit. If double precision is needed, compile the engine with the option [code]precision=double[/code]. + https://www.youtube.com/watch?v=d4EgbgTm0Bg + https://quaternions.online/ $DOCS_URL/tutorials/3d/using_transforms.html#interpolating-with-quaternions https://godotengine.org/asset-library/asset/678 + https://iwatake2222.github.io/rotation_master/rotation_master.html - Constructs a default-initialized quaternion with all components set to [code]0[/code]. + Constructs a [Quaternion] identical to the [constant IDENTITY]. @@ -31,7 +36,7 @@ - Constructs a quaternion representing the shortest arc between two points on the surface of a sphere with a radius of [code]1.0[/code]. + Constructs a [Quaternion] representing the shortest arc between [param arc_from] and [param arc_to]. These can be imagined as two points intersecting a sphere's surface, with a radius of [code]1.0[/code]. @@ -39,14 +44,15 @@ - Constructs a quaternion that will rotate around the given axis by the specified angle. The axis must be a normalized vector. + Constructs a [Quaternion] representing rotation around the [param axis] by the given [param angle], in radians. The axis must be a normalized vector. - Constructs a quaternion from the given [Basis]. + Constructs a [Quaternion] from the given rotation [Basis]. + This constructor is faster than [method Basis.get_rotation_quaternion], but the given basis must be [i]orthonormalized[/i] (see [method Basis.orthonormalized]). Otherwise, the constructor fails and returns [constant IDENTITY]. @@ -56,7 +62,8 @@ - Constructs a quaternion defined by the given values. + Constructs a [Quaternion] defined by the given values. + [b]Note:[/b] Only normalized quaternions represent rotation; if these values are not normalized, the new [Quaternion] will not be a valid rotation. @@ -73,7 +80,8 @@ - Returns the dot product of two quaternions. + Returns the dot product between this quaternion and [param with]. + This is equivalent to [code](quat.x * with.x) + (quat.y * with.y) + (quat.z * with.z) + (quat.w * with.w)[/code]. @@ -86,7 +94,7 @@ - Constructs a Quaternion from Euler angles in YXZ rotation order. + Constructs a new [Quaternion] from the given [Vector3] of [url=https://en.wikipedia.org/wiki/Euler_angles]Euler angles[/url], in radians. This method always uses the YXZ convention ([constant EULER_ORDER_YXZ]). @@ -106,13 +114,14 @@ - Returns the quaternion's rotation in the form of Euler angles. The Euler order depends on the [param order] parameter, for example using the YXZ convention: since this method decomposes, first Z, then X, and Y last. See the [enum EulerOrder] enum for possible values. The returned vector contains the rotation angles in the format (X angle, Y angle, Z angle). + Returns this quaternion's rotation as a [Vector3] of [url=https://en.wikipedia.org/wiki/Euler_angles]Euler angles[/url], in radians. + The order of each consecutive rotation can be changed with [param order] (see [enum EulerOrder] constants). By default, the YXZ convention is used ([constant EULER_ORDER_YXZ]): Z (roll) is calculated first, then X (pitch), and lastly Y (yaw). When using the opposite method [method from_euler], this order is reversed. - Returns the inverse of the quaternion. + Returns the inverse version of this quaternion, inverting the sign of every component except [member w]. @@ -131,31 +140,32 @@ - Returns whether the quaternion is normalized or not. + Returns [code]true[/code] if this quaternion is normalized. See also [method normalized]. - Returns the length of the quaternion. + Returns this quaternion's length, also called magnitude. - Returns the length of the quaternion, squared. + Returns this quaternion's length, squared. + [b]Note:[/b] This method is faster than [method length], so prefer it if you only need to compare quaternion lengths. - Returns the logarithm of this quaternion. The vector part of the result is the rotation axis of this quaternion multiplied by its rotation angle, the real part of the result is zero. + Returns the logarithm of this quaternion. Multiplies this quaternion's rotation axis by its rotation angle, and stores the result in the returned quaternion's vector part ([member x], [member y], and [member z]). The returned quaternion's real part ([member w]) is always [code]0.0[/code]. - Returns a copy of the quaternion, normalized to unit length. + Returns a copy of this quaternion, normalized so that its length is [code]1.0[/code]. See also [method is_normalized]. @@ -163,8 +173,7 @@ - Returns the result of the spherical linear interpolation between this quaternion and [param to] by amount [param weight]. - [b]Note:[/b] Both quaternions must be normalized. + Performs a spherical-linear interpolation with the [param to] quaternion, given a [param weight] and returns the result. Both this quaternion and [param to] must be normalized. @@ -172,7 +181,7 @@ - Returns the result of the spherical linear interpolation between this quaternion and [param to] by amount [param weight], but without checking if the rotation path is not bigger than 90 degrees. + Performs a spherical-linear interpolation with the [param to] quaternion, given a [param weight] and returns the result. Unlike [method slerp], this method does not check if the rotation path is smaller than 90 degrees. Both this quaternion and [param to] must be normalized. @@ -202,25 +211,26 @@ - W component of the quaternion (real part). - Quaternion components should usually not be manipulated directly. + W component of the quaternion. This is the "real" part. + [b]Note:[/b] Quaternion components should usually not be manipulated directly. - X component of the quaternion (imaginary [code]i[/code] axis part). - Quaternion components should usually not be manipulated directly. + X component of the quaternion. This is the value along the "imaginary" [code]i[/code] axis. + [b]Note:[/b] Quaternion components should usually not be manipulated directly. - Y component of the quaternion (imaginary [code]j[/code] axis part). - Quaternion components should usually not be manipulated directly. + Y component of the quaternion. This is the value along the "imaginary" [code]j[/code] axis. + [b]Note:[/b] Quaternion components should usually not be manipulated directly. - Z component of the quaternion (imaginary [code]k[/code] axis part). - Quaternion components should usually not be manipulated directly. + Z component of the quaternion. This is the value along the "imaginary" [code]k[/code] axis. + [b]Note:[/b] Quaternion components should usually not be manipulated directly. - The identity quaternion, representing no rotation. Equivalent to an identity [Basis] matrix. If a vector is transformed by an identity quaternion, it will not change. + The identity quaternion, representing no rotation. This has the same rotation as [constant Basis.IDENTITY]. + If a [Vector3] is rotated (multiplied) by this quaternion, it does not change. @@ -228,7 +238,7 @@ - Returns [code]true[/code] if the quaternions are not equal. + Returns [code]true[/code] if the components of both quaternions are not exactly equal. [b]Note:[/b] Due to floating-point precision errors, consider using [method is_equal_approx] instead, which is more reliable. @@ -236,63 +246,69 @@ - Composes these two quaternions by multiplying them together. This has the effect of rotating the second quaternion (the child) by the first quaternion (the parent). + Composes (multiplies) two quaternions. This rotates the [param right] quaternion (the child) by this quaternion (the parent). - Rotates (multiplies) the [Vector3] by the given [Quaternion]. + Rotates (multiplies) the [param right] vector by this quaternion, returning a [Vector3]. - Multiplies each component of the [Quaternion] by the given value. This operation is not meaningful on its own, but it can be used as a part of a larger expression. + Multiplies each component of the [Quaternion] by the right [float] value. + This operation is not meaningful on its own, but it can be used as a part of a larger expression. - Multiplies each component of the [Quaternion] by the given value. This operation is not meaningful on its own, but it can be used as a part of a larger expression. + Multiplies each component of the [Quaternion] by the right [int] value. + This operation is not meaningful on its own, but it can be used as a part of a larger expression. - Adds each component of the left [Quaternion] to the right [Quaternion]. This operation is not meaningful on its own, but it can be used as a part of a larger expression, such as approximating an intermediate rotation between two nearby rotations. + Adds each component of the left [Quaternion] to the right [Quaternion]. + This operation is not meaningful on its own, but it can be used as a part of a larger expression, such as approximating an intermediate rotation between two nearby rotations. - Subtracts each component of the left [Quaternion] by the right [Quaternion]. This operation is not meaningful on its own, but it can be used as a part of a larger expression. + Subtracts each component of the left [Quaternion] by the right [Quaternion]. + This operation is not meaningful on its own, but it can be used as a part of a larger expression. - Divides each component of the [Quaternion] by the given value. This operation is not meaningful on its own, but it can be used as a part of a larger expression. + Divides each component of the [Quaternion] by the right [float] value. + This operation is not meaningful on its own, but it can be used as a part of a larger expression. - Divides each component of the [Quaternion] by the given value. This operation is not meaningful on its own, but it can be used as a part of a larger expression. + Divides each component of the [Quaternion] by the right [int] value. + This operation is not meaningful on its own, but it can be used as a part of a larger expression. - Returns [code]true[/code] if the quaternions are exactly equal. + Returns [code]true[/code] if the components of both quaternions are exactly equal. [b]Note:[/b] Due to floating-point precision errors, consider using [method is_equal_approx] instead, which is more reliable. @@ -300,7 +316,8 @@ - Access quaternion components using their index. [code]q[0][/code] is equivalent to [code]q.x[/code], [code]q[1][/code] is equivalent to [code]q.y[/code], [code]q[2][/code] is equivalent to [code]q.z[/code], and [code]q[3][/code] is equivalent to [code]q.w[/code]. + Accesses each component of this quaternion by their index. + Index [code]0[/code] is the same as [member x], index [code]1[/code] is the same as [member y], index [code]2[/code] is the same as [member z], and index [code]3[/code] is the same as [member w]. @@ -312,7 +329,7 @@ - Returns the negative value of the [Quaternion]. This is the same as writing [code]Quaternion(-q.x, -q.y, -q.z, -q.w)[/code]. This operation results in a quaternion that represents the same rotation. + Returns the negative value of the [Quaternion]. This is the same as multiplying all components by [code]-1[/code]. This operation results in a quaternion that represents the same rotation. diff --git a/doc/classes/RichTextLabel.xml b/doc/classes/RichTextLabel.xml index 85dea1485a0..ef61b8a7176 100644 --- a/doc/classes/RichTextLabel.xml +++ b/doc/classes/RichTextLabel.xml @@ -69,7 +69,7 @@ - Returns the line number of the character position provided. + Returns the line number of the character position provided. Line and character numbers are both zero-indexed. [b]Note:[/b] If [member threaded] is enabled, this method returns a value for the loaded part of the document. Use [method is_ready] or [signal finished] to determine whether document is fully loaded. @@ -77,7 +77,7 @@ - Returns the paragraph number of the character position provided. + Returns the paragraph number of the character position provided. Paragraph and character numbers are both zero-indexed. [b]Note:[/b] If [member threaded] is enabled, this method returns a value for the loaded part of the document. Use [method is_ready] or [signal finished] to determine whether document is fully loaded. @@ -430,6 +430,7 @@ Adds a meta tag to the tag stack. Similar to the BBCode [code skip-lint][url=something]{text}[/url][/code], but supports non-[String] metadata types. + [b]Note:[/b] Meta tags do nothing by default when clicked. To assign behavior when clicked, connect [signal meta_clicked] to a function that is called when the meta tag is clicked. @@ -616,7 +617,7 @@ Language code used for line-breaking and text shaping algorithms, if left empty current locale is used instead. - If [code]true[/code], the label underlines meta tags such as [code skip-lint][url]{text}[/url][/code]. + If [code]true[/code], the label underlines meta tags such as [code skip-lint][url]{text}[/url][/code]. These tags can call a function when clicked if [signal meta_clicked] is connected to a function. The delay after which the loading progress bar is displayed, in milliseconds. Set to [code]-1[/code] to disable progress bar entirely. @@ -674,7 +675,17 @@ - Triggered when the user clicks on content between meta tags. If the meta is defined in text, e.g. [code skip-lint][url={"data"="hi"}]hi[/url][/code], then the parameter for this signal will be a [String] type. If a particular type or an object is desired, the [method push_meta] method must be used to manually insert the data into the tag stack. + Triggered when the user clicks on content between meta (URL) tags. If the meta is defined in BBCode, e.g. [code skip-lint][url={"key": "value"}]Text[/url][/code], then the parameter for this signal will always be a [String] type. If a particular type or an object is desired, the [method push_meta] method must be used to manually insert the data into the tag stack. Alternatively, you can convert the [String] input to the desired type based on its contents (such as calling [method JSON.parse] on it). + For example, the following method can be connected to [signal meta_clicked] to open clicked URLs using the user's default web browser: + [codeblocks] + [gdscript] + # This assumes RichTextLabel's `meta_clicked` signal was connected to + # the function below using the signal connection dialog. + func _richtextlabel_on_meta_clicked(meta): + # `meta` is of Variant type, so convert it to a String to avoid script errors at run-time. + OS.shell_open(str(meta)) + [/gdscript] + [/codeblocks] diff --git a/doc/classes/Skeleton3D.xml b/doc/classes/Skeleton3D.xml index 2a629abc0db..f014f0dad2f 100644 --- a/doc/classes/Skeleton3D.xml +++ b/doc/classes/Skeleton3D.xml @@ -62,7 +62,7 @@ - Returns an array containing the bone indexes of all the children node of the passed in bone, [param bone_idx]. + Returns an array containing the bone indexes of all the child node of the passed in bone, [param bone_idx]. diff --git a/doc/classes/SpriteBase3D.xml b/doc/classes/SpriteBase3D.xml index a87608bb720..e498bccad1a 100644 --- a/doc/classes/SpriteBase3D.xml +++ b/doc/classes/SpriteBase3D.xml @@ -75,7 +75,8 @@ If [code]true[/code], texture is flipped vertically. - A color value used to [i]multiply[/i] the texture's colors. Can be used for mood-coloring or to simulate the color of light. + A color value used to [i]multiply[/i] the texture's colors. Can be used for mood-coloring or to simulate the color of ambient light. + [b]Note:[/b] Unlike [member CanvasItem.modulate] for 2D, colors with values above [code]1.0[/code] (overbright) are not supported. [b]Note:[/b] If a [member GeometryInstance3D.material_override] is defined on the [SpriteBase3D], the material override must be configured to take vertex colors into account for albedo. Otherwise, the color defined in [member modulate] will be ignored. For a [BaseMaterial3D], [member BaseMaterial3D.vertex_color_use_as_albedo] must be [code]true[/code]. For a [ShaderMaterial], [code]ALBEDO *= COLOR.rgb;[/code] must be inserted in the shader's [code]fragment()[/code] function. @@ -97,6 +98,7 @@ Filter flags for the texture. See [enum BaseMaterial3D.TextureFilter] for options. + [b]Note:[/b] Linear filtering may cause artifacts around the edges, which are especially noticeable on opaque textures. To prevent this, use textures with transparent or identical colors around the edges. If [code]true[/code], the texture's transparency and the opacity are used to make those parts of the sprite invisible. diff --git a/doc/classes/String.xml b/doc/classes/String.xml index e1b60b1656f..66a01a702a3 100644 --- a/doc/classes/String.xml +++ b/doc/classes/String.xml @@ -651,8 +651,8 @@ [codeblocks] [gdscript] var n = -5.2e8 - print(n) # Prints -520000000 - print(String.NumScientific(n)) # Prints -5.2e+08 + print(n) # Prints -520000000 + print(String.num_scientific(n)) # Prints -5.2e+08 [/gdscript] [csharp] // This method is not implemented in C#. diff --git a/doc/classes/TabContainer.xml b/doc/classes/TabContainer.xml index b3a92645690..aba50b9c8c3 100644 --- a/doc/classes/TabContainer.xml +++ b/doc/classes/TabContainer.xml @@ -201,7 +201,7 @@ If [code]true[/code], tabs are visible. If [code]false[/code], tabs' content and titles are hidden. - 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. + If [code]true[/code], child [Control] nodes that are hidden have their minimum size take into account in the total, instead of only the currently visible one. diff --git a/doc/classes/Texture3D.xml b/doc/classes/Texture3D.xml index 6f054a8e0d7..2b1bc026c2c 100644 --- a/doc/classes/Texture3D.xml +++ b/doc/classes/Texture3D.xml @@ -1,7 +1,7 @@ - Base class for 3-dimensionnal textures. + Base class for 3-dimensional textures. Base class for [ImageTexture3D] and [CompressedTexture3D]. Cannot be used directly, but contains all the functions necessary for accessing the derived resource types. [Texture3D] is the base class for all 3-dimensional texture types. See also [TextureLayered]. diff --git a/doc/classes/Transform3D.xml b/doc/classes/Transform3D.xml index 91ece6943ce..2547118ebb8 100644 --- a/doc/classes/Transform3D.xml +++ b/doc/classes/Transform3D.xml @@ -4,8 +4,9 @@ A 3×4 matrix representing a 3D transformation. - A 3×4 matrix (3 rows, 4 columns) used for 3D linear transformations. It can represent transformations such as translation, rotation, and scaling. It consists of a [member basis] (first 3 columns) and a [Vector3] for the [member origin] (last column). + The [Transform3D] built-in [Variant] type is a 3×4 matrix representing a transformation in 3D space. It contains a [Basis], which on its own can represent rotation, scale, and shear. Additionally, combined with its own [member origin], the transform can also represent a translation. For a general introduction, see the [url=$DOCS_URL/tutorials/math/matrices_and_transforms.html]Matrices and transforms[/url] tutorial. + [b]Note:[/b] Godot uses a [url=https://en.wikipedia.org/wiki/Right-hand_rule]right-handed coordinate system[/url], which is a common standard. For directions, the convention for built-in types like [Camera3D] is for -Z to point forward (+X is right, +Y is up, and +Z is back). Other objects may use different direction conventions. For more information, see the [url=$DOCS_URL/tutorials/assets_pipeline/importing_scenes.html#d-asset-direction-conventions]Importing 3D Scenes[/url] tutorial. $DOCS_URL/tutorials/math/index.html @@ -19,7 +20,7 @@ - Constructs a default-initialized [Transform3D] set to [constant IDENTITY]. + Constructs a [Transform3D] identical to the [constant IDENTITY]. @@ -34,14 +35,14 @@ - Constructs a Transform3D from a [Basis] and [Vector3]. + Constructs a [Transform3D] from a [Basis] and [Vector3]. - Constructs a Transform3D from a [Projection] by trimming the last row of the projection matrix ([code]from.x.w[/code], [code]from.y.w[/code], [code]from.z.w[/code], and [code]from.w.w[/code] are not copied over). + Constructs a [Transform3D] from a [Projection]. Because [Transform3D] is a 3×4 matrix and [Projection] is a 4×4 matrix, this operation trims the last row of the projection matrix ([code]from.x.w[/code], [code]from.y.w[/code], [code]from.z.w[/code], and [code]from.w.w[/code] are not included in the new transform). @@ -51,7 +52,8 @@ - Constructs a Transform3D from four [Vector3] values (matrix columns). Each axis corresponds to local basis vectors (some of which may be scaled). + Constructs a [Transform3D] from four [Vector3] values (also called matrix columns). + The first three arguments are the [member basis]'s axes ([member Basis.x], [member Basis.y], and [member Basis.z]). @@ -59,7 +61,8 @@ - Returns the inverse of the transform, under the assumption that the basis is invertible (must have non-zero determinant). + Returns the inverted version of this transform. Unlike [method inverse], this method works with almost any [member basis], including non-uniform ones, but is slower. See also [method Basis.inverse]. + [b]Note:[/b] For this method to return correctly, the transform's [member basis] needs to have a determinant that is not exactly [code]0[/code] (see [method Basis.determinant]). @@ -67,13 +70,15 @@ - Returns a transform interpolated between this transform and another by a given [param weight] (on the range of 0.0 to 1.0). + Returns the result of the linear interpolation between this transform and [param xform] by the given [param weight]. + The [param weight] should be between [code]0.0[/code] and [code]1.0[/code] (inclusive). Values outside this range are allowed and can be used to perform [i]extrapolation[/i] instead. - Returns the inverse of the transform, under the assumption that the transformation basis is orthonormal (i.e. rotation/reflection is fine, scaling/skew is not). Use [method affine_inverse] for non-orthonormal transforms (e.g. with scaling). + Returns the inverted version of this transform. See also [method Basis.inverse]. + [b]Note:[/b] For this method to return correctly, the transform's [member basis] needs to be [i]orthonormal[/i] (see [method Basis.orthonormalized]). That means, the basis should only represent a rotation. If it does not, use [method affine_inverse] instead. @@ -95,7 +100,7 @@ - Returns a copy of the transform rotated such that the forward axis (-Z) points towards the [param target] position. + Returns a copy of this transform rotated so that the forward axis (-Z) points towards the [param target] position. The up axis (+Y) points as close to the [param up] vector as possible while staying perpendicular to the forward axis. The resulting transform is orthonormalized. The existing rotation, scale, and skew information from the original transform is discarded. The [param target] and [param up] vectors cannot be zero, cannot be parallel to each other, and are defined in global/parent space. If [param use_model_front] is [code]true[/code], the +Z axis (asset front) is treated as forward (implies +X is left) and points toward the [param target] position. By default, the -Z axis (camera forward) is treated as forward (implies +X is right). @@ -103,7 +108,7 @@ - Returns the transform with the basis orthogonal (90 degrees), and normalized axis vectors (scale of 1 or -1). + Returns a copy of this transform with its [member basis] orthonormalized. An orthonormal basis is both [i]orthogonal[/i] (the axes are perpendicular to each other) and [i]normalized[/i] (the axes have a length of [code]1[/code]), which also means it can only represent rotation. See also [method Basis.orthonormalized]. @@ -111,7 +116,7 @@ - Returns a copy of the transform rotated around the given [param axis] by the given [param angle] (in radians). + Returns a copy of this transform rotated around the given [param axis] by the given [param angle] (in radians). The [param axis] must be a normalized vector. This method is an optimized version of multiplying the given transform [code]X[/code] with a corresponding rotation transform [code]R[/code] from the left, i.e., [code]R * X[/code]. This can be seen as transforming with respect to the global/parent frame. @@ -122,7 +127,7 @@ - Returns a copy of the transform rotated around the given [param axis] by the given [param angle] (in radians). + Returns a copy of this transform rotated around the given [param axis] by the given [param angle] (in radians). The [param axis] must be a normalized vector. This method is an optimized version of multiplying the given transform [code]X[/code] with a corresponding rotation transform [code]R[/code] from the right, i.e., [code]X * R[/code]. This can be seen as transforming with respect to the local frame. @@ -132,7 +137,7 @@ - Returns a copy of the transform scaled by the given [param scale] factor. + Returns a copy of this transform scaled by the given [param scale] factor. This method is an optimized version of multiplying the given transform [code]X[/code] with a corresponding scaling transform [code]S[/code] from the left, i.e., [code]S * X[/code]. This can be seen as transforming with respect to the global/parent frame. @@ -141,7 +146,7 @@ - Returns a copy of the transform scaled by the given [param scale] factor. + Returns a copy of this transform scaled by the given [param scale] factor. This method is an optimized version of multiplying the given transform [code]X[/code] with a corresponding scaling transform [code]S[/code] from the right, i.e., [code]X * S[/code]. This can be seen as transforming with respect to the local frame. @@ -150,7 +155,7 @@ - Returns a copy of the transform translated by the given [param offset]. + Returns a copy of this transform translated by the given [param offset]. This method is an optimized version of multiplying the given transform [code]X[/code] with a corresponding translation transform [code]T[/code] from the left, i.e., [code]T * X[/code]. This can be seen as transforming with respect to the global/parent frame. @@ -159,7 +164,7 @@ - Returns a copy of the transform translated by the given [param offset]. + Returns a copy of this transform translated by the given [param offset]. This method is an optimized version of multiplying the given transform [code]X[/code] with a corresponding translation transform [code]T[/code] from the right, i.e., [code]X * T[/code]. This can be seen as transforming with respect to the local frame. @@ -167,24 +172,25 @@ - The basis is a matrix containing 3 [Vector3] as its columns: X axis, Y axis, and Z axis. These vectors can be interpreted as the basis vectors of local coordinate system traveling with the object. + The [Basis] of this transform. It is composed by 3 axes ([member Basis.x], [member Basis.y], and [member Basis.z]). Together, these represent the transform's rotation, scale, and shear. - The translation offset of the transform (column 3, the fourth column). Equivalent to array index [code]3[/code]. + The translation offset of this transform. In 3D space, this can be seen as the position. - [Transform3D] with no translation, rotation or scaling applied. When applied to other data structures, [constant IDENTITY] performs no transformation. + A transform with no translation, no rotation, and its scale being [code]1[/code]. Its [member basis] is equal to [constant Basis.IDENTITY]. + When multiplied by another [Variant] such as [AABB] or another [Transform3D], no transformation occurs. - [Transform3D] with mirroring applied perpendicular to the YZ plane. + [Transform3D] with mirroring applied perpendicular to the YZ plane. Its [member basis] is equal to [constant Basis.FLIP_X]. - [Transform3D] with mirroring applied perpendicular to the XZ plane. + [Transform3D] with mirroring applied perpendicular to the XZ plane. Its [member basis] is equal to [constant Basis.FLIP_Y]. - [Transform3D] with mirroring applied perpendicular to the XY plane. + [Transform3D] with mirroring applied perpendicular to the XY plane. Its [member basis] is equal to [constant Basis.FLIP_Z]. @@ -192,7 +198,7 @@ - Returns [code]true[/code] if the transforms are not equal. + Returns [code]true[/code] if the components of both transforms are not equal. [b]Note:[/b] Due to floating-point precision errors, consider using [method is_equal_approx] instead, which is more reliable. @@ -200,56 +206,62 @@ - Transforms (multiplies) the [AABB] by the given [Transform3D] matrix. + Transforms (multiplies) the [AABB] by this transformation matrix. - Transforms (multiplies) each element of the [Vector3] array by the given [Transform3D] matrix. + Transforms (multiplies) every [Vector3] element of the given [PackedVector3Array] by this transformation matrix. + On larger arrays, this operation is much faster than transforming each [Vector3] individually. - Transforms (multiplies) the [Plane] by the given [Transform3D] transformation matrix. + Transforms (multiplies) the [Plane] by this transformation matrix. - Composes these two transformation matrices by multiplying them together. This has the effect of transforming the second transform (the child) by the first transform (the parent). + Transforms (multiplies) this transform by the [param right] transform. + This is the operation performed between parent and child [Node3D]s. + [b]Note:[/b] If you need to only modify one attribute of this transform, consider using one of the following methods, instead: + - For translation, see [method translated] or [method translated_local]. + - For rotation, see [method rotated] or [method rotated_local]. + - For scale, see [method scaled] or [method scaled_local]. - Transforms (multiplies) the [Vector3] by the given [Transform3D] matrix. + Transforms (multiplies) the [Vector3] by this transformation matrix. - This operator multiplies all components of the [Transform3D], including the [member origin] vector, which scales it uniformly. + Multiplies all components of the [Transform3D] by the given [float], including the [member origin]. This affects the transform's scale uniformly, scaling the [member basis]. - This operator multiplies all components of the [Transform3D], including the [member origin] vector, which scales it uniformly. + Multiplies all components of the [Transform3D] by the given [int], including the [member origin]. This affects the transform's scale uniformly, scaling the [member basis]. - Returns [code]true[/code] if the transforms are exactly equal. + Returns [code]true[/code] if the components of both transforms are exactly equal. [b]Note:[/b] Due to floating-point precision errors, consider using [method is_equal_approx] instead, which is more reliable. diff --git a/doc/classes/Tween.xml b/doc/classes/Tween.xml index b265f8ba11e..ac16bebecb8 100644 --- a/doc/classes/Tween.xml +++ b/doc/classes/Tween.xml @@ -237,6 +237,12 @@ If [param parallel] is [code]true[/code], the [Tweener]s appended after this method will by default run simultaneously, as opposed to sequentially. + [b]Note:[/b] Just like with [method parallel], the tweener added right before this method will also be part of the parallel step. + [codeblock] + tween.tween_property(self, "position", Vector2(300, 0), 0.5) + tween.set_parallel() + tween.tween_property(self, "modulate", Color.GREEN, 0.5) # Runs together with the position tweener. + [/codeblock] diff --git a/doc/classes/Viewport.xml b/doc/classes/Viewport.xml index b6a407e0421..58c5fe0c54b 100644 --- a/doc/classes/Viewport.xml +++ b/doc/classes/Viewport.xml @@ -4,7 +4,7 @@ Abstract base class for viewports. Encapsulates drawing and interaction with a game world. - A Viewport creates a different view into the screen, or a sub-view inside another viewport. Children 2D Nodes will display on it, and children Camera3D 3D nodes will render on it too. + A [Viewport] creates a different view into the screen, or a sub-view inside another viewport. Child 2D nodes will display on it, and child Camera3D 3D nodes will render on it too. Optionally, a viewport can have its own 2D or 3D world, so it doesn't share what it draws with other viewports. Viewports can also choose to be audio listeners, so they generate positional audio depending on a 2D or 3D camera child of it. Also, viewports can be assigned to different screens in case the devices have multiple screens. diff --git a/doc/classes/VisualShaderNodeCubemap.xml b/doc/classes/VisualShaderNodeCubemap.xml index 8fc98e24cc8..4e6cf2120a8 100644 --- a/doc/classes/VisualShaderNodeCubemap.xml +++ b/doc/classes/VisualShaderNodeCubemap.xml @@ -33,7 +33,7 @@ No hints are added to the uniform declaration. - Adds [code]hint_albedo[/code] as hint to the uniform declaration for proper sRGB to linear conversion. + Adds [code]source_color[/code] as hint to the uniform declaration for proper sRGB to linear conversion. Adds [code]hint_normal[/code] as hint to the uniform declaration, which internally converts the texture for proper usage as normal map. diff --git a/doc/classes/VisualShaderNodeTexture.xml b/doc/classes/VisualShaderNodeTexture.xml index 5b38683eba2..eda09573adb 100644 --- a/doc/classes/VisualShaderNodeTexture.xml +++ b/doc/classes/VisualShaderNodeTexture.xml @@ -51,7 +51,7 @@ No hints are added to the uniform declaration. - Adds [code]hint_albedo[/code] as hint to the uniform declaration for proper sRGB to linear conversion. + Adds [code]source_color[/code] as hint to the uniform declaration for proper sRGB to linear conversion. Adds [code]hint_normal[/code] as hint to the uniform declaration, which internally converts the texture for proper usage as normal map. diff --git a/doc/classes/Window.xml b/doc/classes/Window.xml index 5f6b1960b78..243c246fd7d 100644 --- a/doc/classes/Window.xml +++ b/doc/classes/Window.xml @@ -97,7 +97,7 @@ - Returns the combined minimum size from the child [Control] nodes of the window. Use [method child_controls_changed] to update it when children nodes have changed. + Returns the combined minimum size from the child [Control] nodes of the window. Use [method child_controls_changed] to update it when child nodes have changed. The value returned by this method can be overridden with [method _get_contents_minimum_size]. diff --git a/doc/classes/XROrigin3D.xml b/doc/classes/XROrigin3D.xml index b35d27ab129..041e8cd7aa5 100644 --- a/doc/classes/XROrigin3D.xml +++ b/doc/classes/XROrigin3D.xml @@ -5,20 +5,19 @@ This is a special node within the AR/VR system that maps the physical location of the center of our tracking space to the virtual location within our game world. - There should be only one of these nodes in your scene and you must have one. All the XRCamera3D, XRController3D and XRAnchor3D nodes should be direct children of this node for spatial tracking to work correctly. + Multiple origin points can be added to the scene tree, but only one can used at a time. All the [XRCamera3D], [XRController3D], and [XRAnchor3D] nodes should be direct children of this node for spatial tracking to work correctly. It is the position of this node that you update when your character needs to move through your game world while we're not moving in the real world. Movement in the real world is always in relation to this origin point. - For example, if your character is driving a car, the XROrigin3D node should be a child node of this car. Or, if you're implementing a teleport system to move your character, you should change the position of this node. + For example, if your character is driving a car, the [XROrigin3D] node should be a child node of this car. Or, if you're implementing a teleport system to move your character, you should change the position of this node. $DOCS_URL/tutorials/xr/index.html - Is this XROrigin3D node the current origin used by the [XRServer]? + If [code]true[/code], this origin node is currently being used by the [XRServer]. Only one origin point can be used at a time. - Allows you to adjust the scale to your game's units. Most AR/VR platforms assume a scale of 1 game world unit = 1 real world meter. - [b]Note:[/b] This method is a passthrough to the [XRServer] itself. + The scale of the game world compared to the real world. This is the same as [member XRServer.world_scale]. By default, most AR/VR platforms assume that 1 game unit corresponds to 1 real world meter. diff --git a/doc/classes/XRServer.xml b/doc/classes/XRServer.xml index 4ef5d3473be..e98b6f37809 100644 --- a/doc/classes/XRServer.xml +++ b/doc/classes/XRServer.xml @@ -113,7 +113,7 @@ [b]Note:[/b] This property is managed by the current [XROrigin3D] node. It is exposed for access from GDExtensions. - Allows you to adjust the scale to your game's units. Most AR/VR platforms assume a scale of 1 game world unit = 1 real world meter. + The scale of the game world compared to the real world. By default, most AR/VR platforms assume that 1 game unit corresponds to 1 real world meter. diff --git a/doc/tools/make_rst.py b/doc/tools/make_rst.py index df3e9285382..047d63b5658 100755 --- a/doc/tools/make_rst.py +++ b/doc/tools/make_rst.py @@ -1691,6 +1691,7 @@ def format_text_block( inside_code_tag = "" inside_code_tabs = False ignore_code_warnings = False + code_warning_if_intended_string = "If this is intended, use [code skip-lint]...[/code]." pos = 0 tag_depth = 0 @@ -1749,7 +1750,7 @@ def format_text_block( else: if not ignore_code_warnings and tag_state.closing: print_warning( - f'{state.current_class}.xml: Found a code string that looks like a closing tag "[{tag_state.raw}]" in {context_name}.', + f'{state.current_class}.xml: Found a code string that looks like a closing tag "[{tag_state.raw}]" in {context_name}. {code_warning_if_intended_string}', state, ) @@ -1816,7 +1817,7 @@ def format_text_block( if inside_code_text in state.classes: print_warning( - f'{state.current_class}.xml: Found a code string "{inside_code_text}" that matches one of the known classes in {context_name}.', + f'{state.current_class}.xml: Found a code string "{inside_code_text}" that matches one of the known classes in {context_name}. {code_warning_if_intended_string}', state, ) @@ -1826,49 +1827,49 @@ def format_text_block( if target_name in class_def.methods: print_warning( - f'{state.current_class}.xml: Found a code string "{inside_code_text}" that matches the {target_class_name}.{target_name} method in {context_name}.', + f'{state.current_class}.xml: Found a code string "{inside_code_text}" that matches the {target_class_name}.{target_name} method in {context_name}. {code_warning_if_intended_string}', state, ) elif target_name in class_def.constructors: print_warning( - f'{state.current_class}.xml: Found a code string "{inside_code_text}" that matches the {target_class_name}.{target_name} constructor in {context_name}.', + f'{state.current_class}.xml: Found a code string "{inside_code_text}" that matches the {target_class_name}.{target_name} constructor in {context_name}. {code_warning_if_intended_string}', state, ) elif target_name in class_def.operators: print_warning( - f'{state.current_class}.xml: Found a code string "{inside_code_text}" that matches the {target_class_name}.{target_name} operator in {context_name}.', + f'{state.current_class}.xml: Found a code string "{inside_code_text}" that matches the {target_class_name}.{target_name} operator in {context_name}. {code_warning_if_intended_string}', state, ) elif target_name in class_def.properties: print_warning( - f'{state.current_class}.xml: Found a code string "{inside_code_text}" that matches the {target_class_name}.{target_name} member in {context_name}.', + f'{state.current_class}.xml: Found a code string "{inside_code_text}" that matches the {target_class_name}.{target_name} member in {context_name}. {code_warning_if_intended_string}', state, ) elif target_name in class_def.signals: print_warning( - f'{state.current_class}.xml: Found a code string "{inside_code_text}" that matches the {target_class_name}.{target_name} signal in {context_name}.', + f'{state.current_class}.xml: Found a code string "{inside_code_text}" that matches the {target_class_name}.{target_name} signal in {context_name}. {code_warning_if_intended_string}', state, ) elif target_name in class_def.annotations: print_warning( - f'{state.current_class}.xml: Found a code string "{inside_code_text}" that matches the {target_class_name}.{target_name} annotation in {context_name}.', + f'{state.current_class}.xml: Found a code string "{inside_code_text}" that matches the {target_class_name}.{target_name} annotation in {context_name}. {code_warning_if_intended_string}', state, ) elif target_name in class_def.theme_items: print_warning( - f'{state.current_class}.xml: Found a code string "{inside_code_text}" that matches the {target_class_name}.{target_name} theme item in {context_name}.', + f'{state.current_class}.xml: Found a code string "{inside_code_text}" that matches the {target_class_name}.{target_name} theme item in {context_name}. {code_warning_if_intended_string}', state, ) elif target_name in class_def.constants: print_warning( - f'{state.current_class}.xml: Found a code string "{inside_code_text}" that matches the {target_class_name}.{target_name} constant in {context_name}.', + f'{state.current_class}.xml: Found a code string "{inside_code_text}" that matches the {target_class_name}.{target_name} constant in {context_name}. {code_warning_if_intended_string}', state, ) @@ -1876,7 +1877,7 @@ def format_text_block( for enum in class_def.enums.values(): if target_name in enum.values: print_warning( - f'{state.current_class}.xml: Found a code string "{inside_code_text}" that matches the {target_class_name}.{target_name} enum value in {context_name}.', + f'{state.current_class}.xml: Found a code string "{inside_code_text}" that matches the {target_class_name}.{target_name} enum value in {context_name}. {code_warning_if_intended_string}', state, ) break @@ -1887,7 +1888,7 @@ def format_text_block( for param_def in context_params: if param_def.name == inside_code_text: print_warning( - f'{state.current_class}.xml: Found a code string "{inside_code_text}" that matches one of the parameters in {context_name}.', + f'{state.current_class}.xml: Found a code string "{inside_code_text}" that matches one of the parameters in {context_name}. {code_warning_if_intended_string}', state, ) break diff --git a/drivers/gles3/rasterizer_scene_gles3.cpp b/drivers/gles3/rasterizer_scene_gles3.cpp index e4246ea6753..bd63ae45ea0 100644 --- a/drivers/gles3/rasterizer_scene_gles3.cpp +++ b/drivers/gles3/rasterizer_scene_gles3.cpp @@ -262,7 +262,9 @@ void RasterizerSceneGLES3::_geometry_instance_add_surface_with_material(Geometry GLES3::Mesh::Surface *s = reinterpret_cast(sdcache->surface); if (p_material->shader_data->uses_tangent && !(s->format & RS::ARRAY_FORMAT_TANGENT)) { - WARN_PRINT_ED("Attempting to use a shader that requires tangents with a mesh that doesn't contain tangents. Ensure that meshes are imported with the 'ensure_tangents' option. If creating your own meshes, add an `ARRAY_TANGENT` array (when using ArrayMesh) or call `generate_tangents()` (when using SurfaceTool)."); + String shader_path = p_material->shader_data->path.is_empty() ? "" : "(" + p_material->shader_data->path + ")"; + String mesh_path = mesh_storage->mesh_get_path(p_mesh).is_empty() ? "" : "(" + mesh_storage->mesh_get_path(p_mesh) + ")"; + WARN_PRINT_ED(vformat("Attempting to use a shader %s that requires tangents with a mesh %s that doesn't contain tangents. Ensure that meshes are imported with the 'ensure_tangents' option. If creating your own meshes, add an `ARRAY_TANGENT` array (when using ArrayMesh) or call `generate_tangents()` (when using SurfaceTool).", shader_path, mesh_path)); } } @@ -1461,7 +1463,15 @@ void RasterizerSceneGLES3::_setup_environment(const RenderDataGLES3 *p_render_da //time global variables scene_state.ubo.time = time; - if (is_environment(p_render_data->environment)) { + if (get_debug_draw_mode() == RS::VIEWPORT_DEBUG_DRAW_UNSHADED) { + scene_state.ubo.use_ambient_light = true; + scene_state.ubo.ambient_light_color_energy[0] = 1; + scene_state.ubo.ambient_light_color_energy[1] = 1; + scene_state.ubo.ambient_light_color_energy[2] = 1; + scene_state.ubo.ambient_light_color_energy[3] = 1.0; + scene_state.ubo.use_ambient_cubemap = false; + scene_state.ubo.use_reflection_cubemap = false; + } else if (is_environment(p_render_data->environment)) { RS::EnvironmentBG env_bg = environment_get_background(p_render_data->environment); RS::EnvironmentAmbientSource ambient_src = environment_get_ambient_source(p_render_data->environment); @@ -2298,7 +2308,7 @@ void RasterizerSceneGLES3::render_scene(const Ref &p_render_ bool keep_color = false; float sky_energy_multiplier = 1.0; - if (get_debug_draw_mode() == RS::VIEWPORT_DEBUG_DRAW_OVERDRAW) { + if (unlikely(get_debug_draw_mode() == RS::VIEWPORT_DEBUG_DRAW_OVERDRAW)) { clear_color = Color(0, 0, 0, 1); //in overdraw mode, BG should always be black } else if (render_data.environment.is_valid()) { RS::EnvironmentBG bg_mode = environment_get_background(render_data.environment); @@ -2546,6 +2556,7 @@ void RasterizerSceneGLES3::_render_list_template(RenderListParameters *p_params, } glBindTexture(GL_TEXTURE_CUBE_MAP, texture_to_bind); } + } else if constexpr (p_pass_mode == PASS_MODE_DEPTH || p_pass_mode == PASS_MODE_SHADOW) { shader_variant = SceneShaderGLES3::MODE_DEPTH; } @@ -2583,8 +2594,16 @@ void RasterizerSceneGLES3::_render_list_template(RenderListParameters *p_params, material_data = surf->material_shadow; mesh_surface = surf->surface_shadow; } else { - shader = surf->shader; - material_data = surf->material; + if (unlikely(get_debug_draw_mode() == RS::VIEWPORT_DEBUG_DRAW_OVERDRAW)) { + material_data = overdraw_material_data_ptr; + shader = material_data->shader_data; + } else if (unlikely(get_debug_draw_mode() == RS::VIEWPORT_DEBUG_DRAW_LIGHTING)) { + material_data = default_material_data_ptr; + shader = material_data->shader_data; + } else { + shader = surf->shader; + material_data = surf->material; + } mesh_surface = surf->surface; } @@ -3400,7 +3419,7 @@ RasterizerSceneGLES3::RasterizerSceneGLES3() { scene_globals.default_shader = material_storage->shader_allocate(); material_storage->shader_initialize(scene_globals.default_shader); material_storage->shader_set_code(scene_globals.default_shader, R"( -// Default 3D material shader. +// Default 3D material shader (Compatibility). shader_type spatial; @@ -3417,6 +3436,29 @@ void fragment() { scene_globals.default_material = material_storage->material_allocate(); material_storage->material_initialize(scene_globals.default_material); material_storage->material_set_shader(scene_globals.default_material, scene_globals.default_shader); + default_material_data_ptr = static_cast(GLES3::MaterialStorage::get_singleton()->material_get_data(scene_globals.default_material, RS::SHADER_SPATIAL)); + } + + { + // Overdraw material and shader. + scene_globals.overdraw_shader = material_storage->shader_allocate(); + material_storage->shader_initialize(scene_globals.overdraw_shader); + material_storage->shader_set_code(scene_globals.overdraw_shader, R"( +// 3D editor Overdraw debug draw mode shader (Compatibility). + +shader_type spatial; + +render_mode blend_add, unshaded, fog_disabled; + +void fragment() { + ALBEDO = vec3(0.4, 0.8, 0.8); + ALPHA = 0.2; +} +)"); + scene_globals.overdraw_material = material_storage->material_allocate(); + material_storage->material_initialize(scene_globals.overdraw_material); + material_storage->material_set_shader(scene_globals.overdraw_material, scene_globals.overdraw_shader); + overdraw_material_data_ptr = static_cast(GLES3::MaterialStorage::get_singleton()->material_get_data(scene_globals.overdraw_material, RS::SHADER_SPATIAL)); } { @@ -3531,6 +3573,10 @@ RasterizerSceneGLES3::~RasterizerSceneGLES3() { RSG::material_storage->material_free(scene_globals.default_material); RSG::material_storage->shader_free(scene_globals.default_shader); + // Overdraw Shader + RSG::material_storage->material_free(scene_globals.overdraw_material); + RSG::material_storage->shader_free(scene_globals.overdraw_shader); + // Sky Shader GLES3::MaterialStorage::get_singleton()->shaders.sky_shader.version_free(sky_globals.shader_default_version); RSG::material_storage->material_free(sky_globals.default_material); diff --git a/drivers/gles3/rasterizer_scene_gles3.h b/drivers/gles3/rasterizer_scene_gles3.h index 7d3c8896dad..8e0033f7825 100644 --- a/drivers/gles3/rasterizer_scene_gles3.h +++ b/drivers/gles3/rasterizer_scene_gles3.h @@ -152,8 +152,13 @@ private: RID default_material; RID default_shader; RID cubemap_filter_shader_version; + RID overdraw_material; + RID overdraw_shader; } scene_globals; + GLES3::SceneMaterialData *default_material_data_ptr = nullptr; + GLES3::SceneMaterialData *overdraw_material_data_ptr = nullptr; + /* LIGHT INSTANCE */ struct LightData { diff --git a/drivers/gles3/shader_gles3.cpp b/drivers/gles3/shader_gles3.cpp index 75b2662a1c0..241fb231d7e 100644 --- a/drivers/gles3/shader_gles3.cpp +++ b/drivers/gles3/shader_gles3.cpp @@ -584,6 +584,19 @@ bool ShaderGLES3::_load_from_cache(Version *p_version) { Version::Specialization specialization; specialization.id = glCreateProgram(); + if (feedback_count) { + Vector feedback; + for (int feedback_index = 0; feedback_index < feedback_count; feedback_index++) { + if (feedbacks[feedback_index].specialization == 0 || (feedbacks[feedback_index].specialization & specialization_key)) { + // Specialization for this feedback is enabled. + feedback.push_back(feedbacks[feedback_index].name); + } + } + + if (!feedback.is_empty()) { + glTransformFeedbackVaryings(specialization.id, feedback.size(), feedback.ptr(), GL_INTERLEAVED_ATTRIBS); + } + } glProgramBinary(specialization.id, variant_format, variant_bytes.ptr(), variant_bytes.size()); GLint link_status = 0; @@ -611,6 +624,7 @@ void ShaderGLES3::_save_to_cache(Version *p_version) { #ifdef WEB_ENABLED // not supported in webgl return; #else + ERR_FAIL_COND(!shader_cache_dir_valid); #if !defined(ANDROID_ENABLED) && !defined(IOS_ENABLED) if (RasterizerGLES3::is_gles_over_gl() && (glGetProgramBinary == NULL)) { // ARB_get_program_binary extension not available. return; diff --git a/drivers/gles3/shader_gles3.h b/drivers/gles3/shader_gles3.h index 0cb53da3163..8968e76c12c 100644 --- a/drivers/gles3/shader_gles3.h +++ b/drivers/gles3/shader_gles3.h @@ -209,7 +209,9 @@ protected: _compile_specialization(s, p_variant, version, p_specialization); version->variants[p_variant].insert(p_specialization, s); spec = version->variants[p_variant].lookup_ptr(p_specialization); - _save_to_cache(version); + if (shader_cache_dir_valid) { + _save_to_cache(version); + } } } else if (spec->build_queued) { // Still queued, wait diff --git a/drivers/gles3/shaders/canvas.glsl b/drivers/gles3/shaders/canvas.glsl index c517fcb8ae7..69cb888c9d3 100644 --- a/drivers/gles3/shaders/canvas.glsl +++ b/drivers/gles3/shaders/canvas.glsl @@ -9,7 +9,7 @@ mode_instanced = #define USE_ATTRIBUTES \n#define USE_INSTANCING #[specializations] -DISABLE_LIGHTING = false +DISABLE_LIGHTING = true USE_RGBA_SHADOWS = false SINGLE_INSTANCE = false diff --git a/drivers/gles3/storage/mesh_storage.cpp b/drivers/gles3/storage/mesh_storage.cpp index e5080b39a39..bb6eb605b53 100644 --- a/drivers/gles3/storage/mesh_storage.cpp +++ b/drivers/gles3/storage/mesh_storage.cpp @@ -727,6 +727,20 @@ AABB MeshStorage::mesh_get_aabb(RID p_mesh, RID p_skeleton) { return aabb; } +void MeshStorage::mesh_set_path(RID p_mesh, const String &p_path) { + Mesh *mesh = mesh_owner.get_or_null(p_mesh); + ERR_FAIL_NULL(mesh); + + mesh->path = p_path; +} + +String MeshStorage::mesh_get_path(RID p_mesh) const { + Mesh *mesh = mesh_owner.get_or_null(p_mesh); + ERR_FAIL_NULL_V(mesh, String()); + + return mesh->path; +} + void MeshStorage::mesh_set_shadow_mesh(RID p_mesh, RID p_shadow_mesh) { Mesh *mesh = mesh_owner.get_or_null(p_mesh); ERR_FAIL_NULL(mesh); diff --git a/drivers/gles3/storage/mesh_storage.h b/drivers/gles3/storage/mesh_storage.h index 217c4dabf05..cea81baa0b7 100644 --- a/drivers/gles3/storage/mesh_storage.h +++ b/drivers/gles3/storage/mesh_storage.h @@ -142,6 +142,8 @@ struct Mesh { RID shadow_mesh; HashSet shadow_owners; + String path; + Dependency dependency; }; @@ -304,8 +306,11 @@ public: virtual void mesh_set_custom_aabb(RID p_mesh, const AABB &p_aabb) override; virtual AABB mesh_get_custom_aabb(RID p_mesh) const override; - virtual AABB mesh_get_aabb(RID p_mesh, RID p_skeleton = RID()) override; + + virtual void mesh_set_path(RID p_mesh, const String &p_path) override; + virtual String mesh_get_path(RID p_mesh) const override; + virtual void mesh_set_shadow_mesh(RID p_mesh, RID p_shadow_mesh) override; virtual void mesh_clear(RID p_mesh) override; diff --git a/drivers/gles3/storage/texture_storage.h b/drivers/gles3/storage/texture_storage.h index 27e358ec31c..e5678031180 100644 --- a/drivers/gles3/storage/texture_storage.h +++ b/drivers/gles3/storage/texture_storage.h @@ -402,8 +402,8 @@ private: RID_Owner canvas_texture_owner; /* Texture API */ - - mutable RID_Owner texture_owner; + // Textures can be created from threads, so this RID_Owner is thread safe. + mutable RID_Owner texture_owner; Ref _get_gl_image_and_format(const Ref &p_image, Image::Format p_format, Image::Format &r_real_format, GLenum &r_gl_format, GLenum &r_gl_internal_format, GLenum &r_gl_type, bool &r_compressed, bool p_force_decompress) const; diff --git a/drivers/wasapi/audio_driver_wasapi.cpp b/drivers/wasapi/audio_driver_wasapi.cpp index 64f2d1f2035..8ea1f52d156 100644 --- a/drivers/wasapi/audio_driver_wasapi.cpp +++ b/drivers/wasapi/audio_driver_wasapi.cpp @@ -737,12 +737,17 @@ void AudioDriverWASAPI::thread_func(void *p_udata) { ad->start_counting_ticks(); if (avail_frames > 0 && ad->audio_output.audio_client) { + UINT32 buffer_size; UINT32 cur_frames; bool invalidated = false; - HRESULT hr = ad->audio_output.audio_client->GetCurrentPadding(&cur_frames); + HRESULT hr = ad->audio_output.audio_client->GetBufferSize(&buffer_size); + if (hr != S_OK) { + ERR_PRINT("WASAPI: GetBufferSize error"); + } + hr = ad->audio_output.audio_client->GetCurrentPadding(&cur_frames); if (hr == S_OK) { // Check how much frames are available on the WASAPI buffer - UINT32 write_frames = MIN(ad->buffer_frames - cur_frames, avail_frames); + UINT32 write_frames = MIN(buffer_size - cur_frames, avail_frames); if (write_frames > 0) { BYTE *buffer = nullptr; hr = ad->audio_output.render_client->GetBuffer(write_frames, &buffer); diff --git a/drivers/windows/dir_access_windows.cpp b/drivers/windows/dir_access_windows.cpp index 8bf83823a03..9d370e30a52 100644 --- a/drivers/windows/dir_access_windows.cpp +++ b/drivers/windows/dir_access_windows.cpp @@ -31,6 +31,7 @@ #if defined(WINDOWS_ENABLED) #include "dir_access_windows.h" +#include "file_access_windows.h" #include "core/config/project_settings.h" #include "core/os/memory.h" @@ -177,6 +178,13 @@ Error DirAccessWindows::make_dir(String p_dir) { p_dir = fix_path(p_dir); } + if (FileAccessWindows::is_path_invalid(p_dir)) { +#ifdef DEBUG_ENABLED + WARN_PRINT("The path :" + p_dir + " is a reserved Windows system pipe, so it can't be used for creating directories."); +#endif + return ERR_INVALID_PARAMETER; + } + p_dir = p_dir.simplify_path().replace("/", "\\"); bool success; diff --git a/drivers/windows/file_access_windows.cpp b/drivers/windows/file_access_windows.cpp index 9d21073f190..e0889d5ad03 100644 --- a/drivers/windows/file_access_windows.cpp +++ b/drivers/windows/file_access_windows.cpp @@ -60,12 +60,7 @@ void FileAccessWindows::check_errors() const { bool FileAccessWindows::is_path_invalid(const String &p_path) { // Check for invalid operating system file. - String fname = p_path; - int dot = fname.find("."); - if (dot != -1) { - fname = fname.substr(0, dot); - } - fname = fname.to_lower(); + String fname = p_path.get_file().get_basename().to_lower(); return invalid_files.has(fname); } diff --git a/drivers/windows/file_access_windows.h b/drivers/windows/file_access_windows.h index 73143009fcf..10f34009f78 100644 --- a/drivers/windows/file_access_windows.h +++ b/drivers/windows/file_access_windows.h @@ -50,10 +50,11 @@ class FileAccessWindows : public FileAccess { void _close(); - static bool is_path_invalid(const String &p_path); static HashSet invalid_files; public: + static bool is_path_invalid(const String &p_path); + virtual String fix_path(const String &p_path) const override; virtual Error open_internal(const String &p_path, int p_mode_flags) override; ///< open a file virtual bool is_open() const override; ///< true when file is open diff --git a/editor/animation_track_editor.cpp b/editor/animation_track_editor.cpp index 8268cf10aec..04d17a50341 100644 --- a/editor/animation_track_editor.cpp +++ b/editor/animation_track_editor.cpp @@ -1349,15 +1349,15 @@ void AnimationTimelineEdit::_notification(int p_what) { time_icon->set_texture(get_editor_theme_icon(SNAME("Time"))); add_track->get_popup()->clear(); - add_track->get_popup()->add_icon_item(get_editor_theme_icon(SNAME("KeyValue")), TTR("Property Track")); - add_track->get_popup()->add_icon_item(get_editor_theme_icon(SNAME("KeyXPosition")), TTR("3D Position Track")); - add_track->get_popup()->add_icon_item(get_editor_theme_icon(SNAME("KeyXRotation")), TTR("3D Rotation Track")); - add_track->get_popup()->add_icon_item(get_editor_theme_icon(SNAME("KeyXScale")), TTR("3D Scale Track")); - add_track->get_popup()->add_icon_item(get_editor_theme_icon(SNAME("KeyBlendShape")), TTR("Blend Shape Track")); - add_track->get_popup()->add_icon_item(get_editor_theme_icon(SNAME("KeyCall")), TTR("Call Method Track")); - add_track->get_popup()->add_icon_item(get_editor_theme_icon(SNAME("KeyBezier")), TTR("Bezier Curve Track")); - add_track->get_popup()->add_icon_item(get_editor_theme_icon(SNAME("KeyAudio")), TTR("Audio Playback Track")); - add_track->get_popup()->add_icon_item(get_editor_theme_icon(SNAME("KeyAnimation")), TTR("Animation Playback Track")); + add_track->get_popup()->add_icon_item(get_editor_theme_icon(SNAME("KeyValue")), TTR("Property Track...")); + add_track->get_popup()->add_icon_item(get_editor_theme_icon(SNAME("KeyXPosition")), TTR("3D Position Track...")); + add_track->get_popup()->add_icon_item(get_editor_theme_icon(SNAME("KeyXRotation")), TTR("3D Rotation Track...")); + add_track->get_popup()->add_icon_item(get_editor_theme_icon(SNAME("KeyXScale")), TTR("3D Scale Track...")); + add_track->get_popup()->add_icon_item(get_editor_theme_icon(SNAME("KeyBlendShape")), TTR("Blend Shape Track...")); + add_track->get_popup()->add_icon_item(get_editor_theme_icon(SNAME("KeyCall")), TTR("Call Method Track...")); + add_track->get_popup()->add_icon_item(get_editor_theme_icon(SNAME("KeyBezier")), TTR("Bezier Curve Track...")); + add_track->get_popup()->add_icon_item(get_editor_theme_icon(SNAME("KeyAudio")), TTR("Audio Playback Track...")); + add_track->get_popup()->add_icon_item(get_editor_theme_icon(SNAME("KeyAnimation")), TTR("Animation Playback Track...")); } break; case EditorSettings::NOTIFICATION_EDITOR_SETTINGS_CHANGED: { @@ -2842,7 +2842,7 @@ void AnimationTrackEdit::gui_input(const Ref &p_event) { } menu->clear(); - menu->add_icon_item(get_editor_theme_icon(SNAME("Key")), TTR("Insert Key"), MENU_KEY_INSERT); + menu->add_icon_item(get_editor_theme_icon(SNAME("Key")), TTR("Insert Key..."), MENU_KEY_INSERT); if (editor->is_selection_active()) { menu->add_separator(); menu->add_icon_item(get_editor_theme_icon(SNAME("Duplicate")), TTR("Duplicate Key(s)"), MENU_KEY_DUPLICATE); @@ -6038,6 +6038,12 @@ void AnimationTrackEditor::_edit_menu_pressed(int p_option) { existing_idx = reset->track_find_key(dst_track, 0, Animation::FIND_MODE_APPROX); } + if (animation->track_get_type(sk.track) == Animation::TYPE_VALUE) { + undo_redo->add_do_method(reset.ptr(), "value_track_set_update_mode", dst_track, animation->value_track_get_update_mode(sk.track)); + undo_redo->add_do_method(reset.ptr(), "track_set_interpolation_type", dst_track, animation->track_get_interpolation_type(sk.track)); + undo_redo->add_do_method(reset.ptr(), "track_set_interpolation_loop_wrap", dst_track, animation->track_get_interpolation_loop_wrap(sk.track)); + } + undo_redo->add_do_method(reset.ptr(), "track_insert_key", dst_track, 0, animation->track_get_key_value(sk.track, sk.key), animation->track_get_key_transition(sk.track, sk.key)); undo_redo->add_undo_method(reset.ptr(), "track_remove_key_at_time", dst_track, 0); @@ -6623,13 +6629,13 @@ AnimationTrackEditor::AnimationTrackEditor() { edit->set_flat(false); edit->set_disabled(true); edit->set_tooltip_text(TTR("Animation properties.")); - edit->get_popup()->add_item(TTR("Copy Tracks"), EDIT_COPY_TRACKS); + edit->get_popup()->add_item(TTR("Copy Tracks..."), EDIT_COPY_TRACKS); edit->get_popup()->add_item(TTR("Paste Tracks"), EDIT_PASTE_TRACKS); edit->get_popup()->add_separator(); - edit->get_popup()->add_item(TTR("Scale Selection"), EDIT_SCALE_SELECTION); - edit->get_popup()->add_item(TTR("Scale From Cursor"), EDIT_SCALE_FROM_CURSOR); + edit->get_popup()->add_item(TTR("Scale Selection..."), EDIT_SCALE_SELECTION); + edit->get_popup()->add_item(TTR("Scale From Cursor..."), EDIT_SCALE_FROM_CURSOR); edit->get_popup()->add_separator(); - edit->get_popup()->add_item(TTR("Make Easing Selection"), EDIT_EASE_SELECTION); + edit->get_popup()->add_item(TTR("Make Easing Selection..."), EDIT_EASE_SELECTION); edit->get_popup()->add_separator(); edit->get_popup()->add_shortcut(ED_SHORTCUT("animation_editor/duplicate_selection", TTR("Duplicate Selection"), KeyModifierMask::CMD_OR_CTRL | Key::D), EDIT_DUPLICATE_SELECTION); edit->get_popup()->add_shortcut(ED_SHORTCUT("animation_editor/duplicate_selection_transposed", TTR("Duplicate Transposed"), KeyModifierMask::SHIFT | KeyModifierMask::CMD_OR_CTRL | Key::D), EDIT_DUPLICATE_TRANSPOSED); @@ -6643,9 +6649,9 @@ AnimationTrackEditor::AnimationTrackEditor() { edit->get_popup()->add_separator(); edit->get_popup()->add_shortcut(ED_SHORTCUT("animation_editor/apply_reset", TTR("Apply Reset")), EDIT_APPLY_RESET); edit->get_popup()->add_separator(); - edit->get_popup()->add_item(TTR("Bake Animation"), EDIT_BAKE_ANIMATION); - edit->get_popup()->add_item(TTR("Optimize Animation (no undo)"), EDIT_OPTIMIZE_ANIMATION); - edit->get_popup()->add_item(TTR("Clean-Up Animation (no undo)"), EDIT_CLEAN_UP_ANIMATION); + edit->get_popup()->add_item(TTR("Bake Animation..."), EDIT_BAKE_ANIMATION); + edit->get_popup()->add_item(TTR("Optimize Animation (no undo)..."), EDIT_OPTIMIZE_ANIMATION); + edit->get_popup()->add_item(TTR("Clean-Up Animation (no undo)..."), EDIT_CLEAN_UP_ANIMATION); edit->get_popup()->connect("id_pressed", callable_mp(this, &AnimationTrackEditor::_edit_menu_pressed)); edit->get_popup()->connect("about_to_popup", callable_mp(this, &AnimationTrackEditor::_edit_menu_about_to_popup)); diff --git a/editor/debugger/debug_adapter/debug_adapter_parser.cpp b/editor/debugger/debug_adapter/debug_adapter_parser.cpp index 929f323e80a..5009de4ac4e 100644 --- a/editor/debugger/debug_adapter/debug_adapter_parser.cpp +++ b/editor/debugger/debug_adapter/debug_adapter_parser.cpp @@ -44,7 +44,7 @@ void DebugAdapterParser::_bind_methods() { ClassDB::bind_method(D_METHOD("req_attach", "params"), &DebugAdapterParser::req_attach); ClassDB::bind_method(D_METHOD("req_restart", "params"), &DebugAdapterParser::req_restart); ClassDB::bind_method(D_METHOD("req_terminate", "params"), &DebugAdapterParser::req_terminate); - ClassDB::bind_method(D_METHOD("req_configurationDone", "params"), &DebugAdapterParser::prepare_success_response); + ClassDB::bind_method(D_METHOD("req_configurationDone", "params"), &DebugAdapterParser::req_configurationDone); ClassDB::bind_method(D_METHOD("req_pause", "params"), &DebugAdapterParser::req_pause); ClassDB::bind_method(D_METHOD("req_continue", "params"), &DebugAdapterParser::req_continue); ClassDB::bind_method(D_METHOD("req_threads", "params"), &DebugAdapterParser::req_threads); @@ -180,6 +180,13 @@ Dictionary DebugAdapterParser::req_launch(const Dictionary &p_params) const { DebugAdapterProtocol::get_singleton()->get_current_peer()->supportsCustomData = args["godot/custom_data"]; } + DebugAdapterProtocol::get_singleton()->get_current_peer()->pending_launch = p_params; + + return Dictionary(); +} + +Dictionary DebugAdapterParser::_launch_process(const Dictionary &p_params) const { + Dictionary args = p_params["arguments"]; ScriptEditorDebugger *dbg = EditorDebuggerNode::get_singleton()->get_default_debugger(); if ((bool)args["noDebug"] != dbg->is_skip_breakpoints()) { dbg->debug_skip_breakpoints(); @@ -246,7 +253,7 @@ Dictionary DebugAdapterParser::req_restart(const Dictionary &p_params) const { args = args["arguments"]; params["arguments"] = args; - Dictionary response = DebugAdapterProtocol::get_singleton()->get_current_peer()->attached ? req_attach(params) : req_launch(params); + Dictionary response = DebugAdapterProtocol::get_singleton()->get_current_peer()->attached ? req_attach(params) : _launch_process(params); if (!response["success"]) { response["command"] = p_params["command"]; return response; @@ -261,6 +268,16 @@ Dictionary DebugAdapterParser::req_terminate(const Dictionary &p_params) const { return prepare_success_response(p_params); } +Dictionary DebugAdapterParser::req_configurationDone(const Dictionary &p_params) const { + Ref peer = DebugAdapterProtocol::get_singleton()->get_current_peer(); + if (!peer->pending_launch.is_empty()) { + peer->res_queue.push_back(_launch_process(peer->pending_launch)); + peer->pending_launch.clear(); + } + + return prepare_success_response(p_params); +} + Dictionary DebugAdapterParser::req_pause(const Dictionary &p_params) const { EditorRunBar::get_singleton()->get_pause_button()->set_pressed(true); EditorDebuggerNode::get_singleton()->_paused(); @@ -468,6 +485,7 @@ Dictionary DebugAdapterParser::req_evaluate(const Dictionary &p_params) const { String value = EditorDebuggerNode::get_singleton()->get_var_value(args["expression"]); body["result"] = value; + body["variablesReference"] = 0; return response; } diff --git a/editor/debugger/debug_adapter/debug_adapter_parser.h b/editor/debugger/debug_adapter/debug_adapter_parser.h index 9995066ab4d..e5493a4b9f9 100644 --- a/editor/debugger/debug_adapter/debug_adapter_parser.h +++ b/editor/debugger/debug_adapter/debug_adapter_parser.h @@ -71,6 +71,7 @@ public: Dictionary req_attach(const Dictionary &p_params) const; Dictionary req_restart(const Dictionary &p_params) const; Dictionary req_terminate(const Dictionary &p_params) const; + Dictionary req_configurationDone(const Dictionary &p_params) const; Dictionary req_pause(const Dictionary &p_params) const; Dictionary req_continue(const Dictionary &p_params) const; Dictionary req_threads(const Dictionary &p_params) const; @@ -84,6 +85,9 @@ public: Dictionary req_evaluate(const Dictionary &p_params) const; Dictionary req_godot_put_msg(const Dictionary &p_params) const; + // Internal requests + Dictionary _launch_process(const Dictionary &p_params) const; + // Events Dictionary ev_initialized() const; Dictionary ev_process(const String &p_command) const; diff --git a/editor/debugger/debug_adapter/debug_adapter_protocol.cpp b/editor/debugger/debug_adapter/debug_adapter_protocol.cpp index 26fb73570e4..7417a3d8f73 100644 --- a/editor/debugger/debug_adapter/debug_adapter_protocol.cpp +++ b/editor/debugger/debug_adapter/debug_adapter_protocol.cpp @@ -678,7 +678,10 @@ bool DebugAdapterProtocol::process_message(const String &p_text) { if (!response.is_empty()) { _current_peer->res_queue.push_front(response); } else { - completed = false; + // Launch request needs to be deferred until we receive a configurationDone request. + if (command != "req_launch") { + completed = false; + } } } diff --git a/editor/debugger/debug_adapter/debug_adapter_protocol.h b/editor/debugger/debug_adapter/debug_adapter_protocol.h index ddc55816db8..fb1c533bbbf 100644 --- a/editor/debugger/debug_adapter/debug_adapter_protocol.h +++ b/editor/debugger/debug_adapter/debug_adapter_protocol.h @@ -63,6 +63,7 @@ struct DAPeer : RefCounted { // Internal client info bool attached = false; + Dictionary pending_launch; Error handle_data(); Error send_data(); diff --git a/editor/debugger/editor_profiler.cpp b/editor/debugger/editor_profiler.cpp index f72538e3dec..6edfb06e351 100644 --- a/editor/debugger/editor_profiler.cpp +++ b/editor/debugger/editor_profiler.cpp @@ -349,7 +349,7 @@ void EditorProfiler::_update_frame() { category->set_custom_color(0, _get_color_from_signature(m.categories[i].signature)); } - for (int j = m.categories[i].items.size() - 1; j >= 0; j--) { + for (int j = 0; j < m.categories[i].items.size(); j++) { const Metric::Category::Item &it = m.categories[i].items[j]; TreeItem *item = variables->create_item(category); diff --git a/editor/debugger/editor_visual_profiler.cpp b/editor/debugger/editor_visual_profiler.cpp index 7df942e288a..47bcbbe4d68 100644 --- a/editor/debugger/editor_visual_profiler.cpp +++ b/editor/debugger/editor_visual_profiler.cpp @@ -70,7 +70,7 @@ void EditorVisualProfiler::add_frame_metric(const Metric &p_metric) { updating_frame = true; clear_button->set_disabled(false); cursor_metric_edit->set_max(frame_metrics[last_metric].frame_number); - cursor_metric_edit->set_min(MAX(frame_metrics[last_metric].frame_number - frame_metrics.size(), 0u)); + cursor_metric_edit->set_min(MAX(int64_t(frame_metrics[last_metric].frame_number) - frame_metrics.size(), 0)); if (!seeking) { cursor_metric_edit->set_value(frame_metrics[last_metric].frame_number); diff --git a/editor/editor_inspector.cpp b/editor/editor_inspector.cpp index 3fa90b3d819..715d0ca34e2 100644 --- a/editor/editor_inspector.cpp +++ b/editor/editor_inspector.cpp @@ -2791,7 +2791,9 @@ void EditorInspector::update_tree() { (!filter.is_empty() || !restrict_to_basic || (N->get().usage & PROPERTY_USAGE_EDITOR_BASIC_SETTING))) { break; } - if (N->get().usage & PROPERTY_USAGE_CATEGORY) { + // Treat custom categories as second-level ones. Do not skip a normal category if it is followed by a custom one. + // Skip in the other 3 cases (normal -> normal, custom -> custom, custom -> normal). + if ((N->get().usage & PROPERTY_USAGE_CATEGORY) && (p.hint_string.is_empty() || !N->get().hint_string.is_empty())) { valid = false; break; } @@ -2808,53 +2810,53 @@ void EditorInspector::update_tree() { // `hint_script` should contain a native class name or a script path. // Otherwise the category was probably added via `@export_category` or `_get_property_list()`. + // Do not add an icon, do not change the current class (`doc_name`) for custom categories. if (p.hint_string.is_empty()) { category->label = p.name; category->set_tooltip_text(p.name); - continue; // Do not add an icon, do not change the current class (`doc_name`). - } + } else { + String type = p.name; + String label = p.name; + doc_name = p.name; - String type = p.name; - String label = p.name; - doc_name = p.name; + // Use category's owner script to update some of its information. + if (!EditorNode::get_editor_data().is_type_recognized(type) && ResourceLoader::exists(p.hint_string)) { + Ref