diff options
Diffstat (limited to 'core')
30 files changed, 274 insertions, 85 deletions
diff --git a/core/config/project_settings.cpp b/core/config/project_settings.cpp index f37e7f5956..0e15edc29f 100644 --- a/core/config/project_settings.cpp +++ b/core/config/project_settings.cpp @@ -41,6 +41,9 @@ #include "core/os/keyboard.h" #include "core/os/os.h" #include "core/variant/variant_parser.h" +#include "core/version.h" + +#include "modules/modules_enabled.gen.h" // For mono. const String ProjectSettings::PROJECT_DATA_DIR_NAME_SUFFIX = "godot"; @@ -62,10 +65,81 @@ String ProjectSettings::get_resource_path() const { return resource_path; } +String ProjectSettings::get_safe_project_name() const { + String safe_name = OS::get_singleton()->get_safe_dir_name(get("application/config/name")); + if (safe_name.is_empty()) { + safe_name = "UnnamedProject"; + } + return safe_name; +} + String ProjectSettings::get_imported_files_path() const { return get_project_data_path().plus_file("imported"); } +// Returns the features that a project must have when opened with this build of Godot. +// This is used by the project manager to provide the initial_settings for config/features. +const PackedStringArray ProjectSettings::get_required_features() { + PackedStringArray features = PackedStringArray(); + features.append(VERSION_BRANCH); +#ifdef REAL_T_IS_DOUBLE + features.append("Double Precision"); +#endif + return features; +} + +// Returns the features supported by this build of Godot. Includes all required features. +const PackedStringArray ProjectSettings::_get_supported_features() { + PackedStringArray features = get_required_features(); +#ifdef MODULE_MONO_ENABLED + features.append("C#"); +#endif + // Allow pinning to a specific patch number or build type by marking + // them as supported. They're only used if the user adds them manually. + features.append(VERSION_BRANCH "." _MKSTR(VERSION_PATCH)); + features.append(VERSION_FULL_CONFIG); + features.append(VERSION_FULL_BUILD); + // For now, assume Vulkan is always supported. + // This should be removed if it's possible to build the editor without Vulkan. + features.append("Vulkan Clustered"); + features.append("Vulkan Mobile"); + return features; +} + +// Returns the features that this project needs but this build of Godot lacks. +const PackedStringArray ProjectSettings::get_unsupported_features(const PackedStringArray &p_project_features) { + PackedStringArray unsupported_features = PackedStringArray(); + PackedStringArray supported_features = singleton->_get_supported_features(); + for (int i = 0; i < p_project_features.size(); i++) { + if (!supported_features.has(p_project_features[i])) { + unsupported_features.append(p_project_features[i]); + } + } + unsupported_features.sort(); + return unsupported_features; +} + +// Returns the features that both this project has and this build of Godot has, ensuring required features exist. +const PackedStringArray ProjectSettings::_trim_to_supported_features(const PackedStringArray &p_project_features) { + // Remove unsupported features if present. + PackedStringArray features = PackedStringArray(p_project_features); + PackedStringArray supported_features = _get_supported_features(); + for (int i = p_project_features.size() - 1; i > -1; i--) { + if (!supported_features.has(p_project_features[i])) { + features.remove_at(i); + } + } + // Add required features if not present. + PackedStringArray required_features = get_required_features(); + for (int i = 0; i < required_features.size(); i++) { + if (!features.has(required_features[i])) { + features.append(required_features[i]); + } + } + features.sort(); + return features; +} + String ProjectSettings::localize_path(const String &p_path) const { if (resource_path.is_empty() || p_path.begins_with("res://") || p_path.begins_with("user://") || (p_path.is_absolute_path() && !p_path.begins_with(resource_path))) { @@ -368,12 +442,12 @@ void ProjectSettings::_convert_to_last_version(int p_from_version) { * If a project file is found, load it or fail. * If nothing was found, error out. */ -Error ProjectSettings::_setup(const String &p_path, const String &p_main_pack, bool p_upwards) { +Error ProjectSettings::_setup(const String &p_path, const String &p_main_pack, bool p_upwards, bool p_ignore_override) { // If looking for files in a network client, use it directly if (FileAccessNetworkClient::get_singleton()) { Error err = _load_settings_text_or_binary("res://project.godot", "res://project.binary"); - if (err == OK) { + if (err == OK && !p_ignore_override) { // Optional, we don't mind if it fails _load_settings_text("res://override.cfg"); } @@ -387,7 +461,7 @@ Error ProjectSettings::_setup(const String &p_path, const String &p_main_pack, b ERR_FAIL_COND_V_MSG(!ok, ERR_CANT_OPEN, "Cannot open resource pack '" + p_main_pack + "'."); Error err = _load_settings_text_or_binary("res://project.godot", "res://project.binary"); - if (err == OK) { + if (err == OK && !p_ignore_override) { // Load override from location of the main pack // Optional, we don't mind if it fails _load_settings_text(p_main_pack.get_base_dir().plus_file("override.cfg")); @@ -437,7 +511,7 @@ Error ProjectSettings::_setup(const String &p_path, const String &p_main_pack, b // If we opened our package, try and load our project. if (found) { Error err = _load_settings_text_or_binary("res://project.godot", "res://project.binary"); - if (err == OK) { + if (err == OK && !p_ignore_override) { // Load override from location of the executable. // Optional, we don't mind if it fails. _load_settings_text(exec_path.get_base_dir().plus_file("override.cfg")); @@ -458,7 +532,7 @@ Error ProjectSettings::_setup(const String &p_path, const String &p_main_pack, b } Error err = _load_settings_text_or_binary("res://project.godot", "res://project.binary"); - if (err == OK) { + if (err == OK && !p_ignore_override) { // Optional, we don't mind if it fails. _load_settings_text("res://override.cfg"); } @@ -481,7 +555,7 @@ Error ProjectSettings::_setup(const String &p_path, const String &p_main_pack, b resource_path = current_dir; resource_path = resource_path.replace("\\", "/"); // Windows path to Unix path just in case. err = _load_settings_text_or_binary(current_dir.plus_file("project.godot"), current_dir.plus_file("project.binary")); - if (err == OK) { + if (err == OK && !p_ignore_override) { // Optional, we don't mind if it fails. _load_settings_text(current_dir.plus_file("override.cfg")); found = true; @@ -513,8 +587,8 @@ Error ProjectSettings::_setup(const String &p_path, const String &p_main_pack, b return OK; } -Error ProjectSettings::setup(const String &p_path, const String &p_main_pack, bool p_upwards) { - Error err = _setup(p_path, p_main_pack, p_upwards); +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", ""); if (custom_settings != "") { @@ -666,6 +740,13 @@ Error ProjectSettings::_load_settings_text_or_binary(const String &p_text_path, return err; } +Error ProjectSettings::load_custom(const String &p_path) { + if (p_path.ends_with(".binary")) { + return _load_settings_binary(p_path); + } + return _load_settings_text(p_path); +} + int ProjectSettings::get_order(const String &p_name) const { ERR_FAIL_COND_V_MSG(!props.has(p_name), -1, "Request for nonexistent project setting: " + p_name + "."); return props[p_name].order; @@ -845,6 +926,34 @@ Error ProjectSettings::_save_custom_bnd(const String &p_file) { // add other par Error ProjectSettings::save_custom(const String &p_path, const CustomMap &p_custom, const Vector<String> &p_custom_features, bool p_merge_with_current) { ERR_FAIL_COND_V_MSG(p_path == "", ERR_INVALID_PARAMETER, "Project settings save path cannot be empty."); + PackedStringArray project_features = has_setting("application/config/features") ? (PackedStringArray)get_setting("application/config/features") : PackedStringArray(); + // If there is no feature list currently present, force one to generate. + if (project_features.is_empty()) { + project_features = ProjectSettings::get_required_features(); + } + // Check the rendering API. + const String rendering_api = has_setting("rendering/quality/driver/driver_name") ? (String)get_setting("rendering/quality/driver/driver_name") : String(); + if (rendering_api != "") { + // Add the rendering API as a project feature if it doesn't already exist. + if (!project_features.has(rendering_api)) { + project_features.append(rendering_api); + } + } + // Check for the existence of a csproj file. + if (FileAccess::exists(get_resource_path().plus_file(get_safe_project_name() + ".csproj"))) { + // If there is a csproj file, add the C# feature if it doesn't already exist. + if (!project_features.has("C#")) { + project_features.append("C#"); + } + } else { + // If there isn't a csproj file, remove the C# feature if it exists. + if (project_features.has("C#")) { + project_features.remove_at(project_features.find("C#")); + } + } + project_features = _trim_to_supported_features(project_features); + set_setting("application/config/features", project_features); + Set<_VCSort> vclist; if (p_merge_with_current) { diff --git a/core/config/project_settings.h b/core/config/project_settings.h index ca37401751..5b74356337 100644 --- a/core/config/project_settings.h +++ b/core/config/project_settings.h @@ -48,6 +48,8 @@ public: //properties that are not for built in values begin from this value, so builtin ones are displayed first NO_BUILTIN_ORDER_BASE = 1 << 16 }; + const static PackedStringArray get_required_features(); + const static PackedStringArray get_unsupported_features(const PackedStringArray &p_project_features); struct AutoloadInfo { StringName name; @@ -111,13 +113,16 @@ protected: Error _save_custom_bnd(const String &p_file); + const static PackedStringArray _get_supported_features(); + const static PackedStringArray _trim_to_supported_features(const PackedStringArray &p_project_features); + void _convert_to_last_version(int p_from_version); bool _load_resource_pack(const String &p_pack, bool p_replace_files = true, int p_offset = 0); void _add_property_info_bind(const Dictionary &p_info); - Error _setup(const String &p_path, const String &p_main_pack, bool p_upwards = false); + Error _setup(const String &p_path, const String &p_main_pack, bool p_upwards = false, bool p_ignore_override = false); void _add_builtin_input_map(); @@ -125,7 +130,7 @@ protected: static void _bind_methods(); public: - static const int CONFIG_VERSION = 4; + static const int CONFIG_VERSION = 5; void set_setting(const String &p_setting, const Variant &p_value); Variant get_setting(const String &p_setting) const; @@ -146,6 +151,7 @@ public: String get_project_data_dir_name() const; String get_project_data_path() const; String get_resource_path() const; + String get_safe_project_name() const; String get_imported_files_path() const; static ProjectSettings *get_singleton(); @@ -156,8 +162,9 @@ public: void set_builtin_order(const String &p_name); bool is_builtin_setting(const String &p_name) const; - Error setup(const String &p_path, const String &p_main_pack, bool p_upwards = false); + Error setup(const String &p_path, const String &p_main_pack, bool p_upwards = false, bool p_ignore_override = false); + Error load_custom(const String &p_path); Error save_custom(const String &p_path = "", const CustomMap &p_custom = CustomMap(), const Vector<String> &p_custom_features = Vector<String>(), bool p_merge_with_current = true); Error save(); void set_custom_property_info(const String &p_prop, const PropertyInfo &p_info); diff --git a/core/extension/gdnative_interface.cpp b/core/extension/gdnative_interface.cpp index a65408fdda..19988a26cb 100644 --- a/core/extension/gdnative_interface.cpp +++ b/core/extension/gdnative_interface.cpp @@ -783,6 +783,18 @@ static GDNativeVariantPtr gdnative_array_operator_index_const(const GDNativeType return (GDNativeVariantPtr)&self->operator[](p_index); } +/* Dictionary functions */ + +static GDNativeVariantPtr gdnative_dictionary_operator_index(GDNativeTypePtr p_self, const GDNativeVariantPtr p_key) { + Dictionary *self = (Dictionary *)p_self; + return (GDNativeVariantPtr)&self->operator[](*(const Variant *)p_key); +} + +static GDNativeVariantPtr gdnative_dictionary_operator_index_const(const GDNativeTypePtr p_self, const GDNativeVariantPtr p_key) { + const Dictionary *self = (const Dictionary *)p_self; + return (GDNativeVariantPtr)&self->operator[](*(const Variant *)p_key); +} + /* OBJECT API */ static void gdnative_object_method_bind_call(const GDNativeMethodBindPtr p_method_bind, GDNativeObjectPtr p_instance, const GDNativeVariantPtr *p_args, GDNativeInt p_arg_count, GDNativeVariantPtr r_return, GDNativeCallError *r_error) { @@ -1001,6 +1013,11 @@ void gdnative_setup_interface(GDNativeInterface *p_interface) { gdni.array_operator_index = gdnative_array_operator_index; gdni.array_operator_index_const = gdnative_array_operator_index_const; + /* Dictionary functions */ + + gdni.dictionary_operator_index = gdnative_dictionary_operator_index; + gdni.dictionary_operator_index_const = gdnative_dictionary_operator_index_const; + /* OBJECT */ gdni.object_method_bind_call = gdnative_object_method_bind_call; diff --git a/core/extension/gdnative_interface.h b/core/extension/gdnative_interface.h index 8f8cb5a3e0..e411a9d85b 100644 --- a/core/extension/gdnative_interface.h +++ b/core/extension/gdnative_interface.h @@ -417,6 +417,11 @@ typedef struct { GDNativeVariantPtr (*array_operator_index)(GDNativeTypePtr p_self, GDNativeInt p_index); // p_self should be an Array ptr GDNativeVariantPtr (*array_operator_index_const)(const GDNativeTypePtr p_self, GDNativeInt p_index); // p_self should be an Array ptr + /* Dictionary functions */ + + GDNativeVariantPtr (*dictionary_operator_index)(GDNativeTypePtr p_self, const GDNativeVariantPtr p_key); // p_self should be an Dictionary ptr + GDNativeVariantPtr (*dictionary_operator_index_const)(const GDNativeTypePtr p_self, const GDNativeVariantPtr p_key); // p_self should be an Dictionary ptr + /* OBJECT */ void (*object_method_bind_call)(const GDNativeMethodBindPtr p_method_bind, GDNativeObjectPtr p_instance, const GDNativeVariantPtr *p_args, GDNativeInt p_arg_count, GDNativeVariantPtr r_ret, GDNativeCallError *r_error); diff --git a/core/input/input.cpp b/core/input/input.cpp index 6fd8aca01b..342ab3b704 100644 --- a/core/input/input.cpp +++ b/core/input/input.cpp @@ -91,6 +91,7 @@ Input::MouseMode Input::get_mouse_mode() const { void Input::_bind_methods() { ClassDB::bind_method(D_METHOD("is_key_pressed", "keycode"), &Input::is_key_pressed); + ClassDB::bind_method(D_METHOD("is_physical_key_pressed", "keycode"), &Input::is_physical_key_pressed); ClassDB::bind_method(D_METHOD("is_mouse_button_pressed", "button"), &Input::is_mouse_button_pressed); ClassDB::bind_method(D_METHOD("is_joy_button_pressed", "device", "button"), &Input::is_joy_button_pressed); ClassDB::bind_method(D_METHOD("is_action_pressed", "action", "exact_match"), &Input::is_action_pressed, DEFVAL(false)); @@ -223,6 +224,11 @@ bool Input::is_key_pressed(Key p_keycode) const { return keys_pressed.has(p_keycode); } +bool Input::is_physical_key_pressed(Key p_keycode) const { + _THREAD_SAFE_METHOD_ + return physical_keys_pressed.has(p_keycode); +} + bool Input::is_mouse_button_pressed(MouseButton p_button) const { _THREAD_SAFE_METHOD_ return (mouse_button_mask & mouse_button_to_mask(p_button)) != MouseButton::NONE; @@ -465,6 +471,13 @@ void Input::_parse_input_event_impl(const Ref<InputEvent> &p_event, bool p_is_em keys_pressed.erase(k->get_keycode()); } } + if (k.is_valid() && !k->is_echo() && k->get_physical_keycode() != Key::NONE) { + if (k->is_pressed()) { + physical_keys_pressed.insert(k->get_physical_keycode()); + } else { + physical_keys_pressed.erase(k->get_physical_keycode()); + } + } Ref<InputEventMouseButton> mb = p_event; @@ -862,6 +875,7 @@ void Input::release_pressed_events() { flush_buffered_events(); // this is needed to release actions strengths keys_pressed.clear(); + physical_keys_pressed.clear(); joy_buttons_pressed.clear(); _joy_axis.clear(); @@ -1337,7 +1351,7 @@ void Input::add_joy_mapping(String p_mapping, bool p_update_existing) { void Input::remove_joy_mapping(String p_guid) { for (int i = map_db.size() - 1; i >= 0; i--) { if (p_guid == map_db[i].uid) { - map_db.remove(i); + map_db.remove_at(i); } } for (KeyValue<int, Joypad> &E : joy_names) { diff --git a/core/input/input.h b/core/input/input.h index dd57ebb563..faec654a3c 100644 --- a/core/input/input.h +++ b/core/input/input.h @@ -87,6 +87,7 @@ public: private: MouseButton mouse_button_mask = MouseButton::NONE; + Set<Key> physical_keys_pressed; Set<Key> keys_pressed; Set<JoyButton> joy_buttons_pressed; Map<JoyAxis, float> _joy_axis; @@ -247,6 +248,7 @@ public: static Input *get_singleton(); bool is_key_pressed(Key p_keycode) const; + bool is_physical_key_pressed(Key p_keycode) const; bool is_mouse_button_pressed(MouseButton p_button) const; bool is_joy_button_pressed(int p_device, JoyButton p_button) const; bool is_action_pressed(const StringName &p_action, bool p_exact = false) const; diff --git a/core/io/config_file.cpp b/core/io/config_file.cpp index 49fa73dab2..33f992e153 100644 --- a/core/io/config_file.cpp +++ b/core/io/config_file.cpp @@ -183,7 +183,9 @@ Error ConfigFile::_internal_save(FileAccess *file) { if (E != values.front()) { file->store_string("\n"); } - file->store_string("[" + E.key() + "]\n\n"); + if (E.key() != "") { + file->store_string("[" + E.key() + "]\n\n"); + } for (OrderedHashMap<String, Variant>::Element F = E.get().front(); F; F = F.next()) { String vstr; diff --git a/core/io/image.cpp b/core/io/image.cpp index b82e6637b4..3f34de132f 100644 --- a/core/io/image.cpp +++ b/core/io/image.cpp @@ -86,20 +86,14 @@ SaveEXRFunc Image::save_exr_func = nullptr; SavePNGBufferFunc Image::save_png_buffer_func = nullptr; -void Image::_put_pixelb(int p_x, int p_y, uint32_t p_pixelsize, uint8_t *p_data, const uint8_t *p_pixel) { - uint32_t ofs = (p_y * width + p_x) * p_pixelsize; - - for (uint32_t i = 0; i < p_pixelsize; i++) { - p_data[ofs + i] = p_pixel[i]; - } +void Image::_put_pixelb(int p_x, int p_y, uint32_t p_pixel_size, uint8_t *p_data, const uint8_t *p_pixel) { + uint32_t ofs = (p_y * width + p_x) * p_pixel_size; + memcpy(p_data + ofs, p_pixel, p_pixel_size); } -void Image::_get_pixelb(int p_x, int p_y, uint32_t p_pixelsize, const uint8_t *p_data, uint8_t *p_pixel) { - uint32_t ofs = (p_y * width + p_x) * p_pixelsize; - - for (uint32_t i = 0; i < p_pixelsize; i++) { - p_pixel[i] = p_data[ofs + i]; - } +void Image::_get_pixelb(int p_x, int p_y, uint32_t p_pixel_size, const uint8_t *p_data, uint8_t *p_pixel) { + uint32_t ofs = (p_y * width + p_x) * p_pixel_size; + memcpy(p_pixel, p_data + ofs, p_pixel_size); } int Image::get_format_pixel_size(Format p_format) { @@ -2697,24 +2691,55 @@ void Image::blend_rect_mask(const Ref<Image> &p_src, const Ref<Image> &p_mask, c } } -void Image::fill(const Color &c) { +// Repeats `p_pixel` `p_count` times in consecutive memory. +// Results in the original pixel and `p_count - 1` subsequent copies of it. +void Image::_repeat_pixel_over_subsequent_memory(uint8_t *p_pixel, int p_pixel_size, int p_count) { + int offset = 1; + for (int stride = 1; offset + stride <= p_count; stride *= 2) { + memcpy(p_pixel + offset * p_pixel_size, p_pixel, stride * p_pixel_size); + offset += stride; + } + if (offset < p_count) { + memcpy(p_pixel + offset * p_pixel_size, p_pixel, (p_count - offset) * p_pixel_size); + } +} + +void Image::fill(const Color &p_color) { ERR_FAIL_COND_MSG(!_can_modify(format), "Cannot fill in compressed or custom image formats."); - uint8_t *wp = data.ptrw(); - uint8_t *dst_data_ptr = wp; + uint8_t *dst_data_ptr = data.ptrw(); int pixel_size = get_format_pixel_size(format); - // put first pixel with the format-aware API - set_pixel(0, 0, c); + // Put first pixel with the format-aware API. + _set_color_at_ofs(dst_data_ptr, 0, p_color); - for (int y = 0; y < height; y++) { - for (int x = 0; x < width; x++) { - uint8_t *dst = &dst_data_ptr[(y * width + x) * pixel_size]; + _repeat_pixel_over_subsequent_memory(dst_data_ptr, pixel_size, width * height); +} - for (int k = 0; k < pixel_size; k++) { - dst[k] = dst_data_ptr[k]; - } +void Image::fill_rect(const Rect2 &p_rect, const Color &p_color) { + ERR_FAIL_COND_MSG(!_can_modify(format), "Cannot fill rect in compressed or custom image formats."); + + Rect2i r = Rect2i(0, 0, width, height).intersection(p_rect.abs()); + if (r.has_no_area()) { + return; + } + + uint8_t *dst_data_ptr = data.ptrw(); + + int pixel_size = get_format_pixel_size(format); + + // Put first pixel with the format-aware API. + uint8_t *rect_first_pixel_ptr = &dst_data_ptr[(r.position.y * width + r.position.x) * pixel_size]; + _set_color_at_ofs(rect_first_pixel_ptr, 0, p_color); + + if (r.size.x == width) { + // No need to fill rows separately. + _repeat_pixel_over_subsequent_memory(rect_first_pixel_ptr, pixel_size, width * r.size.y); + } else { + _repeat_pixel_over_subsequent_memory(rect_first_pixel_ptr, pixel_size, r.size.x); + for (int y = 1; y < r.size.y; y++) { + memcpy(rect_first_pixel_ptr + y * width * pixel_size, rect_first_pixel_ptr, r.size.x * pixel_size); } } } @@ -3160,6 +3185,7 @@ void Image::_bind_methods() { ClassDB::bind_method(D_METHOD("blend_rect", "src", "src_rect", "dst"), &Image::blend_rect); ClassDB::bind_method(D_METHOD("blend_rect_mask", "src", "mask", "src_rect", "dst"), &Image::blend_rect_mask); ClassDB::bind_method(D_METHOD("fill", "color"), &Image::fill); + ClassDB::bind_method(D_METHOD("fill_rect", "rect", "color"), &Image::fill_rect); ClassDB::bind_method(D_METHOD("get_used_rect"), &Image::get_used_rect); ClassDB::bind_method(D_METHOD("get_rect", "rect"), &Image::get_rect); diff --git a/core/io/image.h b/core/io/image.h index d31a065aa7..9023463b08 100644 --- a/core/io/image.h +++ b/core/io/image.h @@ -190,8 +190,10 @@ private: static int _get_dst_image_size(int p_width, int p_height, Format p_format, int &r_mipmaps, int p_mipmaps = -1, int *r_mm_width = nullptr, int *r_mm_height = nullptr); bool _can_modify(Format p_format) const; - _FORCE_INLINE_ void _put_pixelb(int p_x, int p_y, uint32_t p_pixelsize, uint8_t *p_data, const uint8_t *p_pixel); - _FORCE_INLINE_ void _get_pixelb(int p_x, int p_y, uint32_t p_pixelsize, const uint8_t *p_data, uint8_t *p_pixel); + _FORCE_INLINE_ void _put_pixelb(int p_x, int p_y, uint32_t p_pixel_size, uint8_t *p_data, const uint8_t *p_pixel); + _FORCE_INLINE_ void _get_pixelb(int p_x, int p_y, uint32_t p_pixel_size, const uint8_t *p_data, uint8_t *p_pixel); + + _FORCE_INLINE_ void _repeat_pixel_over_subsequent_memory(uint8_t *p_pixel, int p_pixel_size, int p_count); void _set_data(const Dictionary &p_data); Dictionary _get_data() const; @@ -362,7 +364,8 @@ public: void blit_rect_mask(const Ref<Image> &p_src, const Ref<Image> &p_mask, const Rect2 &p_src_rect, const Point2 &p_dest); void blend_rect(const Ref<Image> &p_src, const Rect2 &p_src_rect, const Point2 &p_dest); void blend_rect_mask(const Ref<Image> &p_src, const Ref<Image> &p_mask, const Rect2 &p_src_rect, const Point2 &p_dest); - void fill(const Color &c); + void fill(const Color &p_color); + void fill_rect(const Rect2 &p_rect, const Color &p_color); Rect2 get_used_rect() const; Ref<Image> get_rect(const Rect2 &p_area) const; diff --git a/core/io/packed_data_container.cpp b/core/io/packed_data_container.cpp index 4a76f0191d..d34b5b6fe3 100644 --- a/core/io/packed_data_container.cpp +++ b/core/io/packed_data_container.cpp @@ -100,6 +100,7 @@ Variant PackedDataContainer::_iter_get_ofs(const Variant &p_iter, uint32_t p_off } Variant PackedDataContainer::_get_at_ofs(uint32_t p_ofs, const uint8_t *p_buf, bool &err) const { + ERR_FAIL_COND_V(p_ofs + 4 > (uint32_t)data.size(), Variant()); uint32_t type = decode_uint32(p_buf + p_ofs); if (type == TYPE_ARRAY || type == TYPE_DICT) { @@ -122,6 +123,7 @@ Variant PackedDataContainer::_get_at_ofs(uint32_t p_ofs, const uint8_t *p_buf, b } uint32_t PackedDataContainer::_type_at_ofs(uint32_t p_ofs) const { + ERR_FAIL_COND_V(p_ofs + 4 > (uint32_t)data.size(), 0); const uint8_t *rd = data.ptr(); ERR_FAIL_COND_V(!rd, 0); const uint8_t *r = &rd[p_ofs]; @@ -131,6 +133,7 @@ uint32_t PackedDataContainer::_type_at_ofs(uint32_t p_ofs) const { } int PackedDataContainer::_size(uint32_t p_ofs) const { + ERR_FAIL_COND_V(p_ofs + 4 > (uint32_t)data.size(), 0); const uint8_t *rd = data.ptr(); ERR_FAIL_COND_V(!rd, 0); const uint8_t *r = &rd[p_ofs]; @@ -149,6 +152,7 @@ int PackedDataContainer::_size(uint32_t p_ofs) const { } Variant PackedDataContainer::_key_at_ofs(uint32_t p_ofs, const Variant &p_key, bool &err) const { + ERR_FAIL_COND_V(p_ofs + 4 > (uint32_t)data.size(), Variant()); const uint8_t *rd = data.ptr(); if (!rd) { err = true; diff --git a/core/math/a_star.cpp b/core/math/a_star.cpp index 1079da75ef..8a44646ef9 100644 --- a/core/math/a_star.cpp +++ b/core/math/a_star.cpp @@ -344,7 +344,7 @@ bool AStar::_solve(Point *begin_point, Point *end_point) { } sorter.pop_heap(0, open_list.size(), open_list.ptrw()); // Remove the current point from the open list - open_list.remove(open_list.size() - 1); + open_list.remove_at(open_list.size() - 1); p->closed_pass = pass; // Mark the point as closed for (OAHashMap<int, Point *>::Iterator it = p->neighbours.iter(); it.valid; it = p->neighbours.next_iter(it)) { @@ -812,7 +812,7 @@ bool AStar2D::_solve(AStar::Point *begin_point, AStar::Point *end_point) { } sorter.pop_heap(0, open_list.size(), open_list.ptrw()); // Remove the current point from the open list - open_list.remove(open_list.size() - 1); + open_list.remove_at(open_list.size() - 1); p->closed_pass = astar.pass; // Mark the point as closed for (OAHashMap<int, AStar::Point *>::Iterator it = p->neighbours.iter(); it.valid; it = p->neighbours.next_iter(it)) { diff --git a/core/math/bvh.h b/core/math/bvh.h index 65b8b102a3..c1eff02178 100644 --- a/core/math/bvh.h +++ b/core/math/bvh.h @@ -654,7 +654,7 @@ private: // remove from changed items (not very efficient yet) for (int n = 0; n < (int)changed_items.size(); n++) { if (changed_items[n] == p_handle) { - changed_items.remove_unordered(n); + changed_items.remove_at_unordered(n); // because we are using an unordered remove, // the last changed item will now be at spot 'n', diff --git a/core/math/bvh_pair.inc b/core/math/bvh_pair.inc index 839db59a3a..a12acec2b6 100644 --- a/core/math/bvh_pair.inc +++ b/core/math/bvh_pair.inc @@ -51,7 +51,7 @@ struct ItemPairs { for (int n = 0; n < num_pairs; n++) { if (extended_pairs[n].handle == h) { userdata = extended_pairs[n].userdata; - extended_pairs.remove_unordered(n); + extended_pairs.remove_at_unordered(n); num_pairs--; break; } diff --git a/core/math/convex_hull.cpp b/core/math/convex_hull.cpp index f6560f1bea..2956e0cf09 100644 --- a/core/math/convex_hull.cpp +++ b/core/math/convex_hull.cpp @@ -1688,7 +1688,7 @@ real_t ConvexHullInternal::shrink(real_t p_amount, real_t p_clamp_amount) { while (stack.size() > 0) { Vertex *v = stack[stack.size() - 1]; - stack.remove(stack.size() - 1); + stack.remove_at(stack.size() - 1); Edge *e = v->edges; if (e) { do { diff --git a/core/math/delaunay_2d.h b/core/math/delaunay_2d.h index 2f80cb5634..779ac96b79 100644 --- a/core/math/delaunay_2d.h +++ b/core/math/delaunay_2d.h @@ -123,7 +123,7 @@ public: for (int j = 0; j < triangles.size(); j++) { if (triangles[j].bad) { - triangles.remove(j); + triangles.remove_at(j); j--; } } @@ -154,7 +154,7 @@ public: } } if (invalid) { - triangles.remove(i); + triangles.remove_at(i); i--; } } diff --git a/core/math/expression.cpp b/core/math/expression.cpp index 05f2c8dac9..f366fd0499 100644 --- a/core/math/expression.cpp +++ b/core/math/expression.cpp @@ -1087,7 +1087,7 @@ Expression::ENode *Expression::_parse_expression() { op->nodes[1] = nullptr; expression.write[i].is_op = false; expression.write[i].node = op; - expression.remove(i + 1); + expression.remove_at(i + 1); } } else { @@ -1119,8 +1119,8 @@ Expression::ENode *Expression::_parse_expression() { //replace all 3 nodes by this operator and make it an expression expression.write[next_op - 1].node = op; - expression.remove(next_op); - expression.remove(next_op); + expression.remove_at(next_op); + expression.remove_at(next_op); } } diff --git a/core/object/undo_redo.cpp b/core/object/undo_redo.cpp index 07006e7968..3459506860 100644 --- a/core/object/undo_redo.cpp +++ b/core/object/undo_redo.cpp @@ -282,7 +282,7 @@ void UndoRedo::_pop_history_tail() { } } - actions.remove(0); + actions.remove_at(0); if (current_action >= 0) { current_action--; } diff --git a/core/string/node_path.cpp b/core/string/node_path.cpp index 5fae13779e..7ab85ac9d0 100644 --- a/core/string/node_path.cpp +++ b/core/string/node_path.cpp @@ -293,12 +293,12 @@ void NodePath::simplify() { break; } if (data->path[i].operator String() == ".") { - data->path.remove(i); + data->path.remove_at(i); i--; } else if (i > 0 && data->path[i].operator String() == ".." && data->path[i - 1].operator String() != "." && data->path[i - 1].operator String() != "..") { //remove both - data->path.remove(i - 1); - data->path.remove(i - 1); + data->path.remove_at(i - 1); + data->path.remove_at(i - 1); i -= 2; if (data->path.size() == 0) { data->path.push_back("."); diff --git a/core/string/ustring.cpp b/core/string/ustring.cpp index 70236231a2..320aae2ba4 100644 --- a/core/string/ustring.cpp +++ b/core/string/ustring.cpp @@ -3670,15 +3670,15 @@ String String::simplify_path() const { for (int i = 0; i < dirs.size(); i++) { String d = dirs[i]; if (d == ".") { - dirs.remove(i); + dirs.remove_at(i); i--; } else if (d == "..") { if (i == 0) { - dirs.remove(i); + dirs.remove_at(i); i--; } else { - dirs.remove(i); - dirs.remove(i - 1); + dirs.remove_at(i); + dirs.remove_at(i - 1); i -= 2; } } diff --git a/core/string/ustring.h b/core/string/ustring.h index 1d80ccf58d..f25c36f66c 100644 --- a/core/string/ustring.h +++ b/core/string/ustring.h @@ -209,7 +209,7 @@ public: _FORCE_INLINE_ char32_t *ptrw() { return _cowdata.ptrw(); } _FORCE_INLINE_ const char32_t *ptr() const { return _cowdata.ptr(); } - void remove(int p_index) { _cowdata.remove(p_index); } + void remove_at(int p_index) { _cowdata.remove_at(p_index); } _FORCE_INLINE_ void clear() { resize(0); } diff --git a/core/templates/bin_sorted_array.h b/core/templates/bin_sorted_array.h index be9d0b5475..8db3e7aeb8 100644 --- a/core/templates/bin_sorted_array.h +++ b/core/templates/bin_sorted_array.h @@ -112,7 +112,7 @@ public: return current_idx; } - void remove(uint64_t p_idx) { + void remove_at(uint64_t p_idx) { ERR_FAIL_COND(p_idx >= array.size()); uint64_t new_idx = move(p_idx, 0); uint64_t swap_idx = array.size() - 1; diff --git a/core/templates/cowdata.h b/core/templates/cowdata.h index 9b8c0eb528..e79ca037db 100644 --- a/core/templates/cowdata.h +++ b/core/templates/cowdata.h @@ -167,7 +167,7 @@ public: Error resize(int p_size); - _FORCE_INLINE_ void remove(int p_index) { + _FORCE_INLINE_ void remove_at(int p_index) { ERR_FAIL_INDEX(p_index, size()); T *p = ptrw(); int len = size(); diff --git a/core/templates/local_vector.h b/core/templates/local_vector.h index 5704b8f230..3854e1e94c 100644 --- a/core/templates/local_vector.h +++ b/core/templates/local_vector.h @@ -70,7 +70,7 @@ public: } } - void remove(U p_index) { + void remove_at(U p_index) { ERR_FAIL_UNSIGNED_INDEX(p_index, count); count--; for (U i = p_index; i < count; i++) { @@ -83,7 +83,7 @@ public: /// Removes the item copying the last value into the position of the one to /// remove. It's generally faster than `remove`. - void remove_unordered(U p_index) { + void remove_at_unordered(U p_index) { ERR_FAIL_INDEX(p_index, count); count--; if (count > p_index) { @@ -97,7 +97,7 @@ public: void erase(const T &p_val) { int64_t idx = find(p_val); if (idx >= 0) { - remove(idx); + remove_at(idx); } } diff --git a/core/templates/vector.h b/core/templates/vector.h index 98982c80d3..a955d49101 100644 --- a/core/templates/vector.h +++ b/core/templates/vector.h @@ -68,11 +68,11 @@ public: _FORCE_INLINE_ bool append(const T &p_elem) { return push_back(p_elem); } //alias void fill(T p_elem); - void remove(int p_index) { _cowdata.remove(p_index); } + void remove_at(int p_index) { _cowdata.remove_at(p_index); } void erase(const T &p_val) { int idx = find(p_val); if (idx >= 0) { - remove(idx); + remove_at(idx); } } void reverse(); diff --git a/core/templates/vmap.h b/core/templates/vmap.h index 520e0b3720..2aa22f97cf 100644 --- a/core/templates/vmap.h +++ b/core/templates/vmap.h @@ -134,7 +134,7 @@ public: if (pos < 0) { return; } - _cowdata.remove(pos); + _cowdata.remove_at(pos); } int find(const T &p_val) const { diff --git a/core/templates/vset.h b/core/templates/vset.h index 6665651d42..94e7a17061 100644 --- a/core/templates/vset.h +++ b/core/templates/vset.h @@ -119,7 +119,7 @@ public: if (pos < 0) { return; } - _data.remove(pos); + _data.remove_at(pos); } int find(const T &p_val) const { diff --git a/core/variant/array.cpp b/core/variant/array.cpp index 69a0fff1a1..b049c29688 100644 --- a/core/variant/array.cpp +++ b/core/variant/array.cpp @@ -322,8 +322,8 @@ bool Array::has(const Variant &p_value) const { return _p->array.find(p_value, 0) != -1; } -void Array::remove(int p_pos) { - _p->array.remove(p_pos); +void Array::remove_at(int p_pos) { + _p->array.remove_at(p_pos); } void Array::set(int p_idx, const Variant &p_value) { @@ -576,7 +576,7 @@ Variant Array::pop_back() { Variant Array::pop_front() { if (!_p->array.is_empty()) { const Variant ret = _p->array.get(0); - _p->array.remove(0); + _p->array.remove_at(0); return ret; } return Variant(); @@ -603,7 +603,7 @@ Variant Array::pop_at(int p_pos) { _p->array.size())); const Variant ret = _p->array.get(p_pos); - _p->array.remove(p_pos); + _p->array.remove_at(p_pos); return ret; } diff --git a/core/variant/array.h b/core/variant/array.h index bd39b8e0b1..5d2839dda7 100644 --- a/core/variant/array.h +++ b/core/variant/array.h @@ -75,7 +75,7 @@ public: Error resize(int p_new_size); Error insert(int p_pos, const Variant &p_value); - void remove(int p_pos); + void remove_at(int p_pos); void fill(const Variant &p_value); Variant front() const; diff --git a/core/variant/variant_call.cpp b/core/variant/variant_call.cpp index 65ea969146..34b8b782d2 100644 --- a/core/variant/variant_call.cpp +++ b/core/variant/variant_call.cpp @@ -1808,7 +1808,7 @@ static void _register_variant_builtin_methods() { bind_method(Array, append_array, sarray("array"), varray()); bind_method(Array, resize, sarray("size"), varray()); bind_method(Array, insert, sarray("position", "value"), varray()); - bind_method(Array, remove, sarray("position"), varray()); + bind_method(Array, remove_at, sarray("position"), varray()); bind_method(Array, fill, sarray("value"), varray()); bind_method(Array, erase, sarray("value"), varray()); bind_method(Array, front, sarray(), varray()); @@ -1842,7 +1842,7 @@ static void _register_variant_builtin_methods() { bind_method(PackedByteArray, push_back, sarray("value"), varray()); bind_method(PackedByteArray, append, sarray("value"), varray()); bind_method(PackedByteArray, append_array, sarray("array"), varray()); - bind_method(PackedByteArray, remove, sarray("index"), varray()); + bind_method(PackedByteArray, remove_at, sarray("index"), varray()); bind_method(PackedByteArray, insert, sarray("at_index", "value"), varray()); bind_method(PackedByteArray, fill, sarray("value"), varray()); bind_method(PackedByteArray, resize, sarray("new_size"), varray()); @@ -1903,7 +1903,7 @@ static void _register_variant_builtin_methods() { bind_method(PackedInt32Array, push_back, sarray("value"), varray()); bind_method(PackedInt32Array, append, sarray("value"), varray()); bind_method(PackedInt32Array, append_array, sarray("array"), varray()); - bind_method(PackedInt32Array, remove, sarray("index"), varray()); + bind_method(PackedInt32Array, remove_at, sarray("index"), varray()); bind_method(PackedInt32Array, insert, sarray("at_index", "value"), varray()); bind_method(PackedInt32Array, fill, sarray("value"), varray()); bind_method(PackedInt32Array, resize, sarray("new_size"), varray()); @@ -1923,7 +1923,7 @@ static void _register_variant_builtin_methods() { bind_method(PackedInt64Array, push_back, sarray("value"), varray()); bind_method(PackedInt64Array, append, sarray("value"), varray()); bind_method(PackedInt64Array, append_array, sarray("array"), varray()); - bind_method(PackedInt64Array, remove, sarray("index"), varray()); + bind_method(PackedInt64Array, remove_at, sarray("index"), varray()); bind_method(PackedInt64Array, insert, sarray("at_index", "value"), varray()); bind_method(PackedInt64Array, fill, sarray("value"), varray()); bind_method(PackedInt64Array, resize, sarray("new_size"), varray()); @@ -1943,7 +1943,7 @@ static void _register_variant_builtin_methods() { bind_method(PackedFloat32Array, push_back, sarray("value"), varray()); bind_method(PackedFloat32Array, append, sarray("value"), varray()); bind_method(PackedFloat32Array, append_array, sarray("array"), varray()); - bind_method(PackedFloat32Array, remove, sarray("index"), varray()); + bind_method(PackedFloat32Array, remove_at, sarray("index"), varray()); bind_method(PackedFloat32Array, insert, sarray("at_index", "value"), varray()); bind_method(PackedFloat32Array, fill, sarray("value"), varray()); bind_method(PackedFloat32Array, resize, sarray("new_size"), varray()); @@ -1963,7 +1963,7 @@ static void _register_variant_builtin_methods() { bind_method(PackedFloat64Array, push_back, sarray("value"), varray()); bind_method(PackedFloat64Array, append, sarray("value"), varray()); bind_method(PackedFloat64Array, append_array, sarray("array"), varray()); - bind_method(PackedFloat64Array, remove, sarray("index"), varray()); + bind_method(PackedFloat64Array, remove_at, sarray("index"), varray()); bind_method(PackedFloat64Array, insert, sarray("at_index", "value"), varray()); bind_method(PackedFloat64Array, fill, sarray("value"), varray()); bind_method(PackedFloat64Array, resize, sarray("new_size"), varray()); @@ -1983,7 +1983,7 @@ static void _register_variant_builtin_methods() { bind_method(PackedStringArray, push_back, sarray("value"), varray()); bind_method(PackedStringArray, append, sarray("value"), varray()); bind_method(PackedStringArray, append_array, sarray("array"), varray()); - bind_method(PackedStringArray, remove, sarray("index"), varray()); + bind_method(PackedStringArray, remove_at, sarray("index"), varray()); bind_method(PackedStringArray, insert, sarray("at_index", "value"), varray()); bind_method(PackedStringArray, fill, sarray("value"), varray()); bind_method(PackedStringArray, resize, sarray("new_size"), varray()); @@ -2003,7 +2003,7 @@ static void _register_variant_builtin_methods() { bind_method(PackedVector2Array, push_back, sarray("value"), varray()); bind_method(PackedVector2Array, append, sarray("value"), varray()); bind_method(PackedVector2Array, append_array, sarray("array"), varray()); - bind_method(PackedVector2Array, remove, sarray("index"), varray()); + bind_method(PackedVector2Array, remove_at, sarray("index"), varray()); bind_method(PackedVector2Array, insert, sarray("at_index", "value"), varray()); bind_method(PackedVector2Array, fill, sarray("value"), varray()); bind_method(PackedVector2Array, resize, sarray("new_size"), varray()); @@ -2023,7 +2023,7 @@ static void _register_variant_builtin_methods() { bind_method(PackedVector3Array, push_back, sarray("value"), varray()); bind_method(PackedVector3Array, append, sarray("value"), varray()); bind_method(PackedVector3Array, append_array, sarray("array"), varray()); - bind_method(PackedVector3Array, remove, sarray("index"), varray()); + bind_method(PackedVector3Array, remove_at, sarray("index"), varray()); bind_method(PackedVector3Array, insert, sarray("at_index", "value"), varray()); bind_method(PackedVector3Array, fill, sarray("value"), varray()); bind_method(PackedVector3Array, resize, sarray("new_size"), varray()); @@ -2043,7 +2043,7 @@ static void _register_variant_builtin_methods() { bind_method(PackedColorArray, push_back, sarray("value"), varray()); bind_method(PackedColorArray, append, sarray("value"), varray()); bind_method(PackedColorArray, append_array, sarray("array"), varray()); - bind_method(PackedColorArray, remove, sarray("index"), varray()); + bind_method(PackedColorArray, remove_at, sarray("index"), varray()); bind_method(PackedColorArray, insert, sarray("at_index", "value"), varray()); bind_method(PackedColorArray, fill, sarray("value"), varray()); bind_method(PackedColorArray, resize, sarray("new_size"), varray()); diff --git a/core/variant/variant_setget.cpp b/core/variant/variant_setget.cpp index 2530d77c62..b6ad2d870e 100644 --- a/core/variant/variant_setget.cpp +++ b/core/variant/variant_setget.cpp @@ -704,7 +704,7 @@ struct VariantIndexedSetGet_String { String *b = VariantGetInternalPtr<String>::get_ptr(base); const String *v = VariantInternal::get_string(value); if (v->length() == 0) { - b->remove(index); + b->remove_at(index); } else { b->set(index, v->get(0)); } @@ -723,7 +723,7 @@ struct VariantIndexedSetGet_String { String *b = VariantGetInternalPtr<String>::get_ptr(base); const String *v = VariantInternal::get_string(value); if (v->length() == 0) { - b->remove(index); + b->remove_at(index); } else { b->set(index, v->get(0)); } @@ -738,7 +738,7 @@ struct VariantIndexedSetGet_String { OOB_TEST(index, v.length()); const String &m = *reinterpret_cast<const String *>(member); if (unlikely(m.length() == 0)) { - v.remove(index); + v.remove_at(index); } else { v.set(index, m.unicode_at(0)); } |