diff options
34 files changed, 252 insertions, 208 deletions
diff --git a/core/config/project_settings.cpp b/core/config/project_settings.cpp index 7a10390d72..4d2006d42a 100644 --- a/core/config/project_settings.cpp +++ b/core/config/project_settings.cpp @@ -619,7 +619,7 @@ Error ProjectSettings::_setup(const String &p_path, const String &p_main_pack, b Error ProjectSettings::setup(const String &p_path, const String &p_main_pack, bool p_upwards, bool p_ignore_override) { Error err = _setup(p_path, p_main_pack, p_upwards, p_ignore_override); if (err == OK) { - String custom_settings = GLOBAL_DEF("application/config/project_settings_override", ""); + String custom_settings = GLOBAL_GET("application/config/project_settings_override"); if (!custom_settings.is_empty()) { _load_settings_text(custom_settings); } @@ -1276,6 +1276,7 @@ ProjectSettings::ProjectSettings() { GLOBAL_DEF("physics/2d/run_on_separate_thread", false); GLOBAL_DEF("physics/3d/run_on_separate_thread", false); + GLOBAL_DEF("debug/disable_touch", false); GLOBAL_DEF("debug/settings/profiler/max_functions", 16384); custom_prop_info["debug/settings/profiler/max_functions"] = PropertyInfo(Variant::INT, "debug/settings/profiler/max_functions", PROPERTY_HINT_RANGE, "128,65535,1"); @@ -1292,6 +1293,22 @@ ProjectSettings::ProjectSettings() { GLOBAL_DEF("compression/formats/gzip/compression_level", Compression::gzip_level); custom_prop_info["compression/formats/gzip/compression_level"] = PropertyInfo(Variant::INT, "compression/formats/gzip/compression_level", PROPERTY_HINT_RANGE, "-1,9,1"); + GLOBAL_DEF("debug/settings/crash_handler/message", + String("Please include this when reporting the bug to the project developer.")); + GLOBAL_DEF("debug/settings/crash_handler/message.editor", + String("Please include this when reporting the bug on: https://github.com/godotengine/godot/issues")); + GLOBAL_DEF_RST("rendering/occlusion_culling/bvh_build_quality", 2); + GLOBAL_DEF("memory/limits/multithreaded_server/rid_pool_prealloc", 60); + GLOBAL_DEF_RST("internationalization/rendering/force_right_to_left_layout_direction", false); + + GLOBAL_DEF("gui/timers/incremental_search_max_interval_msec", 2000); + ProjectSettings::get_singleton()->set_custom_property_info("gui/timers/incremental_search_max_interval_msec", PropertyInfo(Variant::INT, "gui/timers/incremental_search_max_interval_msec", PROPERTY_HINT_RANGE, "0,10000,1,or_greater")); // No negative numbers. + + GLOBAL_DEF("rendering/rendering_device/staging_buffer/block_size_kb", 256); + GLOBAL_DEF("rendering/rendering_device/staging_buffer/max_size_mb", 128); + GLOBAL_DEF("rendering/rendering_device/staging_buffer/texture_upload_region_size_px", 64); + GLOBAL_DEF("rendering/rendering_device/vulkan/max_descriptors_per_pool", 64); + // These properties will not show up in the dialog nor in the documentation. If you want to exclude whole groups, see _get_property_list() method. GLOBAL_DEF_INTERNAL("application/config/features", PackedStringArray()); GLOBAL_DEF_INTERNAL("internationalization/locale/translation_remaps", PackedStringArray()); diff --git a/doc/classes/GPUParticles2D.xml b/doc/classes/GPUParticles2D.xml index 4916171900..c7d10078e8 100644 --- a/doc/classes/GPUParticles2D.xml +++ b/doc/classes/GPUParticles2D.xml @@ -89,12 +89,17 @@ Particle texture. If [code]null[/code], particles will be squares. </member> <member name="trail_enabled" type="bool" setter="set_trail_enabled" getter="is_trail_enabled" default="false"> + If [code]true[/code], enables particle trails using a mesh skinning system. + [b]Note:[/b] Unlike [GPUParticles3D], the number of trail sections and subdivisions is set with the [member trail_sections] and [member trail_section_subdivisions] properties. </member> - <member name="trail_length_secs" type="float" setter="set_trail_length" getter="get_trail_length" default="0.3"> + <member name="trail_lifetime" type="float" setter="set_trail_lifetime" getter="get_trail_lifetime" default="0.3"> + The amount of time the particle's trail should represent (in seconds). Only effective if [member trail_enabled] is [code]true[/code]. </member> <member name="trail_section_subdivisions" type="int" setter="set_trail_section_subdivisions" getter="get_trail_section_subdivisions" default="4"> + The number of subdivisions to use for the particle trail rendering. Higher values can result in smoother trail curves, at the cost of performance due to increased mesh complexity. See also [member trail_sections]. Only effective if [member trail_enabled] is [code]true[/code]. </member> <member name="trail_sections" type="int" setter="set_trail_sections" getter="get_trail_sections" default="8"> + The number of sections to use for the particle trail rendering. Higher values can result in smoother trail curves, at the cost of performance due to increased mesh complexity. See also [member trail_section_subdivisions]. Only effective if [member trail_enabled] is [code]true[/code]. </member> <member name="visibility_rect" type="Rect2" setter="set_visibility_rect" getter="get_visibility_rect" default="Rect2(-100, -100, 200, 200)"> The [Rect2] that determines the node's region which needs to be visible on screen for the particle system to be active. diff --git a/doc/classes/GPUParticles3D.xml b/doc/classes/GPUParticles3D.xml index d0be4d784a..ea53c5b4b5 100644 --- a/doc/classes/GPUParticles3D.xml +++ b/doc/classes/GPUParticles3D.xml @@ -116,8 +116,12 @@ <member name="sub_emitter" type="NodePath" setter="set_sub_emitter" getter="get_sub_emitter" default="NodePath("")"> </member> <member name="trail_enabled" type="bool" setter="set_trail_enabled" getter="is_trail_enabled" default="false"> + If [code]true[/code], enables particle trails using a mesh skinning system. Designed to work with [RibbonTrailMesh] and [TubeTrailMesh]. + [b]Note:[/b] [member BaseMaterial3D.use_particle_trails] must also be enabled on the particle mesh's material. Otherwise, setting [member trail_enabled] to [code]true[/code] will have no effect. + [b]Note:[/b] Unlike [GPUParticles2D], the number of trail sections and subdivisions is set in the [RibbonTrailMesh] or the [TubeTrailMesh]'s properties. </member> - <member name="trail_length_secs" type="float" setter="set_trail_length" getter="get_trail_length" default="0.3"> + <member name="trail_lifetime" type="float" setter="set_trail_lifetime" getter="get_trail_lifetime" default="0.3"> + The amount of time the particle's trail should represent (in seconds). Only effective if [member trail_enabled] is [code]true[/code]. </member> <member name="transform_align" type="int" setter="set_transform_align" getter="get_transform_align" enum="GPUParticles3D.TransformAlign" default="0"> </member> diff --git a/doc/classes/PhysicsDirectBodyState2D.xml b/doc/classes/PhysicsDirectBodyState2D.xml index 80afe3b784..e8062f3e94 100644 --- a/doc/classes/PhysicsDirectBodyState2D.xml +++ b/doc/classes/PhysicsDirectBodyState2D.xml @@ -76,6 +76,7 @@ <param index="0" name="torque" type="float" /> <description> Applies a rotational force without affecting position. A force is time dependent and meant to be applied every physics update. + [b]Note:[/b] [member inverse_inertia] is required for this to work. To have [member inverse_inertia], an active [CollisionShape2D] must be a child of the node, or you can manually set [member inverse_inertia]. </description> </method> <method name="apply_torque_impulse"> @@ -84,6 +85,7 @@ <description> Applies a rotational impulse to the body without affecting the position. An impulse is time-independent! Applying an impulse every frame would result in a framerate-dependent force. For this reason, it should only be used when simulating one-time impacts (use the "_force" functions otherwise). + [b]Note:[/b] [member inverse_inertia] is required for this to work. To have [member inverse_inertia], an active [CollisionShape2D] must be a child of the node, or you can manually set [member inverse_inertia]. </description> </method> <method name="get_constant_force" qualifiers="const"> diff --git a/doc/classes/PhysicsDirectBodyState3D.xml b/doc/classes/PhysicsDirectBodyState3D.xml index 3266c02a1e..4c6d51c85a 100644 --- a/doc/classes/PhysicsDirectBodyState3D.xml +++ b/doc/classes/PhysicsDirectBodyState3D.xml @@ -76,6 +76,7 @@ <param index="0" name="torque" type="Vector3" /> <description> Applies a rotational force without affecting position. A force is time dependent and meant to be applied every physics update. + [b]Note:[/b] [member inverse_inertia] is required for this to work. To have [member inverse_inertia], an active [CollisionShape3D] must be a child of the node, or you can manually set [member inverse_inertia]. </description> </method> <method name="apply_torque_impulse"> @@ -84,6 +85,7 @@ <description> Applies a rotational impulse to the body without affecting the position. An impulse is time-independent! Applying an impulse every frame would result in a framerate-dependent force. For this reason, it should only be used when simulating one-time impacts (use the "_force" functions otherwise). + [b]Note:[/b] [member inverse_inertia] is required for this to work. To have [member inverse_inertia], an active [CollisionShape3D] must be a child of the node, or you can manually set [member inverse_inertia]. </description> </method> <method name="get_constant_force" qualifiers="const"> diff --git a/doc/classes/ProjectSettings.xml b/doc/classes/ProjectSettings.xml index fae88a401b..4699131c41 100644 --- a/doc/classes/ProjectSettings.xml +++ b/doc/classes/ProjectSettings.xml @@ -341,6 +341,9 @@ <member name="compression/formats/zstd/window_log_size" type="int" setter="" getter="" default="27"> Largest size limit (in power of 2) allowed when compressing using long-distance matching with Zstandard. Higher values can result in better compression, but will require more memory when compressing and decompressing. </member> + <member name="debug/disable_touch" type="bool" setter="" getter="" default="false"> + Disable touch input. Only has effect on iOS. + </member> <member name="debug/file_logging/enable_file_logging" type="bool" setter="" getter="" default="false"> If [code]true[/code], logs all output to files. </member> diff --git a/doc/classes/RigidBody2D.xml b/doc/classes/RigidBody2D.xml index 9eedc3a24c..6e3535f14a 100644 --- a/doc/classes/RigidBody2D.xml +++ b/doc/classes/RigidBody2D.xml @@ -87,6 +87,7 @@ <param index="0" name="torque" type="float" /> <description> Applies a rotational force without affecting position. A force is time dependent and meant to be applied every physics update. + [b]Note:[/b] [member inertia] is required for this to work. To have [member inertia], an active [CollisionShape2D] must be a child of the node, or you can manually set [member inertia]. </description> </method> <method name="apply_torque_impulse"> @@ -95,6 +96,7 @@ <description> Applies a rotational impulse to the body without affecting the position. An impulse is time-independent! Applying an impulse every frame would result in a framerate-dependent force. For this reason, it should only be used when simulating one-time impacts (use the "_force" functions otherwise). + [b]Note:[/b] [member inertia] is required for this to work. To have [member inertia], an active [CollisionShape2D] must be a child of the node, or you can manually set [member inertia]. </description> </method> <method name="get_colliding_bodies" qualifiers="const"> diff --git a/doc/classes/RigidBody3D.xml b/doc/classes/RigidBody3D.xml index 3ee3f25df1..8380d56de3 100644 --- a/doc/classes/RigidBody3D.xml +++ b/doc/classes/RigidBody3D.xml @@ -87,6 +87,7 @@ <param index="0" name="torque" type="Vector3" /> <description> Applies a rotational force without affecting position. A force is time dependent and meant to be applied every physics update. + [b]Note:[/b] [member inertia] is required for this to work. To have [member inertia], an active [CollisionShape3D] must be a child of the node, or you can manually set [member inertia]. </description> </method> <method name="apply_torque_impulse"> @@ -95,6 +96,7 @@ <description> Applies a rotational impulse to the body without affecting the position. An impulse is time-independent! Applying an impulse every frame would result in a framerate-dependent force. For this reason, it should only be used when simulating one-time impacts (use the "_force" functions otherwise). + [b]Note:[/b] [member inertia] is required for this to work. To have [member inertia], an active [CollisionShape3D] must be a child of the node, or you can manually set [member inertia]. </description> </method> <method name="get_colliding_bodies" qualifiers="const"> diff --git a/drivers/vulkan/rendering_device_vulkan.cpp b/drivers/vulkan/rendering_device_vulkan.cpp index 66754932ad..0ff4ca31e6 100644 --- a/drivers/vulkan/rendering_device_vulkan.cpp +++ b/drivers/vulkan/rendering_device_vulkan.cpp @@ -9387,12 +9387,10 @@ void RenderingDeviceVulkan::initialize(VulkanContext *p_context, bool p_local_de } } - // NOTE: If adding new project settings here, also duplicate their definition in - // rendering_server.cpp for headless doctool. - staging_buffer_block_size = GLOBAL_DEF("rendering/rendering_device/staging_buffer/block_size_kb", 256); + staging_buffer_block_size = GLOBAL_GET("rendering/rendering_device/staging_buffer/block_size_kb"); staging_buffer_block_size = MAX(4u, staging_buffer_block_size); staging_buffer_block_size *= 1024; // Kb -> bytes. - staging_buffer_max_size = GLOBAL_DEF("rendering/rendering_device/staging_buffer/max_size_mb", 128); + staging_buffer_max_size = GLOBAL_GET("rendering/rendering_device/staging_buffer/max_size_mb"); staging_buffer_max_size = MAX(1u, staging_buffer_max_size); staging_buffer_max_size *= 1024 * 1024; @@ -9400,7 +9398,7 @@ void RenderingDeviceVulkan::initialize(VulkanContext *p_context, bool p_local_de // Validate enough blocks. staging_buffer_max_size = staging_buffer_block_size * 4; } - texture_upload_region_size_px = GLOBAL_DEF("rendering/rendering_device/staging_buffer/texture_upload_region_size_px", 64); + texture_upload_region_size_px = GLOBAL_GET("rendering/rendering_device/staging_buffer/texture_upload_region_size_px"); texture_upload_region_size_px = nearest_power_of_2_templated(texture_upload_region_size_px); frames_drawn = frame_count; // Start from frame count, so everything else is immediately old. @@ -9415,7 +9413,7 @@ void RenderingDeviceVulkan::initialize(VulkanContext *p_context, bool p_local_de ERR_CONTINUE(err != OK); } - max_descriptors_per_pool = GLOBAL_DEF("rendering/rendering_device/vulkan/max_descriptors_per_pool", 64); + max_descriptors_per_pool = GLOBAL_GET("rendering/rendering_device/vulkan/max_descriptors_per_pool"); // Check to make sure DescriptorPoolKey is good. static_assert(sizeof(uint64_t) * 3 >= UNIFORM_TYPE_MAX * sizeof(uint16_t)); diff --git a/editor/editor_node.cpp b/editor/editor_node.cpp index bd6bc3ece5..1bca1b3c87 100644 --- a/editor/editor_node.cpp +++ b/editor/editor_node.cpp @@ -536,7 +536,7 @@ void EditorNode::_update_from_settings() { RS::get_singleton()->environment_set_volumetric_fog_filter_active(bool(GLOBAL_GET("rendering/environment/volumetric_fog/use_filter"))); RS::get_singleton()->canvas_set_shadow_texture_size(GLOBAL_GET("rendering/2d/shadow_atlas/size")); - bool use_half_res_gi = GLOBAL_DEF("rendering/global_illumination/gi/use_half_resolution", false); + bool use_half_res_gi = GLOBAL_GET("rendering/global_illumination/gi/use_half_resolution"); RS::get_singleton()->gi_set_use_half_resolution(use_half_res_gi); bool snap_2d_transforms = GLOBAL_GET("rendering/2d/snap/snap_2d_transforms_to_pixel"); @@ -5134,7 +5134,7 @@ bool EditorNode::has_scenes_in_session() { bool EditorNode::ensure_main_scene(bool p_from_native) { pick_main_scene->set_meta("from_native", p_from_native); // Whether from play button or native run. - String main_scene = GLOBAL_DEF_BASIC("application/run/main_scene", ""); + String main_scene = GLOBAL_GET("application/run/main_scene"); if (main_scene.is_empty()) { current_menu_option = -1; @@ -5201,7 +5201,7 @@ bool EditorNode::is_run_playing() const { String EditorNode::get_run_playing_scene() const { String run_filename = editor_run.get_running_scene(); if (run_filename.is_empty() && is_run_playing()) { - run_filename = GLOBAL_DEF_BASIC("application/run/main_scene", ""); // Must be the main scene then. + run_filename = GLOBAL_GET("application/run/main_scene"); // Must be the main scene then. } return run_filename; diff --git a/editor/plugins/gdextension_export_plugin.h b/editor/plugins/gdextension_export_plugin.h index e1d68d97b5..c5f7d2a047 100644 --- a/editor/plugins/gdextension_export_plugin.h +++ b/editor/plugins/gdextension_export_plugin.h @@ -107,7 +107,7 @@ void GDExtensionExportPlugin::_export_file(const String &p_path, const String &p for (const String &E : p_features) { tags.append(E); } - ERR_FAIL_MSG(vformat("Couldn't export extension: %s. No suitable library found for export flags: %s", p_path, String(", ").join(tags))); + ERR_FAIL_MSG(vformat("No suitable library found. The libraries' tags referred to an invalid feature flag. Possible feature flags for your platform: %s", p_path, String(", ").join(tags))); } List<String> dependencies; diff --git a/main/main.cpp b/main/main.cpp index 5b998d98ce..0fce8e3d94 100644 --- a/main/main.cpp +++ b/main/main.cpp @@ -443,11 +443,7 @@ Error Main::test_setup() { globals = memnew(ProjectSettings); - GLOBAL_DEF("debug/settings/crash_handler/message", - String("Please include this when reporting the bug on https://github.com/godotengine/godot/issues")); - GLOBAL_DEF_RST("rendering/occlusion_culling/bvh_build_quality", 2); - - register_core_settings(); //here globals are present + register_core_settings(); // Here globals are present. translation_server = memnew(TranslationServer); tsman = memnew(TextServerManager); @@ -665,11 +661,6 @@ Error Main::setup(const char *execpath, int argc, char *argv[], bool p_second_ph GLOBAL_DEF_RST("application/run/flush_stdout_on_print", false); GLOBAL_DEF_RST("application/run/flush_stdout_on_print.debug", true); - GLOBAL_DEF("debug/settings/crash_handler/message", - String("Please include this when reporting the bug to the project developer.")); - GLOBAL_DEF("debug/settings/crash_handler/message.editor", - String("Please include this when reporting the bug on: https://github.com/godotengine/godot/issues")); - MAIN_PRINT("Main: Parse CMDLine"); /* argument parsing and main creation */ @@ -1358,7 +1349,6 @@ Error Main::setup(const char *execpath, int argc, char *argv[], bool p_second_ph ResourceUID::get_singleton()->load_from_cache(); // load UUIDs from cache. - GLOBAL_DEF("memory/limits/multithreaded_server/rid_pool_prealloc", 60); ProjectSettings::get_singleton()->set_custom_property_info("memory/limits/multithreaded_server/rid_pool_prealloc", PropertyInfo(Variant::INT, "memory/limits/multithreaded_server/rid_pool_prealloc", @@ -1715,7 +1705,6 @@ Error Main::setup(const char *execpath, int argc, char *argv[], bool p_second_ph window_mode = (DisplayServer::WindowMode)(GLOBAL_GET("display/window/size/mode").operator int()); } - GLOBAL_DEF_RST("internationalization/rendering/force_right_to_left_layout_direction", false); GLOBAL_DEF("internationalization/locale/include_text_server_data", false); OS::get_singleton()->_allow_hidpi = GLOBAL_DEF("display/window/dpi/allow_hidpi", true); @@ -2165,12 +2154,12 @@ Error Main::setup2(Thread::ID p_main_tid_override) { boot_logo->set_pixel(0, 0, Color(0, 0, 0, 0)); } + Color boot_bg_color = GLOBAL_DEF_BASIC("application/boot_splash/bg_color", boot_splash_bg_color); + #if defined(TOOLS_ENABLED) && !defined(NO_EDITOR_SPLASH) - const Color boot_bg_color = + boot_bg_color = GLOBAL_DEF_BASIC("application/boot_splash/bg_color", (editor || project_manager) ? boot_splash_editor_bg_color : boot_splash_bg_color); -#else - const Color boot_bg_color = GLOBAL_DEF_BASIC("application/boot_splash/bg_color", boot_splash_bg_color); #endif if (boot_logo.is_valid()) { RenderingServer::get_singleton()->set_boot_image(boot_logo, boot_bg_color, boot_logo_scale, @@ -2202,7 +2191,7 @@ Error Main::setup2(Thread::ID p_main_tid_override) { MAIN_PRINT("Main: DCC"); RenderingServer::get_singleton()->set_default_clear_color( - GLOBAL_DEF_BASIC("rendering/environment/defaults/default_clear_color", Color(0.3, 0.3, 0.3))); + GLOBAL_GET("rendering/environment/defaults/default_clear_color")); GLOBAL_DEF("application/config/icon", String()); ProjectSettings::get_singleton()->set_custom_property_info("application/config/icon", @@ -2805,15 +2794,48 @@ bool Main::start() { startup_benchmark_file = String(); } #endif + GLOBAL_DEF_BASIC("display/window/stretch/mode", "disabled"); + ProjectSettings::get_singleton()->set_custom_property_info("display/window/stretch/mode", + PropertyInfo(Variant::STRING, + "display/window/stretch/mode", + PROPERTY_HINT_ENUM, + "disabled,canvas_items,viewport")); + GLOBAL_DEF_BASIC("display/window/stretch/aspect", "keep"); + ProjectSettings::get_singleton()->set_custom_property_info("display/window/stretch/aspect", + PropertyInfo(Variant::STRING, + "display/window/stretch/aspect", + PROPERTY_HINT_ENUM, + "ignore,keep,keep_width,keep_height,expand")); + GLOBAL_DEF_BASIC("display/window/stretch/scale", 1.0); + ProjectSettings::get_singleton()->set_custom_property_info("display/window/stretch/scale", + PropertyInfo(Variant::FLOAT, + "display/window/stretch/scale", + PROPERTY_HINT_RANGE, + "0.5,8.0,0.01")); + sml->set_auto_accept_quit(GLOBAL_DEF("application/config/auto_accept_quit", true)); + sml->set_quit_on_go_back(GLOBAL_DEF("application/config/quit_on_go_back", true)); + GLOBAL_DEF_BASIC("gui/common/snap_controls_to_pixels", true); + GLOBAL_DEF_BASIC("gui/fonts/dynamic_fonts/use_oversampling", true); + + GLOBAL_DEF_BASIC("rendering/textures/canvas_textures/default_texture_filter", 1); + ProjectSettings::get_singleton()->set_custom_property_info( + "rendering/textures/canvas_textures/default_texture_filter", + PropertyInfo(Variant::INT, "rendering/textures/canvas_textures/default_texture_filter", PROPERTY_HINT_ENUM, + "Nearest,Linear,Linear Mipmap,Nearest Mipmap")); + GLOBAL_DEF_BASIC("rendering/textures/canvas_textures/default_texture_repeat", 0); + ProjectSettings::get_singleton()->set_custom_property_info( + "rendering/textures/canvas_textures/default_texture_repeat", + PropertyInfo(Variant::INT, "rendering/textures/canvas_textures/default_texture_repeat", PROPERTY_HINT_ENUM, + "Disable,Enable,Mirror")); if (!editor && !project_manager) { //standard helpers that can be changed from main config - String stretch_mode = GLOBAL_DEF_BASIC("display/window/stretch/mode", "disabled"); - String stretch_aspect = GLOBAL_DEF_BASIC("display/window/stretch/aspect", "keep"); - Size2i stretch_size = Size2i(GLOBAL_DEF_BASIC("display/window/size/viewport_width", 0), - GLOBAL_DEF_BASIC("display/window/size/viewport_height", 0)); - real_t stretch_scale = GLOBAL_DEF_BASIC("display/window/stretch/scale", 1.0); + String stretch_mode = GLOBAL_GET("display/window/stretch/mode"); + String stretch_aspect = GLOBAL_GET("display/window/stretch/aspect"); + Size2i stretch_size = Size2i(GLOBAL_GET("display/window/size/viewport_width"), + GLOBAL_GET("display/window/size/viewport_height")); + real_t stretch_scale = GLOBAL_GET("display/window/stretch/scale"); Window::ContentScaleMode cs_sm = Window::CONTENT_SCALE_MODE_DISABLED; if (stretch_mode == "canvas_items") { @@ -2838,8 +2860,8 @@ bool Main::start() { sml->get_root()->set_content_scale_size(stretch_size); sml->get_root()->set_content_scale_factor(stretch_scale); - sml->set_auto_accept_quit(GLOBAL_DEF("application/config/auto_accept_quit", true)); - sml->set_quit_on_go_back(GLOBAL_DEF("application/config/quit_on_go_back", true)); + sml->set_auto_accept_quit(GLOBAL_GET("application/config/auto_accept_quit")); + sml->set_quit_on_go_back(GLOBAL_GET("application/config/quit_on_go_back")); String appname = GLOBAL_GET("application/config/name"); appname = TranslationServer::get_singleton()->translate(appname); #ifdef DEBUG_ENABLED @@ -2855,53 +2877,18 @@ bool Main::start() { // It can still be overridden by the user in a script. DisplayServer::get_singleton()->window_set_min_size(Size2i(64, 64)); - bool snap_controls = GLOBAL_DEF("gui/common/snap_controls_to_pixels", true); + bool snap_controls = GLOBAL_GET("gui/common/snap_controls_to_pixels"); sml->get_root()->set_snap_controls_to_pixels(snap_controls); - bool font_oversampling = GLOBAL_DEF("gui/fonts/dynamic_fonts/use_oversampling", true); + bool font_oversampling = GLOBAL_GET("gui/fonts/dynamic_fonts/use_oversampling"); sml->get_root()->set_use_font_oversampling(font_oversampling); - int texture_filter = GLOBAL_DEF("rendering/textures/canvas_textures/default_texture_filter", 1); - int texture_repeat = GLOBAL_DEF("rendering/textures/canvas_textures/default_texture_repeat", 0); + int texture_filter = GLOBAL_GET("rendering/textures/canvas_textures/default_texture_filter"); + int texture_repeat = GLOBAL_GET("rendering/textures/canvas_textures/default_texture_repeat"); sml->get_root()->set_default_canvas_item_texture_filter( Viewport::DefaultCanvasItemTextureFilter(texture_filter)); sml->get_root()->set_default_canvas_item_texture_repeat( Viewport::DefaultCanvasItemTextureRepeat(texture_repeat)); - - } else { - GLOBAL_DEF_BASIC("display/window/stretch/mode", "disabled"); - ProjectSettings::get_singleton()->set_custom_property_info("display/window/stretch/mode", - PropertyInfo(Variant::STRING, - "display/window/stretch/mode", - PROPERTY_HINT_ENUM, - "disabled,canvas_items,viewport")); - GLOBAL_DEF_BASIC("display/window/stretch/aspect", "keep"); - ProjectSettings::get_singleton()->set_custom_property_info("display/window/stretch/aspect", - PropertyInfo(Variant::STRING, - "display/window/stretch/aspect", - PROPERTY_HINT_ENUM, - "ignore,keep,keep_width,keep_height,expand")); - GLOBAL_DEF_BASIC("display/window/stretch/scale", 1.0); - ProjectSettings::get_singleton()->set_custom_property_info("display/window/stretch/scale", - PropertyInfo(Variant::FLOAT, - "display/window/stretch/scale", - PROPERTY_HINT_RANGE, - "0.5,8.0,0.01")); - sml->set_auto_accept_quit(GLOBAL_DEF("application/config/auto_accept_quit", true)); - sml->set_quit_on_go_back(GLOBAL_DEF("application/config/quit_on_go_back", true)); - GLOBAL_DEF_BASIC("gui/common/snap_controls_to_pixels", true); - GLOBAL_DEF_BASIC("gui/fonts/dynamic_fonts/use_oversampling", true); - - GLOBAL_DEF_BASIC("rendering/textures/canvas_textures/default_texture_filter", 1); - ProjectSettings::get_singleton()->set_custom_property_info( - "rendering/textures/canvas_textures/default_texture_filter", - PropertyInfo(Variant::INT, "rendering/textures/canvas_textures/default_texture_filter", PROPERTY_HINT_ENUM, - "Nearest,Linear,Linear Mipmap,Nearest Mipmap")); - GLOBAL_DEF_BASIC("rendering/textures/canvas_textures/default_texture_repeat", 0); - ProjectSettings::get_singleton()->set_custom_property_info( - "rendering/textures/canvas_textures/default_texture_repeat", - PropertyInfo(Variant::INT, "rendering/textures/canvas_textures/default_texture_repeat", PROPERTY_HINT_ENUM, - "Disable,Enable,Mirror")); } #ifdef TOOLS_ENABLED @@ -2970,7 +2957,7 @@ bool Main::start() { Engine::get_singleton()->startup_benchmark_begin_measure("game_load"); // Load SSL Certificates from Project Settings (or builtin). - Crypto::load_default_certificates(GLOBAL_DEF("network/tls/certificate_bundle_override", "")); + Crypto::load_default_certificates(GLOBAL_GET("network/tls/certificate_bundle_override")); if (!game_path.is_empty()) { Node *scene = nullptr; @@ -2983,7 +2970,7 @@ bool Main::start() { sml->add_current_scene(scene); #ifdef MACOS_ENABLED - String mac_iconpath = GLOBAL_DEF("application/config/macos_native_icon", "Variant()"); + String mac_iconpath = GLOBAL_GET("application/config/macos_native_icon"); if (!mac_iconpath.is_empty()) { DisplayServer::get_singleton()->set_native_icon(mac_iconpath); hasicon = true; @@ -2991,14 +2978,14 @@ bool Main::start() { #endif #ifdef WINDOWS_ENABLED - String win_iconpath = GLOBAL_DEF("application/config/windows_native_icon", "Variant()"); + String win_iconpath = GLOBAL_GET("application/config/windows_native_icon"); if (!win_iconpath.is_empty()) { DisplayServer::get_singleton()->set_native_icon(win_iconpath); hasicon = true; } #endif - String iconpath = GLOBAL_DEF("application/config/icon", "Variant()"); + String iconpath = GLOBAL_GET("application/config/icon"); if ((!iconpath.is_empty()) && (!hasicon)) { Ref<Image> icon; icon.instantiate(); diff --git a/platform/android/export/export_plugin.cpp b/platform/android/export/export_plugin.cpp index 3bfdd3b881..9919268375 100644 --- a/platform/android/export/export_plugin.cpp +++ b/platform/android/export/export_plugin.cpp @@ -585,12 +585,13 @@ zip_fileinfo EditorExportPlatformAndroid::get_zip_fileinfo() { return zipfi; } -Vector<String> EditorExportPlatformAndroid::get_abis() { - Vector<String> abis; - abis.push_back("armeabi-v7a"); - abis.push_back("arm64-v8a"); - abis.push_back("x86"); - abis.push_back("x86_64"); +Vector<EditorExportPlatformAndroid::ABI> EditorExportPlatformAndroid::get_abis() { + // Should have the same order and size as get_archs. + Vector<ABI> abis; + abis.push_back(ABI("armeabi-v7a", "arm32")); + abis.push_back(ABI("arm64-v8a", "arm64")); + abis.push_back(ABI("x86", "x86_32")); + abis.push_back(ABI("x86_64", "x86_64")); return abis; } @@ -687,14 +688,20 @@ Error EditorExportPlatformAndroid::save_apk_so(void *p_userdata, const SharedObj return FAILED; } APKExportData *ed = static_cast<APKExportData *>(p_userdata); - Vector<String> abis = get_abis(); + Vector<ABI> abis = get_abis(); bool exported = false; for (int i = 0; i < p_so.tags.size(); ++i) { // shared objects can be fat (compatible with multiple ABIs) - int abi_index = abis.find(p_so.tags[i]); + int abi_index = -1; + for (int j = 0; j < abis.size(); ++j) { + if (abis[j].abi == p_so.tags[i] || abis[j].arch == p_so.tags[i]) { + abi_index = j; + break; + } + } if (abi_index != -1) { exported = true; - String abi = abis[abi_index]; + String abi = abis[abi_index].abi; String dst_path = String("lib").path_join(abi).path_join(p_so.path.get_file()); Vector<uint8_t> array = FileAccess::get_file_as_array(p_so.path); Error store_err = store_in_apk(ed, dst_path, array); @@ -702,9 +709,7 @@ Error EditorExportPlatformAndroid::save_apk_so(void *p_userdata, const SharedObj } } if (!exported) { - String abis_string = String(" ").join(abis); - String err = "Cannot determine ABI for library \"" + p_so.path + "\". One of the supported ABIs must be used as a tag: " + abis_string; - ERR_PRINT(err); + ERR_PRINT("Cannot determine architecture for library \"" + p_so.path + "\". One of the supported architectures must be used as a tag: " + join_abis(abis, " ", true)); return FAILED; } return OK; @@ -725,16 +730,22 @@ Error EditorExportPlatformAndroid::ignore_apk_file(void *p_userdata, const Strin Error EditorExportPlatformAndroid::copy_gradle_so(void *p_userdata, const SharedObject &p_so) { ERR_FAIL_COND_V_MSG(!p_so.path.get_file().begins_with("lib"), FAILED, "Android .so file names must start with \"lib\", but got: " + p_so.path); - Vector<String> abis = get_abis(); + Vector<ABI> abis = get_abis(); CustomExportData *export_data = static_cast<CustomExportData *>(p_userdata); bool exported = false; for (int i = 0; i < p_so.tags.size(); ++i) { - int abi_index = abis.find(p_so.tags[i]); + int abi_index = -1; + for (int j = 0; j < abis.size(); ++j) { + if (abis[j].abi == p_so.tags[i] || abis[j].arch == p_so.tags[i]) { + abi_index = j; + break; + } + } if (abi_index != -1) { exported = true; String base = "res://android/build/libs"; String type = export_data->debug ? "debug" : "release"; - String abi = abis[abi_index]; + String abi = abis[abi_index].abi; String filename = p_so.path.get_file(); String dst_path = base.path_join(type).path_join(abi).path_join(filename); Vector<uint8_t> data = FileAccess::get_file_as_array(p_so.path); @@ -745,7 +756,7 @@ Error EditorExportPlatformAndroid::copy_gradle_so(void *p_userdata, const Shared } } ERR_FAIL_COND_V_MSG(!exported, FAILED, - "Cannot determine ABI for library \"" + p_so.path + "\". One of the supported ABIs must be used as a tag: " + String(" ").join(abis)); + "Cannot determine architecture for library \"" + p_so.path + "\". One of the supported architectures must be used as a tag:" + join_abis(abis, " ", true)); return OK; } @@ -1656,11 +1667,11 @@ void EditorExportPlatformAndroid::_copy_icons_to_gradle_project(const Ref<Editor } } -Vector<String> EditorExportPlatformAndroid::get_enabled_abis(const Ref<EditorExportPreset> &p_preset) { - Vector<String> abis = get_abis(); - Vector<String> enabled_abis; +Vector<EditorExportPlatformAndroid::ABI> EditorExportPlatformAndroid::get_enabled_abis(const Ref<EditorExportPreset> &p_preset) { + Vector<ABI> abis = get_abis(); + Vector<ABI> enabled_abis; for (int i = 0; i < abis.size(); ++i) { - bool is_enabled = p_preset->get("architectures/" + abis[i]); + bool is_enabled = p_preset->get("architectures/" + abis[i].abi); if (is_enabled) { enabled_abis.push_back(abis[i]); } @@ -1671,9 +1682,10 @@ Vector<String> EditorExportPlatformAndroid::get_enabled_abis(const Ref<EditorExp void EditorExportPlatformAndroid::get_preset_features(const Ref<EditorExportPreset> &p_preset, List<String> *r_features) const { r_features->push_back("etc2"); - Vector<String> abis = get_enabled_abis(p_preset); + Vector<ABI> abis = get_enabled_abis(p_preset); for (int i = 0; i < abis.size(); ++i) { - r_features->push_back(abis[i]); + r_features->push_back(abis[i].arch); + r_features->push_back(abis[i].abi); } } @@ -1697,9 +1709,9 @@ void EditorExportPlatformAndroid::get_export_options(List<ExportOption> *r_optio // Android supports multiple architectures in an app bundle, so // we expose each option as a checkbox in the export dialog. - const Vector<String> abis = get_abis(); + const Vector<ABI> abis = get_abis(); for (int i = 0; i < abis.size(); ++i) { - const String abi = abis[i]; + const String abi = abis[i].abi; // All Android devices supporting Vulkan run 64-bit Android, // so there is usually no point in exporting for 32-bit Android. const bool is_default = abi == "arm64-v8a"; @@ -2516,13 +2528,24 @@ void EditorExportPlatformAndroid::_remove_copied_libs() { da->remove(GDNATIVE_LIBS_PATH); } -String EditorExportPlatformAndroid::join_list(List<String> parts, const String &separator) const { +String EditorExportPlatformAndroid::join_list(const List<String> &p_parts, const String &p_separator) { + String ret; + for (int i = 0; i < p_parts.size(); ++i) { + if (i > 0) { + ret += p_separator; + } + ret += p_parts[i]; + } + return ret; +} + +String EditorExportPlatformAndroid::join_abis(const Vector<EditorExportPlatformAndroid::ABI> &p_parts, const String &p_separator, bool p_use_arch) { String ret; - for (int i = 0; i < parts.size(); ++i) { + for (int i = 0; i < p_parts.size(); ++i) { if (i > 0) { - ret += separator; + ret += p_separator; } - ret += parts[i]; + ret += (p_use_arch) ? p_parts[i].arch : p_parts[i].abi; } return ret; } @@ -2544,7 +2567,7 @@ Error EditorExportPlatformAndroid::export_project_helper(const Ref<EditorExportP bool use_custom_build = bool(p_preset->get("custom_build/use_custom_build")); bool p_give_internet = p_flags & (DEBUG_FLAG_DUMB_CLIENT | DEBUG_FLAG_REMOTE_DEBUG); bool apk_expansion = p_preset->get("apk_expansion/enable"); - Vector<String> enabled_abis = get_enabled_abis(p_preset); + Vector<ABI> enabled_abis = get_enabled_abis(p_preset); print_verbose("Exporting for Android..."); print_verbose("- debug build: " + bool_to_string(p_debug)); @@ -2553,7 +2576,7 @@ Error EditorExportPlatformAndroid::export_project_helper(const Ref<EditorExportP print_verbose("- sign build: " + bool_to_string(should_sign)); print_verbose("- custom build enabled: " + bool_to_string(use_custom_build)); print_verbose("- apk expansion enabled: " + bool_to_string(apk_expansion)); - print_verbose("- enabled abis: " + String(",").join(enabled_abis)); + print_verbose("- enabled abis: " + join_abis(enabled_abis, ",", false)); print_verbose("- export filter: " + itos(p_preset->get_export_filter())); print_verbose("- include filter: " + p_preset->get_include_filter()); print_verbose("- exclude filter: " + p_preset->get_exclude_filter()); @@ -2676,7 +2699,7 @@ Error EditorExportPlatformAndroid::export_project_helper(const Ref<EditorExportP if (!target_sdk_version.is_valid_int()) { target_sdk_version = itos(DEFAULT_TARGET_SDK_VERSION); } - String enabled_abi_string = String("|").join(enabled_abis); + String enabled_abi_string = join_abis(enabled_abis, "|", false); String sign_flag = should_sign ? "true" : "false"; String zipalign_flag = "true"; @@ -2861,7 +2884,7 @@ Error EditorExportPlatformAndroid::export_project_helper(const Ref<EditorExportP String apk_expansion_pkey = p_preset->get("apk_expansion/public_key"); - Vector<String> invalid_abis(enabled_abis); + Vector<ABI> invalid_abis(enabled_abis); while (ret == UNZ_OK) { //get filename unz_file_info info; @@ -2924,7 +2947,7 @@ Error EditorExportPlatformAndroid::export_project_helper(const Ref<EditorExportP if (file.ends_with(".so")) { bool enabled = false; for (int i = 0; i < enabled_abis.size(); ++i) { - if (file.begins_with("lib/" + enabled_abis[i] + "/")) { + if (file.begins_with("lib/" + enabled_abis[i].abi + "/")) { invalid_abis.erase(enabled_abis[i]); enabled = true; break; @@ -2966,8 +2989,7 @@ Error EditorExportPlatformAndroid::export_project_helper(const Ref<EditorExportP } if (!invalid_abis.is_empty()) { - String unsupported_arch = String(", ").join(invalid_abis); - add_message(EXPORT_MESSAGE_ERROR, TTR("Export"), vformat(TTR("Missing libraries in the export template for the selected architectures: %s. Please build a template with all required libraries, or uncheck the missing architectures in the export preset."), unsupported_arch)); + add_message(EXPORT_MESSAGE_ERROR, TTR("Export"), vformat(TTR("Missing libraries in the export template for the selected architectures: %s. Please build a template with all required libraries, or uncheck the missing architectures in the export preset."), join_abis(invalid_abis, ", ", false))); CLEANUP_AND_RETURN(ERR_FILE_NOT_FOUND); } diff --git a/platform/android/export/export_plugin.h b/platform/android/export/export_plugin.h index 46012bd46c..c8fcb761fe 100644 --- a/platform/android/export/export_plugin.h +++ b/platform/android/export/export_plugin.h @@ -99,7 +99,22 @@ class EditorExportPlatformAndroid : public EditorExportPlatform { static zip_fileinfo get_zip_fileinfo(); - static Vector<String> get_abis(); + struct ABI { + String abi; + String arch; + + bool operator==(const ABI &p_a) const { + return p_a.abi == abi; + } + + ABI(const String &p_abi, const String &p_arch) { + abi = p_abi; + arch = p_arch; + } + ABI() {} + }; + + static Vector<ABI> get_abis(); /// List the gdap files in the directory specified by the p_path parameter. static Vector<String> list_gdap_files(const String &p_path); @@ -152,7 +167,7 @@ class EditorExportPlatformAndroid : public EditorExportPlatform { const Ref<Image> &foreground, const Ref<Image> &background); - static Vector<String> get_enabled_abis(const Ref<EditorExportPreset> &p_preset); + static Vector<ABI> get_enabled_abis(const Ref<EditorExportPreset> &p_preset); public: typedef Error (*EditorExportSaveFunction)(void *p_userdata, const String &p_path, const Vector<uint8_t> &p_data, int p_file, int p_total, const Vector<String> &p_enc_in_filters, const Vector<String> &p_enc_ex_filters, const Vector<uint8_t> &p_key); @@ -228,7 +243,8 @@ public: void _remove_copied_libs(); - String join_list(List<String> parts, const String &separator) const; + static String join_list(const List<String> &p_parts, const String &p_separator); + static String join_abis(const Vector<ABI> &p_parts, const String &p_separator, bool p_use_arch); virtual Error export_project(const Ref<EditorExportPreset> &p_preset, bool p_debug, const String &p_path, int p_flags = 0) override; diff --git a/platform/android/java/lib/src/org/godotengine/godot/input/GodotEditText.java b/platform/android/java/lib/src/org/godotengine/godot/input/GodotEditText.java index 7925b54fc4..804dbaf165 100644 --- a/platform/android/java/lib/src/org/godotengine/godot/input/GodotEditText.java +++ b/platform/android/java/lib/src/org/godotengine/godot/input/GodotEditText.java @@ -127,7 +127,9 @@ public class GodotEditText extends EditText { edit.setText(""); edit.append(text); if (msg.arg2 != -1) { - edit.setSelection(msg.arg1, msg.arg2); + int selectionStart = Math.min(msg.arg1, edit.length()); + int selectionEnd = Math.min(msg.arg2, edit.length()); + edit.setSelection(selectionStart, selectionEnd); edit.mInputWrapper.setSelection(true); } else { edit.mInputWrapper.setSelection(false); diff --git a/platform/android/java/lib/src/org/godotengine/godot/input/GodotGestureHandler.kt b/platform/android/java/lib/src/org/godotengine/godot/input/GodotGestureHandler.kt index a7a57621de..cde8d7cdae 100644 --- a/platform/android/java/lib/src/org/godotengine/godot/input/GodotGestureHandler.kt +++ b/platform/android/java/lib/src/org/godotengine/godot/input/GodotGestureHandler.kt @@ -77,7 +77,7 @@ internal class GodotGestureHandler : SimpleOnGestureListener(), OnScaleGestureLi } private fun contextClickRouter(event: MotionEvent) { - if (scaleInProgress) { + if (scaleInProgress || nextDownIsDoubleTap) { return } @@ -134,40 +134,24 @@ internal class GodotGestureHandler : SimpleOnGestureListener(), OnScaleGestureLi } private fun onActionUp(event: MotionEvent): Boolean { + if (event.actionMasked == MotionEvent.ACTION_CANCEL && pointerCaptureInProgress) { + // Don't dispatch the ACTION_CANCEL while a capture is in progress + return true + } + val sourceMouseRelative = if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) { event.isFromSource(InputDevice.SOURCE_MOUSE_RELATIVE) } else { false } - when { - pointerCaptureInProgress -> { - return if (event.actionMasked == MotionEvent.ACTION_CANCEL) { - // Don't dispatch the ACTION_CANCEL while a capture is in progress - true - } else { - GodotInputHandler.handleMouseEvent( - MotionEvent.ACTION_UP, - event.buttonState, - event.x, - event.y, - 0f, - 0f, - false, - sourceMouseRelative - ) - pointerCaptureInProgress = false - true - } - } - dragInProgress -> { - GodotInputHandler.handleMotionEvent(event) - dragInProgress = false - return true - } - contextClickInProgress -> { + + if (pointerCaptureInProgress || dragInProgress || contextClickInProgress) { + if (contextClickInProgress || GodotInputHandler.isMouseEvent(event)) { + // This may be an ACTION_BUTTON_RELEASE event which we don't handle, + // so we convert it to an ACTION_UP event. GodotInputHandler.handleMouseEvent( - event.actionMasked, - 0, + MotionEvent.ACTION_UP, + event.buttonState, event.x, event.y, 0f, @@ -175,11 +159,16 @@ internal class GodotGestureHandler : SimpleOnGestureListener(), OnScaleGestureLi false, sourceMouseRelative ) - contextClickInProgress = false - return true + } else { + GodotInputHandler.handleTouchEvent(event) } - else -> return false + pointerCaptureInProgress = false + dragInProgress = false + contextClickInProgress = false + return true } + + return false } private fun onActionMove(event: MotionEvent): Boolean { @@ -242,7 +231,7 @@ internal class GodotGestureHandler : SimpleOnGestureListener(), OnScaleGestureLi val x = terminusEvent.x val y = terminusEvent.y - if (terminusEvent.pointerCount >= 2 && panningAndScalingEnabled) { + if (terminusEvent.pointerCount >= 2 && panningAndScalingEnabled && !pointerCaptureInProgress) { GodotLib.pan(x, y, distanceX / 5f, distanceY / 5f) } else { GodotInputHandler.handleMotionEvent(terminusEvent) @@ -251,7 +240,7 @@ internal class GodotGestureHandler : SimpleOnGestureListener(), OnScaleGestureLi } override fun onScale(detector: ScaleGestureDetector?): Boolean { - if (detector == null || !panningAndScalingEnabled) { + if (detector == null || !panningAndScalingEnabled || pointerCaptureInProgress) { return false } GodotLib.magnify( @@ -263,7 +252,7 @@ internal class GodotGestureHandler : SimpleOnGestureListener(), OnScaleGestureLi } override fun onScaleBegin(detector: ScaleGestureDetector?): Boolean { - if (detector == null || !panningAndScalingEnabled) { + if (detector == null || !panningAndScalingEnabled || pointerCaptureInProgress) { return false } scaleInProgress = true diff --git a/platform/android/java/lib/src/org/godotengine/godot/input/GodotInputHandler.java b/platform/android/java/lib/src/org/godotengine/godot/input/GodotInputHandler.java index d2f3c5aed2..2f26497cc8 100644 --- a/platform/android/java/lib/src/org/godotengine/godot/input/GodotInputHandler.java +++ b/platform/android/java/lib/src/org/godotengine/godot/input/GodotInputHandler.java @@ -245,7 +245,7 @@ public class GodotInputHandler implements InputManager.InputDeviceListener { } return true; } - } else if (isMouseEvent(event)) { + } else { return handleMouseEvent(event); } @@ -473,6 +473,9 @@ public class GodotInputHandler implements InputManager.InputDeviceListener { } static boolean handleMouseEvent(int eventAction, int buttonsMask, float x, float y, float deltaX, float deltaY, boolean doubleClick, boolean sourceMouseRelative) { + // We don't handle ACTION_BUTTON_PRESS and ACTION_BUTTON_RELEASE events as they typically + // follow ACTION_DOWN and ACTION_UP events. As such, handling them would result in duplicate + // stream of events to the engine. switch (eventAction) { case MotionEvent.ACTION_CANCEL: case MotionEvent.ACTION_UP: diff --git a/platform/android/java_godot_view_wrapper.cpp b/platform/android/java_godot_view_wrapper.cpp index 762840a4b1..378a467772 100644 --- a/platform/android/java_godot_view_wrapper.cpp +++ b/platform/android/java_godot_view_wrapper.cpp @@ -68,7 +68,7 @@ void GodotJavaViewWrapper::request_pointer_capture() { } void GodotJavaViewWrapper::release_pointer_capture() { - if (_request_pointer_capture != nullptr) { + if (_release_pointer_capture != nullptr) { JNIEnv *env = get_jni_env(); ERR_FAIL_NULL(env); diff --git a/platform/android/os_android.cpp b/platform/android/os_android.cpp index 4469c7a0f7..97fa90b1d2 100644 --- a/platform/android/os_android.cpp +++ b/platform/android/os_android.cpp @@ -162,11 +162,16 @@ Vector<String> OS_Android::get_granted_permissions() const { } Error OS_Android::open_dynamic_library(const String p_path, void *&p_library_handle, bool p_also_set_library_path, String *r_resolved_path) { - p_library_handle = dlopen(p_path.utf8().get_data(), RTLD_NOW); + String path = p_path; + if (!FileAccess::exists(path)) { + path = p_path.get_file(); + } + + p_library_handle = dlopen(path.utf8().get_data(), RTLD_NOW); ERR_FAIL_NULL_V_MSG(p_library_handle, ERR_CANT_OPEN, "Can't open dynamic library: " + p_path + ", error: " + dlerror() + "."); if (r_resolved_path != nullptr) { - *r_resolved_path = p_path; + *r_resolved_path = path; } return OK; diff --git a/platform/ios/display_server_ios.mm b/platform/ios/display_server_ios.mm index 8808d8e842..6793b40dd4 100644 --- a/platform/ios/display_server_ios.mm +++ b/platform/ios/display_server_ios.mm @@ -227,7 +227,7 @@ void DisplayServerIOS::_window_callback(const Callable &p_callable, const Varian // MARK: Touches void DisplayServerIOS::touch_press(int p_idx, int p_x, int p_y, bool p_pressed, bool p_double_click) { - if (!GLOBAL_DEF("debug/disable_touch", false)) { + if (!GLOBAL_GET("debug/disable_touch")) { Ref<InputEventScreenTouch> ev; ev.instantiate(); @@ -240,7 +240,7 @@ void DisplayServerIOS::touch_press(int p_idx, int p_x, int p_y, bool p_pressed, } void DisplayServerIOS::touch_drag(int p_idx, int p_prev_x, int p_prev_y, int p_x, int p_y) { - if (!GLOBAL_DEF("debug/disable_touch", false)) { + if (!GLOBAL_GET("debug/disable_touch")) { Ref<InputEventScreenDrag> ev; ev.instantiate(); ev->set_index(p_idx); diff --git a/scene/2d/gpu_particles_2d.cpp b/scene/2d/gpu_particles_2d.cpp index 9786b01058..e18f2bd1a1 100644 --- a/scene/2d/gpu_particles_2d.cpp +++ b/scene/2d/gpu_particles_2d.cpp @@ -141,16 +141,16 @@ void GPUParticles2D::set_process_material(const Ref<Material> &p_material) { void GPUParticles2D::set_trail_enabled(bool p_enabled) { trail_enabled = p_enabled; - RS::get_singleton()->particles_set_trails(particles, trail_enabled, trail_length); + RS::get_singleton()->particles_set_trails(particles, trail_enabled, trail_lifetime); queue_redraw(); RS::get_singleton()->particles_set_transform_align(particles, p_enabled ? RS::PARTICLES_TRANSFORM_ALIGN_Y_TO_VELOCITY : RS::PARTICLES_TRANSFORM_ALIGN_DISABLED); } -void GPUParticles2D::set_trail_length(double p_seconds) { +void GPUParticles2D::set_trail_lifetime(double p_seconds) { ERR_FAIL_COND(p_seconds < 0.001); - trail_length = p_seconds; - RS::get_singleton()->particles_set_trails(particles, trail_enabled, trail_length); + trail_lifetime = p_seconds; + RS::get_singleton()->particles_set_trails(particles, trail_enabled, trail_lifetime); queue_redraw(); } @@ -181,8 +181,8 @@ bool GPUParticles2D::is_trail_enabled() const { return trail_enabled; } -double GPUParticles2D::get_trail_length() const { - return trail_length; +double GPUParticles2D::get_trail_lifetime() const { + return trail_lifetime; } void GPUParticles2D::_update_collision_size() { @@ -614,10 +614,10 @@ void GPUParticles2D::_bind_methods() { ClassDB::bind_method(D_METHOD("emit_particle", "xform", "velocity", "color", "custom", "flags"), &GPUParticles2D::emit_particle); ClassDB::bind_method(D_METHOD("set_trail_enabled", "enabled"), &GPUParticles2D::set_trail_enabled); - ClassDB::bind_method(D_METHOD("set_trail_length", "secs"), &GPUParticles2D::set_trail_length); + ClassDB::bind_method(D_METHOD("set_trail_lifetime", "secs"), &GPUParticles2D::set_trail_lifetime); ClassDB::bind_method(D_METHOD("is_trail_enabled"), &GPUParticles2D::is_trail_enabled); - ClassDB::bind_method(D_METHOD("get_trail_length"), &GPUParticles2D::get_trail_length); + ClassDB::bind_method(D_METHOD("get_trail_lifetime"), &GPUParticles2D::get_trail_lifetime); ClassDB::bind_method(D_METHOD("set_trail_sections", "sections"), &GPUParticles2D::set_trail_sections); ClassDB::bind_method(D_METHOD("get_trail_sections"), &GPUParticles2D::get_trail_sections); @@ -647,7 +647,7 @@ void GPUParticles2D::_bind_methods() { ADD_PROPERTY(PropertyInfo(Variant::INT, "draw_order", PROPERTY_HINT_ENUM, "Index,Lifetime,Reverse Lifetime"), "set_draw_order", "get_draw_order"); ADD_GROUP("Trails", "trail_"); ADD_PROPERTY(PropertyInfo(Variant::BOOL, "trail_enabled"), "set_trail_enabled", "is_trail_enabled"); - ADD_PROPERTY(PropertyInfo(Variant::FLOAT, "trail_length_secs", PROPERTY_HINT_RANGE, "0.01,10,0.01,suffix:s"), "set_trail_length", "get_trail_length"); + ADD_PROPERTY(PropertyInfo(Variant::FLOAT, "trail_lifetime", PROPERTY_HINT_RANGE, "0.01,10,0.01,or_greater,suffix:s"), "set_trail_lifetime", "get_trail_lifetime"); ADD_PROPERTY(PropertyInfo(Variant::INT, "trail_sections", PROPERTY_HINT_RANGE, "2,128,1"), "set_trail_sections", "get_trail_sections"); ADD_PROPERTY(PropertyInfo(Variant::INT, "trail_section_subdivisions", PROPERTY_HINT_RANGE, "1,1024,1"), "set_trail_section_subdivisions", "get_trail_section_subdivisions"); ADD_GROUP("Process Material", "process_"); diff --git a/scene/2d/gpu_particles_2d.h b/scene/2d/gpu_particles_2d.h index d613b4ef51..7fba174357 100644 --- a/scene/2d/gpu_particles_2d.h +++ b/scene/2d/gpu_particles_2d.h @@ -74,7 +74,7 @@ private: real_t collision_base_size = 1.0; bool trail_enabled = false; - double trail_length = 0.3; + double trail_lifetime = 0.3; int trail_sections = 8; int trail_section_subdivisions = 4; @@ -104,7 +104,7 @@ public: void set_speed_scale(double p_scale); void set_collision_base_size(real_t p_ratio); void set_trail_enabled(bool p_enabled); - void set_trail_length(double p_seconds); + void set_trail_lifetime(double p_seconds); void set_trail_sections(int p_sections); void set_trail_section_subdivisions(int p_subdivisions); @@ -126,7 +126,7 @@ public: real_t get_collision_base_size() const; bool is_trail_enabled() const; - double get_trail_length() const; + double get_trail_lifetime() const; int get_trail_sections() const; int get_trail_section_subdivisions() const; diff --git a/scene/3d/gpu_particles_3d.cpp b/scene/3d/gpu_particles_3d.cpp index dbbf196f7a..9d04202c2d 100644 --- a/scene/3d/gpu_particles_3d.cpp +++ b/scene/3d/gpu_particles_3d.cpp @@ -176,22 +176,22 @@ void GPUParticles3D::set_draw_order(DrawOrder p_order) { void GPUParticles3D::set_trail_enabled(bool p_enabled) { trail_enabled = p_enabled; - RS::get_singleton()->particles_set_trails(particles, trail_enabled, trail_length); + RS::get_singleton()->particles_set_trails(particles, trail_enabled, trail_lifetime); update_configuration_warnings(); } -void GPUParticles3D::set_trail_length(double p_seconds) { +void GPUParticles3D::set_trail_lifetime(double p_seconds) { ERR_FAIL_COND(p_seconds < 0.001); - trail_length = p_seconds; - RS::get_singleton()->particles_set_trails(particles, trail_enabled, trail_length); + trail_lifetime = p_seconds; + RS::get_singleton()->particles_set_trails(particles, trail_enabled, trail_lifetime); } bool GPUParticles3D::is_trail_enabled() const { return trail_enabled; } -double GPUParticles3D::get_trail_length() const { - return trail_length; +double GPUParticles3D::get_trail_lifetime() const { + return trail_lifetime; } GPUParticles3D::DrawOrder GPUParticles3D::get_draw_order() const { @@ -552,10 +552,10 @@ void GPUParticles3D::_bind_methods() { ClassDB::bind_method(D_METHOD("emit_particle", "xform", "velocity", "color", "custom", "flags"), &GPUParticles3D::emit_particle); ClassDB::bind_method(D_METHOD("set_trail_enabled", "enabled"), &GPUParticles3D::set_trail_enabled); - ClassDB::bind_method(D_METHOD("set_trail_length", "secs"), &GPUParticles3D::set_trail_length); + ClassDB::bind_method(D_METHOD("set_trail_lifetime", "secs"), &GPUParticles3D::set_trail_lifetime); ClassDB::bind_method(D_METHOD("is_trail_enabled"), &GPUParticles3D::is_trail_enabled); - ClassDB::bind_method(D_METHOD("get_trail_length"), &GPUParticles3D::get_trail_length); + ClassDB::bind_method(D_METHOD("get_trail_lifetime"), &GPUParticles3D::get_trail_lifetime); ClassDB::bind_method(D_METHOD("set_transform_align", "align"), &GPUParticles3D::set_transform_align); ClassDB::bind_method(D_METHOD("get_transform_align"), &GPUParticles3D::get_transform_align); @@ -583,7 +583,7 @@ void GPUParticles3D::_bind_methods() { ADD_PROPERTY(PropertyInfo(Variant::INT, "transform_align", PROPERTY_HINT_ENUM, "Disabled,Z-Billboard,Y to Velocity,Z-Billboard + Y to Velocity"), "set_transform_align", "get_transform_align"); ADD_GROUP("Trails", "trail_"); ADD_PROPERTY(PropertyInfo(Variant::BOOL, "trail_enabled"), "set_trail_enabled", "is_trail_enabled"); - ADD_PROPERTY(PropertyInfo(Variant::FLOAT, "trail_length_secs", PROPERTY_HINT_RANGE, "0.01,10,0.01,suffix:s"), "set_trail_length", "get_trail_length"); + ADD_PROPERTY(PropertyInfo(Variant::FLOAT, "trail_lifetime", PROPERTY_HINT_RANGE, "0.01,10,0.01,or_greater,suffix:s"), "set_trail_lifetime", "get_trail_lifetime"); ADD_GROUP("Process Material", ""); ADD_PROPERTY(PropertyInfo(Variant::OBJECT, "process_material", PROPERTY_HINT_RESOURCE_TYPE, "ShaderMaterial,ParticleProcessMaterial"), "set_process_material", "get_process_material"); ADD_GROUP("Draw Passes", "draw_"); @@ -627,7 +627,7 @@ GPUParticles3D::GPUParticles3D() { set_pre_process_time(0); set_explosiveness_ratio(0); set_randomness_ratio(0); - set_trail_length(0.3); + set_trail_lifetime(0.3); set_visibility_aabb(AABB(Vector3(-4, -4, -4), Vector3(8, 8, 8))); set_use_local_coordinates(false); set_draw_passes(1); diff --git a/scene/3d/gpu_particles_3d.h b/scene/3d/gpu_particles_3d.h index ef92218e4d..835d71862a 100644 --- a/scene/3d/gpu_particles_3d.h +++ b/scene/3d/gpu_particles_3d.h @@ -76,7 +76,7 @@ private: real_t collision_base_size = 0.01; bool trail_enabled = false; - double trail_length = 0.3; + double trail_lifetime = 0.3; TransformAlign transform_align = TRANSFORM_ALIGN_DISABLED; @@ -112,7 +112,7 @@ public: void set_speed_scale(double p_scale); void set_collision_base_size(real_t p_ratio); void set_trail_enabled(bool p_enabled); - void set_trail_length(double p_seconds); + void set_trail_lifetime(double p_seconds); bool is_emitting() const; int get_amount() const; @@ -127,7 +127,7 @@ public: double get_speed_scale() const; real_t get_collision_base_size() const; bool is_trail_enabled() const; - double get_trail_length() const; + double get_trail_lifetime() const; void set_fixed_fps(int p_count); int get_fixed_fps() const; diff --git a/scene/gui/item_list.cpp b/scene/gui/item_list.cpp index d6b5557a3f..82f089735d 100644 --- a/scene/gui/item_list.cpp +++ b/scene/gui/item_list.cpp @@ -896,7 +896,7 @@ void ItemList::gui_input(const Ref<InputEvent> &p_event) { if (k.is_valid() && k->get_unicode()) { uint64_t now = OS::get_singleton()->get_ticks_msec(); uint64_t diff = now - search_time_msec; - uint64_t max_interval = uint64_t(GLOBAL_DEF("gui/timers/incremental_search_max_interval_msec", 2000)); + uint64_t max_interval = uint64_t(GLOBAL_GET("gui/timers/incremental_search_max_interval_msec")); search_time_msec = now; if (diff > max_interval) { @@ -1831,9 +1831,6 @@ void ItemList::_bind_methods() { ADD_SIGNAL(MethodInfo("item_clicked", PropertyInfo(Variant::INT, "index"), PropertyInfo(Variant::VECTOR2, "at_position"), PropertyInfo(Variant::INT, "mouse_button_index"))); ADD_SIGNAL(MethodInfo("multi_selected", PropertyInfo(Variant::INT, "index"), PropertyInfo(Variant::BOOL, "selected"))); ADD_SIGNAL(MethodInfo("item_activated", PropertyInfo(Variant::INT, "index"))); - - GLOBAL_DEF("gui/timers/incremental_search_max_interval_msec", 2000); - ProjectSettings::get_singleton()->set_custom_property_info("gui/timers/incremental_search_max_interval_msec", PropertyInfo(Variant::INT, "gui/timers/incremental_search_max_interval_msec", PROPERTY_HINT_RANGE, "0,10000,1,or_greater")); // No negative numbers } ItemList::ItemList() { diff --git a/scene/gui/popup_menu.cpp b/scene/gui/popup_menu.cpp index 9a411ef7ed..82f56a56c9 100644 --- a/scene/gui/popup_menu.cpp +++ b/scene/gui/popup_menu.cpp @@ -472,7 +472,7 @@ void PopupMenu::gui_input(const Ref<InputEvent> &p_event) { if (allow_search && k.is_valid() && k->get_unicode() && k->is_pressed()) { uint64_t now = OS::get_singleton()->get_ticks_msec(); uint64_t diff = now - search_time_msec; - uint64_t max_interval = uint64_t(GLOBAL_DEF("gui/timers/incremental_search_max_interval_msec", 2000)); + uint64_t max_interval = uint64_t(GLOBAL_GET("gui/timers/incremental_search_max_interval_msec")); search_time_msec = now; if (diff > max_interval) { diff --git a/scene/gui/tree.cpp b/scene/gui/tree.cpp index 6f9a9a5141..1c96858da7 100644 --- a/scene/gui/tree.cpp +++ b/scene/gui/tree.cpp @@ -4818,7 +4818,7 @@ TreeItem *Tree::get_item_with_text(const String &p_find) const { void Tree::_do_incr_search(const String &p_add) { uint64_t time = OS::get_singleton()->get_ticks_usec() / 1000; // convert to msec uint64_t diff = time - last_keypress; - if (diff > uint64_t(GLOBAL_DEF("gui/timers/incremental_search_max_interval_msec", 2000))) { + if (diff > uint64_t(GLOBAL_GET("gui/timers/incremental_search_max_interval_msec"))) { incr_search = p_add; } else if (incr_search != p_add) { incr_search += p_add; diff --git a/scene/resources/shape_2d.cpp b/scene/resources/shape_2d.cpp index 61daf801e8..af84144591 100644 --- a/scene/resources/shape_2d.cpp +++ b/scene/resources/shape_2d.cpp @@ -116,7 +116,7 @@ bool Shape2D::is_collision_outline_enabled() { return true; } #endif - return GLOBAL_DEF("debug/shapes/collision/draw_2d_outlines", true); + return GLOBAL_GET("debug/shapes/collision/draw_2d_outlines"); } Shape2D::Shape2D(const RID &p_rid) { diff --git a/servers/physics_2d/godot_space_2d.cpp b/servers/physics_2d/godot_space_2d.cpp index a82d7dbbc4..89afb0e2a0 100644 --- a/servers/physics_2d/godot_space_2d.cpp +++ b/servers/physics_2d/godot_space_2d.cpp @@ -1225,7 +1225,7 @@ GodotSpace2D::GodotSpace2D() { ProjectSettings::get_singleton()->set_custom_property_info("physics/2d/solver/solver_iterations", PropertyInfo(Variant::INT, "physics/2d/solver/solver_iterations", PROPERTY_HINT_RANGE, "1,32,1,or_greater")); contact_recycle_radius = GLOBAL_DEF("physics/2d/solver/contact_recycle_radius", 1.0); - ProjectSettings::get_singleton()->set_custom_property_info("physics/2d/solver/contact_recycle_radius", PropertyInfo(Variant::FLOAT, "physics/2d/solver/contact_max_separation", PROPERTY_HINT_RANGE, "0,10,0.01,or_greater")); + ProjectSettings::get_singleton()->set_custom_property_info("physics/2d/solver/contact_recycle_radius", PropertyInfo(Variant::FLOAT, "physics/2d/solver/contact_recycle_radius", PROPERTY_HINT_RANGE, "0,10,0.01,or_greater")); contact_max_separation = GLOBAL_DEF("physics/2d/solver/contact_max_separation", 1.5); ProjectSettings::get_singleton()->set_custom_property_info("physics/2d/solver/contact_max_separation", PropertyInfo(Variant::FLOAT, "physics/2d/solver/contact_max_separation", PROPERTY_HINT_RANGE, "0,10,0.01,or_greater")); diff --git a/servers/physics_3d/godot_space_3d.cpp b/servers/physics_3d/godot_space_3d.cpp index c23485279d..c98409e2c4 100644 --- a/servers/physics_3d/godot_space_3d.cpp +++ b/servers/physics_3d/godot_space_3d.cpp @@ -1258,7 +1258,7 @@ GodotSpace3D::GodotSpace3D() { ProjectSettings::get_singleton()->set_custom_property_info("physics/3d/solver/solver_iterations", PropertyInfo(Variant::INT, "physics/3d/solver/solver_iterations", PROPERTY_HINT_RANGE, "1,32,1,or_greater")); contact_recycle_radius = GLOBAL_DEF("physics/3d/solver/contact_recycle_radius", 0.01); - ProjectSettings::get_singleton()->set_custom_property_info("physics/3d/solver/contact_recycle_radius", PropertyInfo(Variant::FLOAT, "physics/3d/solver/contact_max_separation", PROPERTY_HINT_RANGE, "0,0.1,0.01,or_greater")); + ProjectSettings::get_singleton()->set_custom_property_info("physics/3d/solver/contact_recycle_radius", PropertyInfo(Variant::FLOAT, "physics/3d/solver/contact_recycle_radius", PROPERTY_HINT_RANGE, "0,0.1,0.01,or_greater")); contact_max_separation = GLOBAL_DEF("physics/3d/solver/contact_max_separation", 0.05); ProjectSettings::get_singleton()->set_custom_property_info("physics/3d/solver/contact_max_separation", PropertyInfo(Variant::FLOAT, "physics/3d/solver/contact_max_separation", PROPERTY_HINT_RANGE, "0,0.1,0.01,or_greater")); diff --git a/servers/rendering/renderer_rd/storage_rd/particles_storage.cpp b/servers/rendering/renderer_rd/storage_rd/particles_storage.cpp index 7fa0bb64a3..854976692e 100644 --- a/servers/rendering/renderer_rd/storage_rd/particles_storage.cpp +++ b/servers/rendering/renderer_rd/storage_rd/particles_storage.cpp @@ -425,7 +425,7 @@ void ParticlesStorage::particles_set_trails(RID p_particles, bool p_enable, doub p_length = MIN(10.0, p_length); particles->trails_enabled = p_enable; - particles->trail_length = p_length; + particles->trail_lifetime = p_length; _particles_free_data(particles); @@ -1351,7 +1351,7 @@ void ParticlesStorage::update_particles() { int history_size = 1; int trail_steps = 1; if (particles->trails_enabled && particles->trail_bind_poses.size() > 1) { - history_size = MAX(1, int(particles->trail_length * fixed_fps)); + history_size = MAX(1, int(particles->trail_lifetime * fixed_fps)); trail_steps = particles->trail_bind_poses.size(); } diff --git a/servers/rendering/renderer_rd/storage_rd/particles_storage.h b/servers/rendering/renderer_rd/storage_rd/particles_storage.h index 017844626f..6478e2b5dc 100644 --- a/servers/rendering/renderer_rd/storage_rd/particles_storage.h +++ b/servers/rendering/renderer_rd/storage_rd/particles_storage.h @@ -232,7 +232,7 @@ private: Dependency dependency; - double trail_length = 1.0; + double trail_lifetime = 0.3; bool trails_enabled = false; LocalVector<ParticlesFrameParams> frame_history; LocalVector<ParticlesFrameParams> trail_params; diff --git a/servers/rendering_server.cpp b/servers/rendering_server.cpp index cf30d377b7..0c4d641a6f 100644 --- a/servers/rendering_server.cpp +++ b/servers/rendering_server.cpp @@ -2871,14 +2871,6 @@ void RenderingServer::init() { GLOBAL_DEF("rendering/2d/shadow_atlas/size", 2048); - // Already defined in some RenderingDevice*::initialize, which run before this code. - // We re-define them here just for doctool's sake. Make sure to keep default values in sync. - GLOBAL_DEF("rendering/rendering_device/staging_buffer/block_size_kb", 256); - GLOBAL_DEF("rendering/rendering_device/staging_buffer/max_size_mb", 128); - GLOBAL_DEF("rendering/rendering_device/staging_buffer/texture_upload_region_size_px", 64); - // Vulkan-specific. - GLOBAL_DEF("rendering/rendering_device/vulkan/max_descriptors_per_pool", 64); - // Number of commands that can be drawn per frame. GLOBAL_DEF_RST("rendering/gl_compatibility/item_buffer_size", 16384); ProjectSettings::get_singleton()->set_custom_property_info("rendering/gl_compatibility/item_buffer_size", PropertyInfo(Variant::INT, "rendering/gl_compatibility/item_buffer_size", PROPERTY_HINT_RANGE, "1024,1048576,1")); @@ -2981,7 +2973,6 @@ void RenderingServer::init() { ProjectSettings::get_singleton()->set_custom_property_info("rendering/textures/light_projectors/filter", PropertyInfo(Variant::INT, "rendering/textures/light_projectors/filter", PROPERTY_HINT_ENUM, "Nearest (Fast),Linear (Fast),Nearest Mipmap (Fast),Linear Mipmap (Fast),Nearest Mipmap Anisotropic (Average),Linear Mipmap Anisotropic (Average)")); GLOBAL_DEF_RST("rendering/occlusion_culling/occlusion_rays_per_thread", 512); - GLOBAL_DEF_RST("rendering/occlusion_culling/bvh_build_quality", 2); ProjectSettings::get_singleton()->set_custom_property_info("rendering/occlusion_culling/bvh_build_quality", PropertyInfo(Variant::INT, "rendering/occlusion_culling/bvh_build_quality", PROPERTY_HINT_ENUM, "Low,Medium,High")); GLOBAL_DEF("rendering/environment/glow/upscale_mode", 1); diff --git a/tests/test_main.cpp b/tests/test_main.cpp index cee110414e..d58c19ac32 100644 --- a/tests/test_main.cpp +++ b/tests/test_main.cpp @@ -192,11 +192,8 @@ struct GodotTestCaseListener : public doctest::IReporter { String name = String(p_in.m_name); if (name.find("[SceneTree]") != -1) { - GLOBAL_DEF("memory/limits/multithreaded_server/rid_pool_prealloc", 60); memnew(MessageQueue); - GLOBAL_DEF("internationalization/rendering/force_right_to_left_layout_direction", false); - memnew(Input); Error err = OK; |