diff options
Diffstat (limited to 'core')
46 files changed, 500 insertions, 143 deletions
diff --git a/core/bind/core_bind.cpp b/core/bind/core_bind.cpp index dbfa04be4d..8a898f3b53 100644 --- a/core/bind/core_bind.cpp +++ b/core/bind/core_bind.cpp @@ -308,6 +308,14 @@ void _OS::set_window_position(const Point2 &p_position) { OS::get_singleton()->set_window_position(p_position); } +Size2 _OS::get_max_window_size() const { + return OS::get_singleton()->get_max_window_size(); +} + +Size2 _OS::get_min_window_size() const { + return OS::get_singleton()->get_min_window_size(); +} + Size2 _OS::get_window_size() const { return OS::get_singleton()->get_window_size(); } @@ -316,6 +324,14 @@ Size2 _OS::get_real_window_size() const { return OS::get_singleton()->get_real_window_size(); } +void _OS::set_max_window_size(const Size2 &p_size) { + OS::get_singleton()->set_max_window_size(p_size); +} + +void _OS::set_min_window_size(const Size2 &p_size) { + OS::get_singleton()->set_min_window_size(p_size); +} + void _OS::set_window_size(const Size2 &p_size) { OS::get_singleton()->set_window_size(p_size); } @@ -1139,6 +1155,10 @@ void _OS::_bind_methods() { ClassDB::bind_method(D_METHOD("get_window_position"), &_OS::get_window_position); ClassDB::bind_method(D_METHOD("set_window_position", "position"), &_OS::set_window_position); ClassDB::bind_method(D_METHOD("get_window_size"), &_OS::get_window_size); + ClassDB::bind_method(D_METHOD("get_max_window_size"), &_OS::get_max_window_size); + ClassDB::bind_method(D_METHOD("get_min_window_size"), &_OS::get_min_window_size); + ClassDB::bind_method(D_METHOD("set_max_window_size", "size"), &_OS::set_max_window_size); + ClassDB::bind_method(D_METHOD("set_min_window_size", "size"), &_OS::set_min_window_size); ClassDB::bind_method(D_METHOD("set_window_size", "size"), &_OS::set_window_size); ClassDB::bind_method(D_METHOD("get_window_safe_area"), &_OS::get_window_safe_area); ClassDB::bind_method(D_METHOD("set_window_fullscreen", "enabled"), &_OS::set_window_fullscreen); @@ -1284,6 +1304,8 @@ void _OS::_bind_methods() { ADD_PROPERTY(PropertyInfo(Variant::BOOL, "vsync_enabled"), "set_use_vsync", "is_vsync_enabled"); ADD_PROPERTY(PropertyInfo(Variant::BOOL, "low_processor_usage_mode"), "set_low_processor_usage_mode", "is_in_low_processor_usage_mode"); ADD_PROPERTY(PropertyInfo(Variant::BOOL, "keep_screen_on"), "set_keep_screen_on", "is_keep_screen_on"); + ADD_PROPERTY(PropertyInfo(Variant::VECTOR2, "min_window_size"), "set_min_window_size", "get_min_window_size"); + ADD_PROPERTY(PropertyInfo(Variant::VECTOR2, "max_window_size"), "set_max_window_size", "get_max_window_size"); ADD_PROPERTY(PropertyInfo(Variant::INT, "screen_orientation", PROPERTY_HINT_ENUM, "Landscape,Portrait,Reverse Landscape,Reverse Portrait,Sensor Landscape,Sensor Portrait,Sensor"), "set_screen_orientation", "get_screen_orientation"); ADD_GROUP("Window", "window_"); ADD_PROPERTY(PropertyInfo(Variant::BOOL, "window_borderless"), "set_borderless_window", "get_borderless_window"); diff --git a/core/bind/core_bind.h b/core/bind/core_bind.h index 8f74d88be5..7d0c158f51 100644 --- a/core/bind/core_bind.h +++ b/core/bind/core_bind.h @@ -175,9 +175,13 @@ public: virtual int get_screen_dpi(int p_screen = -1) const; virtual Point2 get_window_position() const; virtual void set_window_position(const Point2 &p_position); + virtual Size2 get_max_window_size() const; + virtual Size2 get_min_window_size() const; virtual Size2 get_window_size() const; virtual Size2 get_real_window_size() const; virtual Rect2 get_window_safe_area() const; + virtual void set_max_window_size(const Size2 &p_size); + virtual void set_min_window_size(const Size2 &p_size); virtual void set_window_size(const Size2 &p_size); virtual void set_window_fullscreen(bool p_enabled); virtual bool is_window_fullscreen() const; @@ -690,7 +694,7 @@ VARIANT_ENUM_CAST(_Thread::Priority); class _ClassDB : public Object { - GDCLASS(_ClassDB, Object) + GDCLASS(_ClassDB, Object); protected: static void _bind_methods(); @@ -775,7 +779,7 @@ public: class _JSON; class JSONParseResult : public Reference { - GDCLASS(JSONParseResult, Reference) + GDCLASS(JSONParseResult, Reference); friend class _JSON; @@ -803,7 +807,7 @@ public: }; class _JSON : public Object { - GDCLASS(_JSON, Object) + GDCLASS(_JSON, Object); protected: static void _bind_methods(); diff --git a/core/color.cpp b/core/color.cpp index efd2941b47..8959fce4e3 100644 --- a/core/color.cpp +++ b/core/color.cpp @@ -525,7 +525,7 @@ Color Color::from_hsv(float p_h, float p_s, float p_v, float p_a) const { float Color::gray() const { ERR_EXPLAIN("Color.gray() is deprecated and will be removed in a future version. Use Color.get_v() for a better grayscale approximation."); - WARN_DEPRECATED + WARN_DEPRECATED; return (r + g + b) / 3.0; } diff --git a/core/command_queue_mt.h b/core/command_queue_mt.h index 59eabd8786..798fa4394d 100644 --- a/core/command_queue_mt.h +++ b/core/command_queue_mt.h @@ -406,8 +406,10 @@ class CommandQueueMT { tryagain: // tried to read an empty queue - if (read_ptr == write_ptr) + if (read_ptr == write_ptr) { + if (p_lock) unlock(); return false; + } uint32_t size_ptr = read_ptr; uint32_t size = *(uint32_t *)&command_mem[read_ptr] >> 1; diff --git a/core/engine.cpp b/core/engine.cpp index 9607dedb3c..50822244cf 100644 --- a/core/engine.cpp +++ b/core/engine.cpp @@ -38,6 +38,7 @@ void Engine::set_iterations_per_second(int p_ips) { + ERR_FAIL_COND(p_ips <= 0); ips = p_ips; } int Engine::get_iterations_per_second() const { diff --git a/core/global_constants.cpp b/core/global_constants.cpp index fb90403226..671b3c545b 100644 --- a/core/global_constants.cpp +++ b/core/global_constants.cpp @@ -425,6 +425,16 @@ void register_global_constants() { BIND_GLOBAL_ENUM_CONSTANT(JOY_DS_X); BIND_GLOBAL_ENUM_CONSTANT(JOY_DS_Y); + BIND_GLOBAL_ENUM_CONSTANT(JOY_VR_GRIP); + BIND_GLOBAL_ENUM_CONSTANT(JOY_VR_PAD); + BIND_GLOBAL_ENUM_CONSTANT(JOY_VR_TRIGGER); + + BIND_GLOBAL_ENUM_CONSTANT(JOY_OCULUS_AX); + BIND_GLOBAL_ENUM_CONSTANT(JOY_OCULUS_BY); + BIND_GLOBAL_ENUM_CONSTANT(JOY_OCULUS_MENU); + + BIND_GLOBAL_ENUM_CONSTANT(JOY_OPENVR_MENU); + BIND_GLOBAL_ENUM_CONSTANT(JOY_SELECT); BIND_GLOBAL_ENUM_CONSTANT(JOY_START); BIND_GLOBAL_ENUM_CONSTANT(JOY_DPAD_UP); @@ -459,6 +469,12 @@ void register_global_constants() { BIND_GLOBAL_ENUM_CONSTANT(JOY_ANALOG_L2); BIND_GLOBAL_ENUM_CONSTANT(JOY_ANALOG_R2); + BIND_GLOBAL_ENUM_CONSTANT(JOY_VR_ANALOG_TRIGGER); + BIND_GLOBAL_ENUM_CONSTANT(JOY_VR_ANALOG_GRIP); + + BIND_GLOBAL_ENUM_CONSTANT(JOY_OPENVR_TOUCHPADX); + BIND_GLOBAL_ENUM_CONSTANT(JOY_OPENVR_TOUCHPADY); + // midi BIND_GLOBAL_ENUM_CONSTANT(MIDI_MESSAGE_NOTE_OFF); BIND_GLOBAL_ENUM_CONSTANT(MIDI_MESSAGE_NOTE_ON); diff --git a/core/hash_map.h b/core/hash_map.h index 44459a3080..31332991de 100644 --- a/core/hash_map.h +++ b/core/hash_map.h @@ -162,20 +162,21 @@ private: new_hash_table[i] = 0; } - for (int i = 0; i < (1 << hash_table_power); i++) { + if (hash_table) { + for (int i = 0; i < (1 << hash_table_power); i++) { - while (hash_table[i]) { + while (hash_table[i]) { - Element *se = hash_table[i]; - hash_table[i] = se->next; - int new_pos = se->hash & ((1 << new_hash_table_power) - 1); - se->next = new_hash_table[new_pos]; - new_hash_table[new_pos] = se; + Element *se = hash_table[i]; + hash_table[i] = se->next; + int new_pos = se->hash & ((1 << new_hash_table_power) - 1); + se->next = new_hash_table[new_pos]; + new_hash_table[new_pos] = se; + } } - } - if (hash_table) memdelete_arr(hash_table); + } hash_table = new_hash_table; hash_table_power = new_hash_table_power; } diff --git a/core/image.cpp b/core/image.cpp index 30af724de9..c85d7f6bcc 100644 --- a/core/image.cpp +++ b/core/image.cpp @@ -749,7 +749,7 @@ static void _scale_lanczos(const uint8_t *__restrict p_src, uint8_t *__restrict float scale_factor = MAX(x_scale, 1); // A larger kernel is required only when downscaling int32_t half_kernel = LANCZOS_TYPE * scale_factor; - float *kernel = memnew_arr(float, half_kernel * 2 - 1); + float *kernel = memnew_arr(float, half_kernel * 2); for (int32_t buffer_x = 0; buffer_x < dst_width; buffer_x++) { @@ -800,7 +800,7 @@ static void _scale_lanczos(const uint8_t *__restrict p_src, uint8_t *__restrict float scale_factor = MAX(y_scale, 1); int32_t half_kernel = LANCZOS_TYPE * scale_factor; - float *kernel = memnew_arr(float, half_kernel * 2 - 1); + float *kernel = memnew_arr(float, half_kernel * 2); for (int32_t dst_y = 0; dst_y < dst_height; dst_y++) { diff --git a/core/input_map.cpp b/core/input_map.cpp index 15f68f9c2a..012c6a7c4f 100644 --- a/core/input_map.cpp +++ b/core/input_map.cpp @@ -202,7 +202,7 @@ bool InputMap::event_get_action_status(const Ref<InputEvent> &p_event, const Str if (p_pressed != NULL) *p_pressed = input_event_action->is_pressed(); if (p_strength != NULL) - *p_strength = (*p_pressed) ? 1.0f : 0.0f; + *p_strength = (*p_pressed) ? input_event_action->get_strength() : 0.0f; return input_event_action->get_action() == p_action; } diff --git a/core/io/config_file.cpp b/core/io/config_file.cpp index 414742deeb..871e21df3e 100644 --- a/core/io/config_file.cpp +++ b/core/io/config_file.cpp @@ -198,10 +198,6 @@ Error ConfigFile::load(const String &p_path) { section = next_tag.name; } } - - memdelete(f); - - return OK; } void ConfigFile::_bind_methods() { diff --git a/core/io/file_access_encrypted.cpp b/core/io/file_access_encrypted.cpp index 3cf6908961..7dea749a43 100644 --- a/core/io/file_access_encrypted.cpp +++ b/core/io/file_access_encrypted.cpp @@ -100,6 +100,7 @@ Error FileAccessEncrypted::open_and_parse(FileAccess *p_base, const Vector<uint8 MD5Update(&md5, (uint8_t *)data.ptr(), data.size()); MD5Final(&md5); + ERR_EXPLAIN("The MD5 sum of the decrypted file does not match the expected value. It could be that the file is corrupt, or that the provided decryption key is invalid."); ERR_FAIL_COND_V(String::md5(md5.digest) != String::md5(md5d), ERR_FILE_CORRUPT); file = p_base; @@ -307,8 +308,8 @@ uint32_t FileAccessEncrypted::_get_unix_permissions(const String &p_file) { } Error FileAccessEncrypted::_set_unix_permissions(const String &p_file, uint32_t p_permissions) { - - return FAILED; + ERR_PRINT("Setting UNIX permissions on encrypted files is not implemented yet"); + return ERR_UNAVAILABLE; } FileAccessEncrypted::FileAccessEncrypted() { diff --git a/core/io/file_access_network.cpp b/core/io/file_access_network.cpp index 722e62c54e..5dd167c581 100644 --- a/core/io/file_access_network.cpp +++ b/core/io/file_access_network.cpp @@ -118,7 +118,10 @@ void FileAccessNetworkClient::_thread_func() { FileAccessNetwork *fa = NULL; if (response != FileAccessNetwork::RESPONSE_DATA) { - ERR_FAIL_COND(!accesses.has(id)); + if (!accesses.has(id)) { + unlock_mutex(); + ERR_FAIL_COND(!accesses.has(id)); + } } if (accesses.has(id)) @@ -498,13 +501,13 @@ uint64_t FileAccessNetwork::_get_modified_time(const String &p_file) { } uint32_t FileAccessNetwork::_get_unix_permissions(const String &p_file) { - //could be implemented, not sure if worth it + ERR_PRINT("Getting UNIX permissions from network drives is not implemented yet"); return 0; } Error FileAccessNetwork::_set_unix_permissions(const String &p_file, uint32_t p_permissions) { - - return FAILED; + ERR_PRINT("Setting UNIX permissions on network drives is not implemented yet"); + return ERR_UNAVAILABLE; } void FileAccessNetwork::configure() { diff --git a/core/io/http_client.cpp b/core/io/http_client.cpp index ce2054db36..891fb7b0ca 100644 --- a/core/io/http_client.cpp +++ b/core/io/http_client.cpp @@ -346,6 +346,12 @@ Error HTTPClient::poll() { } else { // We are already handshaking, which means we can use your already active SSL connection ssl = static_cast<Ref<StreamPeerSSL> >(connection); + if (ssl.is_null()) { + close(); + status = STATUS_SSL_HANDSHAKE_ERROR; + return ERR_CANT_CONNECT; + } + ssl->poll(); // Try to finish the handshake } diff --git a/core/io/image_loader.cpp b/core/io/image_loader.cpp index a5a0738140..a759e615c7 100644 --- a/core/io/image_loader.cpp +++ b/core/io/image_loader.cpp @@ -65,6 +65,9 @@ Error ImageLoader::load_image(String p_file, Ref<Image> p_image, FileAccess *p_c if (!loader[i]->recognize(extension)) continue; Error err = loader[i]->load_image(p_image, f, p_force_linear, p_scale); + if (err != OK) { + ERR_PRINTS("Error loading image: " + p_file); + } if (err != ERR_FILE_UNRECOGNIZED) { diff --git a/core/io/image_loader.h b/core/io/image_loader.h index 95c562b7a9..ae4b72a534 100644 --- a/core/io/image_loader.h +++ b/core/io/image_loader.h @@ -88,7 +88,6 @@ public: }; class ResourceFormatLoaderImage : public ResourceFormatLoader { - GDCLASS(ResourceFormatLoaderImage, ResourceFormatLoader) public: virtual RES load(const String &p_path, const String &p_original_path = "", Error *r_error = NULL); virtual void get_recognized_extensions(List<String> *p_extensions) const; diff --git a/core/io/resource_format_binary.h b/core/io/resource_format_binary.h index a4894e4033..27777c8e8b 100644 --- a/core/io/resource_format_binary.h +++ b/core/io/resource_format_binary.h @@ -100,7 +100,6 @@ public: }; class ResourceFormatLoaderBinary : public ResourceFormatLoader { - GDCLASS(ResourceFormatLoaderBinary, ResourceFormatLoader) public: virtual Ref<ResourceInteractiveLoader> load_interactive(const String &p_path, const String &p_original_path = "", Error *r_error = NULL); virtual void get_recognized_extensions_for_type(const String &p_type, List<String> *p_extensions) const; @@ -162,7 +161,6 @@ public: }; class ResourceFormatSaverBinary : public ResourceFormatSaver { - GDCLASS(ResourceFormatSaverBinary, ResourceFormatSaver) public: static ResourceFormatSaverBinary *singleton; virtual Error save(const String &p_path, const RES &p_resource, uint32_t p_flags = 0); diff --git a/core/io/resource_importer.h b/core/io/resource_importer.h index 2e01989564..9cf298a7f5 100644 --- a/core/io/resource_importer.h +++ b/core/io/resource_importer.h @@ -37,8 +37,6 @@ class ResourceImporter; class ResourceFormatImporter : public ResourceFormatLoader { - GDCLASS(ResourceFormatImporter, ResourceFormatLoader) - struct PathAndType { String path; String type; @@ -96,7 +94,8 @@ public: class ResourceImporter : public Reference { - GDCLASS(ResourceImporter, Reference) + GDCLASS(ResourceImporter, Reference); + public: virtual String get_importer_name() const = 0; virtual String get_visible_name() const = 0; diff --git a/core/io/resource_loader.h b/core/io/resource_loader.h index 9e7020be7c..70e7bdc224 100644 --- a/core/io/resource_loader.h +++ b/core/io/resource_loader.h @@ -62,7 +62,7 @@ public: class ResourceFormatLoader : public Reference { - GDCLASS(ResourceFormatLoader, Reference) + GDCLASS(ResourceFormatLoader, Reference); protected: static void _bind_methods(); diff --git a/core/io/resource_saver.h b/core/io/resource_saver.h index 7df3bfb1f8..0fba47a5e8 100644 --- a/core/io/resource_saver.h +++ b/core/io/resource_saver.h @@ -38,7 +38,7 @@ */ class ResourceFormatSaver : public Reference { - GDCLASS(ResourceFormatSaver, Reference) + GDCLASS(ResourceFormatSaver, Reference); protected: static void _bind_methods(); diff --git a/core/io/translation_loader_po.h b/core/io/translation_loader_po.h index d5fd264385..9d9c5d16ee 100644 --- a/core/io/translation_loader_po.h +++ b/core/io/translation_loader_po.h @@ -36,7 +36,6 @@ #include "core/translation.h" class TranslationLoaderPO : public ResourceFormatLoader { - GDCLASS(TranslationLoaderPO, ResourceFormatLoader) public: static RES load_translation(FileAccess *f, Error *r_error, const String &p_path = String()); virtual RES load(const String &p_path, const String &p_original_path = "", Error *r_error = NULL); diff --git a/core/io/xml_parser.cpp b/core/io/xml_parser.cpp index 4407ddb7d3..82527d3f38 100644 --- a/core/io/xml_parser.cpp +++ b/core/io/xml_parser.cpp @@ -348,7 +348,7 @@ uint64_t XMLParser::get_node_offset() const { Error XMLParser::seek(uint64_t p_pos) { - ERR_FAIL_COND_V(!data, ERR_FILE_EOF) + ERR_FAIL_COND_V(!data, ERR_FILE_EOF); ERR_FAIL_COND_V(p_pos >= length, ERR_FILE_EOF); P = data + p_pos; diff --git a/core/list.h b/core/list.h index 103a82a31d..d1b528562d 100644 --- a/core/list.h +++ b/core/list.h @@ -602,9 +602,6 @@ public: Element *next = current->next_ptr; - //disconnect - current->next_ptr = NULL; - if (from != current) { current->prev_ptr = NULL; diff --git a/core/math/a_star.cpp b/core/math/a_star.cpp index 3d71e66f80..7ce3824505 100644 --- a/core/math/a_star.cpp +++ b/core/math/a_star.cpp @@ -99,14 +99,22 @@ void AStar::remove_point(int p_id) { Point *p = points[p_id]; - Map<int, Point *>::Element *PE = points.front(); - while (PE) { - for (Set<Point *>::Element *E = PE->get()->neighbours.front(); E; E = E->next()) { - Segment s(p_id, E->get()->id); - segments.erase(s); - E->get()->neighbours.erase(p); - } - PE = PE->next(); + for (Set<Point *>::Element *E = p->neighbours.front(); E; E = E->next()) { + + Segment s(p_id, E->get()->id); + segments.erase(s); + + E->get()->neighbours.erase(p); + E->get()->unlinked_neighbours.erase(p); + } + + for (Set<Point *>::Element *E = p->unlinked_neighbours.front(); E; E = E->next()) { + + Segment s(p_id, E->get()->id); + segments.erase(s); + + E->get()->neighbours.erase(p); + E->get()->unlinked_neighbours.erase(p); } memdelete(p); @@ -125,6 +133,8 @@ void AStar::connect_points(int p_id, int p_with_id, bool bidirectional) { if (bidirectional) b->neighbours.insert(a); + else + b->unlinked_neighbours.insert(a); Segment s(p_id, p_with_id); if (s.from == p_id) { @@ -147,7 +157,9 @@ void AStar::disconnect_points(int p_id, int p_with_id) { Point *a = points[p_id]; Point *b = points[p_with_id]; a->neighbours.erase(b); + a->unlinked_neighbours.erase(b); b->neighbours.erase(a); + b->unlinked_neighbours.erase(a); } bool AStar::has_point(int p_id) const { @@ -423,10 +435,16 @@ PoolVector<int> AStar::get_id_path(int p_from_id, int p_to_id) { } void AStar::set_point_disabled(int p_id, bool p_disabled) { + + ERR_FAIL_COND(!points.has(p_id)); + points[p_id]->enabled = !p_disabled; } bool AStar::is_point_disabled(int p_id) const { + + ERR_FAIL_COND_V(!points.has(p_id), false); + return !points[p_id]->enabled; } @@ -440,13 +458,12 @@ void AStar::_bind_methods() { ClassDB::bind_method(D_METHOD("set_point_weight_scale", "id", "weight_scale"), &AStar::set_point_weight_scale); ClassDB::bind_method(D_METHOD("remove_point", "id"), &AStar::remove_point); ClassDB::bind_method(D_METHOD("has_point", "id"), &AStar::has_point); + ClassDB::bind_method(D_METHOD("get_point_connections", "id"), &AStar::get_point_connections); ClassDB::bind_method(D_METHOD("get_points"), &AStar::get_points); ClassDB::bind_method(D_METHOD("set_point_disabled", "id", "disabled"), &AStar::set_point_disabled, DEFVAL(true)); ClassDB::bind_method(D_METHOD("is_point_disabled", "id"), &AStar::is_point_disabled); - ClassDB::bind_method(D_METHOD("get_point_connections", "id"), &AStar::get_point_connections); - ClassDB::bind_method(D_METHOD("connect_points", "id", "to_id", "bidirectional"), &AStar::connect_points, DEFVAL(true)); ClassDB::bind_method(D_METHOD("disconnect_points", "id", "to_id"), &AStar::disconnect_points); ClassDB::bind_method(D_METHOD("are_points_connected", "id", "to_id"), &AStar::are_points_connected); @@ -473,3 +490,135 @@ AStar::~AStar() { pass = 1; clear(); } + +///////////////////////////////////////////////////////////// + +int AStar2D::get_available_point_id() const { + return astar.get_available_point_id(); +} + +void AStar2D::add_point(int p_id, const Vector2 &p_pos, real_t p_weight_scale) { + astar.add_point(p_id, Vector3(p_pos.x, p_pos.y, 0), p_weight_scale); +} + +Vector2 AStar2D::get_point_position(int p_id) const { + Vector3 p = astar.get_point_position(p_id); + return Vector2(p.x, p.y); +} + +void AStar2D::set_point_position(int p_id, const Vector2 &p_pos) { + astar.set_point_position(p_id, Vector3(p_pos.x, p_pos.y, 0)); +} + +real_t AStar2D::get_point_weight_scale(int p_id) const { + return astar.get_point_weight_scale(p_id); +} + +void AStar2D::set_point_weight_scale(int p_id, real_t p_weight_scale) { + astar.set_point_weight_scale(p_id, p_weight_scale); +} + +void AStar2D::remove_point(int p_id) { + astar.remove_point(p_id); +} + +bool AStar2D::has_point(int p_id) const { + return astar.has_point(p_id); +} + +PoolVector<int> AStar2D::get_point_connections(int p_id) { + return astar.get_point_connections(p_id); +} + +Array AStar2D::get_points() { + return astar.get_points(); +} + +void AStar2D::set_point_disabled(int p_id, bool p_disabled) { + astar.set_point_disabled(p_id, p_disabled); +} + +bool AStar2D::is_point_disabled(int p_id) const { + return astar.is_point_disabled(p_id); +} + +void AStar2D::connect_points(int p_id, int p_with_id, bool p_bidirectional) { + astar.connect_points(p_id, p_with_id, p_bidirectional); +} + +void AStar2D::disconnect_points(int p_id, int p_with_id) { + astar.disconnect_points(p_id, p_with_id); +} + +bool AStar2D::are_points_connected(int p_id, int p_with_id) const { + return astar.are_points_connected(p_id, p_with_id); +} + +void AStar2D::clear() { + astar.clear(); +} + +int AStar2D::get_closest_point(const Vector2 &p_point) const { + return astar.get_closest_point(Vector3(p_point.x, p_point.y, 0)); +} + +Vector2 AStar2D::get_closest_position_in_segment(const Vector2 &p_point) const { + Vector3 p = astar.get_closest_position_in_segment(Vector3(p_point.x, p_point.y, 0)); + return Vector2(p.x, p.y); +} + +PoolVector<Vector2> AStar2D::get_point_path(int p_from_id, int p_to_id) { + + PoolVector3Array pv = astar.get_point_path(p_from_id, p_to_id); + int size = pv.size(); + PoolVector2Array path; + path.resize(size); + { + PoolVector<Vector3>::Read r = pv.read(); + PoolVector<Vector2>::Write w = path.write(); + for (int i = 0; i < size; i++) { + Vector3 p = r[i]; + w[i] = Vector2(p.x, p.y); + } + } + return path; +} + +PoolVector<int> AStar2D::get_id_path(int p_from_id, int p_to_id) { + return astar.get_id_path(p_from_id, p_to_id); +} + +void AStar2D::_bind_methods() { + + ClassDB::bind_method(D_METHOD("get_available_point_id"), &AStar2D::get_available_point_id); + ClassDB::bind_method(D_METHOD("add_point", "id", "position", "weight_scale"), &AStar2D::add_point, DEFVAL(1.0)); + ClassDB::bind_method(D_METHOD("get_point_position", "id"), &AStar2D::get_point_position); + ClassDB::bind_method(D_METHOD("set_point_position", "id", "position"), &AStar2D::set_point_position); + ClassDB::bind_method(D_METHOD("get_point_weight_scale", "id"), &AStar2D::get_point_weight_scale); + ClassDB::bind_method(D_METHOD("set_point_weight_scale", "id", "weight_scale"), &AStar2D::set_point_weight_scale); + ClassDB::bind_method(D_METHOD("remove_point", "id"), &AStar2D::remove_point); + ClassDB::bind_method(D_METHOD("has_point", "id"), &AStar2D::has_point); + ClassDB::bind_method(D_METHOD("get_point_connections", "id"), &AStar2D::get_point_connections); + ClassDB::bind_method(D_METHOD("get_points"), &AStar2D::get_points); + + ClassDB::bind_method(D_METHOD("set_point_disabled", "id", "disabled"), &AStar2D::set_point_disabled, DEFVAL(true)); + ClassDB::bind_method(D_METHOD("is_point_disabled", "id"), &AStar2D::is_point_disabled); + + ClassDB::bind_method(D_METHOD("connect_points", "id", "to_id", "bidirectional"), &AStar2D::connect_points, DEFVAL(true)); + ClassDB::bind_method(D_METHOD("disconnect_points", "id", "to_id"), &AStar2D::disconnect_points); + ClassDB::bind_method(D_METHOD("are_points_connected", "id", "to_id"), &AStar2D::are_points_connected); + + ClassDB::bind_method(D_METHOD("clear"), &AStar2D::clear); + + ClassDB::bind_method(D_METHOD("get_closest_point", "to_position"), &AStar2D::get_closest_point); + ClassDB::bind_method(D_METHOD("get_closest_position_in_segment", "to_position"), &AStar2D::get_closest_position_in_segment); + + ClassDB::bind_method(D_METHOD("get_point_path", "from_id", "to_id"), &AStar2D::get_point_path); + ClassDB::bind_method(D_METHOD("get_id_path", "from_id", "to_id"), &AStar2D::get_id_path); +} + +AStar2D::AStar2D() { +} + +AStar2D::~AStar2D() { +} diff --git a/core/math/a_star.h b/core/math/a_star.h index fac8a9d312..ec333efc1d 100644 --- a/core/math/a_star.h +++ b/core/math/a_star.h @@ -42,7 +42,7 @@ class AStar : public Reference { - GDCLASS(AStar, Reference) + GDCLASS(AStar, Reference); uint64_t pass; @@ -54,6 +54,7 @@ class AStar : public Reference { bool enabled; Set<Point *> neighbours; + Set<Point *> unlinked_neighbours; // Used for pathfinding Point *prev_point; @@ -142,4 +143,43 @@ public: ~AStar(); }; +class AStar2D : public Reference { + GDCLASS(AStar2D, Reference); + AStar astar; + +protected: + static void _bind_methods(); + +public: + int get_available_point_id() const; + + void add_point(int p_id, const Vector2 &p_pos, real_t p_weight_scale = 1); + Vector2 get_point_position(int p_id) const; + void set_point_position(int p_id, const Vector2 &p_pos); + real_t get_point_weight_scale(int p_id) const; + void set_point_weight_scale(int p_id, real_t p_weight_scale); + void remove_point(int p_id); + bool has_point(int p_id) const; + PoolVector<int> get_point_connections(int p_id); + Array get_points(); + + void set_point_disabled(int p_id, bool p_disabled = true); + bool is_point_disabled(int p_id) const; + + void connect_points(int p_id, int p_with_id, bool p_bidirectional = true); + void disconnect_points(int p_id, int p_with_id); + bool are_points_connected(int p_id, int p_with_id) const; + + void clear(); + + int get_closest_point(const Vector2 &p_point) const; + Vector2 get_closest_position_in_segment(const Vector2 &p_point) const; + + PoolVector<Vector2> get_point_path(int p_from_id, int p_to_id); + PoolVector<int> get_id_path(int p_from_id, int p_to_id); + + AStar2D(); + ~AStar2D(); +}; + #endif // ASTAR_H diff --git a/core/math/expression.cpp b/core/math/expression.cpp index 079c9b524f..e484e9194d 100644 --- a/core/math/expression.cpp +++ b/core/math/expression.cpp @@ -70,6 +70,7 @@ const char *Expression::func_name[Expression::FUNC_MAX] = { "inverse_lerp", "range_lerp", "smoothstep", + "move_toward", "dectime", "randomize", "randi", @@ -189,6 +190,7 @@ int Expression::get_func_argument_count(BuiltinFunc p_func) { case MATH_LERP: case MATH_INVERSE_LERP: case MATH_SMOOTHSTEP: + case MATH_MOVE_TOWARD: case MATH_DECTIME: case MATH_WRAP: case MATH_WRAPF: @@ -407,6 +409,13 @@ void Expression::exec_func(BuiltinFunc p_func, const Variant **p_inputs, Variant VALIDATE_ARG_NUM(2); *r_return = Math::smoothstep((double)*p_inputs[0], (double)*p_inputs[1], (double)*p_inputs[2]); } break; + case MATH_MOVE_TOWARD: { + + VALIDATE_ARG_NUM(0); + VALIDATE_ARG_NUM(1); + VALIDATE_ARG_NUM(2); + *r_return = Math::move_toward((double)*p_inputs[0], (double)*p_inputs[1], (double)*p_inputs[2]); + } break; case MATH_DECTIME: { VALIDATE_ARG_NUM(0); diff --git a/core/math/expression.h b/core/math/expression.h index f20619f0b6..1113bb6587 100644 --- a/core/math/expression.h +++ b/core/math/expression.h @@ -34,7 +34,8 @@ #include "core/reference.h" class Expression : public Reference { - GDCLASS(Expression, Reference) + GDCLASS(Expression, Reference); + public: enum BuiltinFunc { MATH_SIN, @@ -68,6 +69,7 @@ public: MATH_INVERSE_LERP, MATH_RANGE_LERP, MATH_SMOOTHSTEP, + MATH_MOVE_TOWARD, MATH_DECTIME, MATH_RANDOMIZE, MATH_RAND, diff --git a/core/math/math_funcs.h b/core/math/math_funcs.h index 82b5b56c01..0e3bd8a318 100644 --- a/core/math/math_funcs.h +++ b/core/math/math_funcs.h @@ -224,6 +224,8 @@ public: float x = CLAMP((p_weight - p_from) / (p_to - p_from), 0.0f, 1.0f); return x * x * (3.0f - 2.0f * x); } + static _ALWAYS_INLINE_ double move_toward(double p_from, double p_to, double p_delta) { return abs(p_to - p_from) <= p_delta ? p_to : p_from + SGN(p_to - p_from) * p_delta; } + static _ALWAYS_INLINE_ float move_toward(float p_from, float p_to, float p_delta) { return abs(p_to - p_from) <= p_delta ? p_to : p_from + SGN(p_to - p_from) * p_delta; } static _ALWAYS_INLINE_ double linear2db(double p_linear) { return Math::log(p_linear) * 8.6858896380650365530225783783321; } static _ALWAYS_INLINE_ float linear2db(float p_linear) { return Math::log(p_linear) * 8.6858896380650365530225783783321; } diff --git a/core/math/random_number_generator.h b/core/math/random_number_generator.h index 6b6bcdd2cd..a6182a4b33 100644 --- a/core/math/random_number_generator.h +++ b/core/math/random_number_generator.h @@ -59,7 +59,10 @@ public: _FORCE_INLINE_ int randi_range(int from, int to) { unsigned int ret = randbase.rand(); - return ret % (to - from + 1) + from; + if (to < from) + return ret % (from - to + 1) + to; + else + return ret % (to - from + 1) + from; } RandomNumberGenerator(); diff --git a/core/math/random_pcg.cpp b/core/math/random_pcg.cpp index 8351bd138e..00c0af515d 100644 --- a/core/math/random_pcg.cpp +++ b/core/math/random_pcg.cpp @@ -43,13 +43,9 @@ void RandomPCG::randomize() { } double RandomPCG::random(double p_from, double p_to) { - unsigned int r = rand(); - double ret = (double)r / (double)RANDOM_MAX; - return (ret) * (p_to - p_from) + p_from; + return randd() * (p_to - p_from) + p_from; } float RandomPCG::random(float p_from, float p_to) { - unsigned int r = rand(); - float ret = (float)r / (float)RANDOM_MAX; - return (ret) * (p_to - p_from) + p_from; + return randf() * (p_to - p_from) + p_from; } diff --git a/core/math/random_pcg.h b/core/math/random_pcg.h index 0d1b311c0d..aa25914638 100644 --- a/core/math/random_pcg.h +++ b/core/math/random_pcg.h @@ -37,6 +37,28 @@ #include "thirdparty/misc/pcg.h" +#if defined(__GNUC__) || (_llvm_has_builtin(__builtin_clz)) +#define CLZ32(x) __builtin_clz(x) +#elif defined(_MSC_VER) +#include "intrin.h" +static int __bsr_clz32(uint32_t x) { + unsigned long index; + _BitScanReverse(&index, x); + return 31 - index; +} +#define CLZ32(x) __bsr_clz32(x) +#else +#endif + +#if defined(__GNUC__) || (_llvm_has_builtin(__builtin_ldexp) && _llvm_has_builtin(__builtin_ldexpf)) +#define LDEXP(s, e) __builtin_ldexp(s, e) +#define LDEXPF(s, e) __builtin_ldexpf(s, e) +#else +#include "math.h" +#define LDEXP(s, e) ldexp(s, e) +#define LDEXPF(s, e) ldexp(s, e) +#endif + class RandomPCG { pcg32_random_t pcg; uint64_t current_seed; // seed with this to get the same state @@ -60,8 +82,44 @@ public: current_seed = pcg.state; return pcg32_random_r(&pcg); } - _FORCE_INLINE_ double randd() { return (double)rand() / (double)RANDOM_MAX; } - _FORCE_INLINE_ float randf() { return (float)rand() / (float)RANDOM_MAX; } + + // Obtaining floating point numbers in [0, 1] range with "good enough" uniformity. + // These functions sample the output of rand() as the fraction part of an infinite binary number, + // with some tricks applied to reduce ops and branching: + // 1. Instead of shifting to the first 1 and connecting random bits, we simply set the MSB and LSB to 1. + // Provided that the RNG is actually uniform bit by bit, this should have the exact same effect. + // 2. In order to compensate for exponent info loss, we count zeros from another random number, + // and just add that to the initial offset. + // This has the same probability as counting and shifting an actual bit stream: 2^-n for n zeroes. + // For all numbers above 2^-96 (2^-64 for floats), the functions should be uniform. + // However, all numbers below that threshold are floored to 0. + // The thresholds are chosen to minimize rand() calls while keeping the numbers within a totally subjective quality standard. + // If clz or ldexp isn't available, fall back to bit truncation for performance, sacrificing uniformity. + _FORCE_INLINE_ double randd() { +#if defined(CLZ32) + uint32_t proto_exp_offset = rand(); + if (unlikely(proto_exp_offset == 0)) { + return 0; + } + uint64_t significand = (((uint64_t)rand()) << 32) | rand() | 0x8000000000000001U; + return LDEXP((double)significand, -64 - CLZ32(proto_exp_offset)); +#else +#pragma message("RandomPCG::randd - intrinsic clz is not available, falling back to bit truncation") + return (double)(((((uint64_t)rand()) << 32) | rand()) & 0x1FFFFFFFFFFFFFU) / (double)0x1FFFFFFFFFFFFFU; +#endif + } + _FORCE_INLINE_ float randf() { +#if defined(CLZ32) + uint32_t proto_exp_offset = rand(); + if (unlikely(proto_exp_offset == 0)) { + return 0; + } + return LDEXPF((float)(rand() | 0x80000001), -32 - CLZ32(proto_exp_offset)); +#else +#pragma message("RandomPCG::randf - intrinsic clz is not available, falling back to bit truncation") + return (float)(rand() & 0xFFFFFF) / (float)0xFFFFFF; +#endif + } _FORCE_INLINE_ double randfn(double p_mean, double p_deviation) { return p_mean + p_deviation * (cos(Math_TAU * randd()) * sqrt(-2.0 * log(randd()))); // Box-Muller transform diff --git a/core/math/vector2.cpp b/core/math/vector2.cpp index 5c1ea5943d..779a28be66 100644 --- a/core/math/vector2.cpp +++ b/core/math/vector2.cpp @@ -164,6 +164,13 @@ Vector2 Vector2::cubic_interpolate(const Vector2 &p_b, const Vector2 &p_pre_a, c return out; } +Vector2 Vector2::move_toward(const Vector2 &p_to, const real_t p_delta) const { + Vector2 v = *this; + Vector2 vd = p_to - v; + real_t len = vd.length(); + return len <= p_delta || len < CMP_EPSILON ? p_to : v + vd / len * p_delta; +} + // slide returns the component of the vector along the given plane, specified by its normal vector. Vector2 Vector2::slide(const Vector2 &p_normal) const { #ifdef MATH_CHECKS diff --git a/core/math/vector2.h b/core/math/vector2.h index a0c6024c9f..78a1641c1e 100644 --- a/core/math/vector2.h +++ b/core/math/vector2.h @@ -79,6 +79,7 @@ struct Vector2 { _FORCE_INLINE_ Vector2 linear_interpolate(const Vector2 &p_b, real_t p_t) const; _FORCE_INLINE_ Vector2 slerp(const Vector2 &p_b, real_t p_t) const; Vector2 cubic_interpolate(const Vector2 &p_b, const Vector2 &p_pre_a, const Vector2 &p_post_b, real_t p_t) const; + Vector2 move_toward(const Vector2 &p_to, const real_t p_delta) const; Vector2 slide(const Vector2 &p_normal) const; Vector2 bounce(const Vector2 &p_normal) const; diff --git a/core/math/vector3.cpp b/core/math/vector3.cpp index 1c28934422..73927821cf 100644 --- a/core/math/vector3.cpp +++ b/core/math/vector3.cpp @@ -127,6 +127,13 @@ Vector3 Vector3::cubic_interpolate(const Vector3 &p_b, const Vector3 &p_pre_a, c return out; } +Vector3 Vector3::move_toward(const Vector3 &p_to, const real_t p_delta) const { + Vector3 v = *this; + Vector3 vd = p_to - v; + real_t len = vd.length(); + return len <= p_delta || len < CMP_EPSILON ? p_to : v + vd / len * p_delta; +} + Vector3::operator String() const { return (rtos(x) + ", " + rtos(y) + ", " + rtos(z)); diff --git a/core/math/vector3.h b/core/math/vector3.h index 21fc09653f..811a207138 100644 --- a/core/math/vector3.h +++ b/core/math/vector3.h @@ -94,6 +94,7 @@ struct Vector3 { _FORCE_INLINE_ Vector3 slerp(const Vector3 &p_b, real_t p_t) const; Vector3 cubic_interpolate(const Vector3 &p_b, const Vector3 &p_pre_a, const Vector3 &p_post_b, real_t p_t) const; Vector3 cubic_interpolaten(const Vector3 &p_b, const Vector3 &p_pre_a, const Vector3 &p_post_b, real_t p_t) const; + Vector3 move_toward(const Vector3 &p_to, const real_t p_delta) const; _FORCE_INLINE_ Vector3 cross(const Vector3 &p_b) const; _FORCE_INLINE_ real_t dot(const Vector3 &p_b) const; @@ -223,7 +224,7 @@ Vector3 Vector3::slerp(const Vector3 &p_b, real_t p_t) const { #endif real_t theta = angle_to(p_b); - return rotated(cross(p_b), theta * p_t); + return rotated(cross(p_b).normalized(), theta * p_t); } real_t Vector3::distance_to(const Vector3 &p_b) const { diff --git a/core/os/input_event.cpp b/core/os/input_event.cpp index a072017353..9c5066da3d 100644 --- a/core/os/input_event.cpp +++ b/core/os/input_event.cpp @@ -1010,6 +1010,14 @@ bool InputEventAction::is_pressed() const { return pressed; } +void InputEventAction::set_strength(float p_strength) { + strength = CLAMP(p_strength, 0.0f, 1.0f); +} + +float InputEventAction::get_strength() const { + return strength; +} + bool InputEventAction::shortcut_match(const Ref<InputEvent> &p_event) const { if (p_event.is_null()) return false; @@ -1051,14 +1059,19 @@ void InputEventAction::_bind_methods() { ClassDB::bind_method(D_METHOD("set_pressed", "pressed"), &InputEventAction::set_pressed); //ClassDB::bind_method(D_METHOD("is_pressed"), &InputEventAction::is_pressed); + ClassDB::bind_method(D_METHOD("set_strength", "strength"), &InputEventAction::set_strength); + ClassDB::bind_method(D_METHOD("get_strength"), &InputEventAction::get_strength); + // ClassDB::bind_method(D_METHOD("is_action", "name"), &InputEventAction::is_action); ADD_PROPERTY(PropertyInfo(Variant::STRING, "action"), "set_action", "get_action"); ADD_PROPERTY(PropertyInfo(Variant::BOOL, "pressed"), "set_pressed", "is_pressed"); + ADD_PROPERTY(PropertyInfo(Variant::REAL, "strength", PROPERTY_HINT_RANGE, "0,1,0.01"), "set_strength", "get_strength"); } InputEventAction::InputEventAction() { pressed = false; + strength = 1.0f; } ///////////////////////////// diff --git a/core/os/input_event.h b/core/os/input_event.h index ba01516519..4f5762e756 100644 --- a/core/os/input_event.h +++ b/core/os/input_event.h @@ -117,6 +117,16 @@ enum JoystickList { JOY_WII_MINUS = JOY_BUTTON_10, JOY_WII_PLUS = JOY_BUTTON_11, + JOY_VR_GRIP = JOY_BUTTON_2, + JOY_VR_PAD = JOY_BUTTON_14, + JOY_VR_TRIGGER = JOY_BUTTON_15, + + JOY_OCULUS_AX = JOY_BUTTON_7, + JOY_OCULUS_BY = JOY_BUTTON_1, + JOY_OCULUS_MENU = JOY_BUTTON_3, + + JOY_OPENVR_MENU = JOY_BUTTON_1, + // end of history JOY_AXIS_0 = 0, @@ -139,6 +149,12 @@ enum JoystickList { JOY_ANALOG_L2 = JOY_AXIS_6, JOY_ANALOG_R2 = JOY_AXIS_7, + + JOY_VR_ANALOG_TRIGGER = JOY_AXIS_2, + JOY_VR_ANALOG_GRIP = JOY_AXIS_4, + + JOY_OPENVR_TOUCHPADX = JOY_AXIS_0, + JOY_OPENVR_TOUCHPADY = JOY_AXIS_1, }; enum MidiMessageList { @@ -157,7 +173,7 @@ enum MidiMessageList { */ class InputEvent : public Resource { - GDCLASS(InputEvent, Resource) + GDCLASS(InputEvent, Resource); int device; @@ -194,7 +210,7 @@ public: }; class InputEventWithModifiers : public InputEvent { - GDCLASS(InputEventWithModifiers, InputEvent) + GDCLASS(InputEventWithModifiers, InputEvent); bool shift; bool alt; @@ -240,7 +256,7 @@ public: class InputEventKey : public InputEventWithModifiers { - GDCLASS(InputEventKey, InputEventWithModifiers) + GDCLASS(InputEventKey, InputEventWithModifiers); bool pressed; /// otherwise release @@ -279,7 +295,7 @@ public: class InputEventMouse : public InputEventWithModifiers { - GDCLASS(InputEventMouse, InputEventWithModifiers) + GDCLASS(InputEventMouse, InputEventWithModifiers); int button_mask; @@ -304,7 +320,7 @@ public: class InputEventMouseButton : public InputEventMouse { - GDCLASS(InputEventMouseButton, InputEventMouse) + GDCLASS(InputEventMouseButton, InputEventMouse); float factor; int button_index; @@ -338,7 +354,7 @@ public: class InputEventMouseMotion : public InputEventMouse { - GDCLASS(InputEventMouseMotion, InputEventMouse) + GDCLASS(InputEventMouseMotion, InputEventMouse); Vector2 relative; Vector2 speed; @@ -362,7 +378,7 @@ public: class InputEventJoypadMotion : public InputEvent { - GDCLASS(InputEventJoypadMotion, InputEvent) + GDCLASS(InputEventJoypadMotion, InputEvent); int axis; ///< Joypad axis float axis_value; ///< -1 to 1 @@ -387,7 +403,7 @@ public: }; class InputEventJoypadButton : public InputEvent { - GDCLASS(InputEventJoypadButton, InputEvent) + GDCLASS(InputEventJoypadButton, InputEvent); int button_index; bool pressed; @@ -415,7 +431,7 @@ public: }; class InputEventScreenTouch : public InputEvent { - GDCLASS(InputEventScreenTouch, InputEvent) + GDCLASS(InputEventScreenTouch, InputEvent); int index; Vector2 pos; bool pressed; @@ -441,7 +457,7 @@ public: class InputEventScreenDrag : public InputEvent { - GDCLASS(InputEventScreenDrag, InputEvent) + GDCLASS(InputEventScreenDrag, InputEvent); int index; Vector2 pos; Vector2 relative; @@ -471,10 +487,11 @@ public: class InputEventAction : public InputEvent { - GDCLASS(InputEventAction, InputEvent) + GDCLASS(InputEventAction, InputEvent); StringName action; bool pressed; + float strength; protected: static void _bind_methods(); @@ -486,6 +503,9 @@ public: void set_pressed(bool p_pressed); virtual bool is_pressed() const; + void set_strength(float p_strength); + float get_strength() const; + virtual bool is_action(const StringName &p_action) const; virtual bool action_match(const Ref<InputEvent> &p_event, bool *p_pressed, float *p_strength, float p_deadzone) const; @@ -499,7 +519,7 @@ public: class InputEventGesture : public InputEventWithModifiers { - GDCLASS(InputEventGesture, InputEventWithModifiers) + GDCLASS(InputEventGesture, InputEventWithModifiers); Vector2 pos; @@ -513,7 +533,7 @@ public: class InputEventMagnifyGesture : public InputEventGesture { - GDCLASS(InputEventMagnifyGesture, InputEventGesture) + GDCLASS(InputEventMagnifyGesture, InputEventGesture); real_t factor; protected: @@ -531,7 +551,7 @@ public: class InputEventPanGesture : public InputEventGesture { - GDCLASS(InputEventPanGesture, InputEventGesture) + GDCLASS(InputEventPanGesture, InputEventGesture); Vector2 delta; protected: @@ -548,7 +568,7 @@ public: }; class InputEventMIDI : public InputEvent { - GDCLASS(InputEventMIDI, InputEvent) + GDCLASS(InputEventMIDI, InputEvent); int channel; int message; diff --git a/core/os/os.h b/core/os/os.h index 4f6a539e78..514e1e2ad3 100644 --- a/core/os/os.h +++ b/core/os/os.h @@ -104,7 +104,6 @@ public: bool maximized; bool always_on_top; bool use_vsync; - bool layered_splash; bool layered; float get_aspect() const { return (float)width / (float)height; } VideoMode(int p_width = 1024, int p_height = 600, bool p_fullscreen = false, bool p_resizable = true, bool p_borderless_window = false, bool p_maximized = false, bool p_always_on_top = false, bool p_use_vsync = false) { @@ -117,7 +116,6 @@ public: always_on_top = p_always_on_top; use_vsync = p_use_vsync; layered = false; - layered_splash = false; } }; @@ -207,8 +205,12 @@ public: virtual int get_screen_dpi(int p_screen = -1) const { return 72; } virtual Point2 get_window_position() const { return Vector2(); } virtual void set_window_position(const Point2 &p_position) {} + virtual Size2 get_max_window_size() const { return Size2(); }; + virtual Size2 get_min_window_size() const { return Size2(); }; virtual Size2 get_window_size() const = 0; virtual Size2 get_real_window_size() const { return get_window_size(); } + virtual void set_min_window_size(const Size2 p_size) {} + virtual void set_max_window_size(const Size2 p_size) {} virtual void set_window_size(const Size2 p_size) {} virtual void set_window_fullscreen(bool p_enabled) {} virtual bool is_window_fullscreen() const { return true; } diff --git a/core/print_string.cpp b/core/print_string.cpp index d91d49f53b..3271744af3 100644 --- a/core/print_string.cpp +++ b/core/print_string.cpp @@ -68,8 +68,8 @@ void remove_print_handler(PrintHandlerList *p_handler) { } //OS::get_singleton()->print("print handler list is %p\n",print_handler_list); - ERR_FAIL_COND(l == NULL); _global_unlock(); + ERR_FAIL_COND(l == NULL); } void print_line(String p_string) { diff --git a/core/project_settings.cpp b/core/project_settings.cpp index c86d1567dd..0508806a35 100644 --- a/core/project_settings.cpp +++ b/core/project_settings.cpp @@ -75,11 +75,19 @@ String ProjectSettings::localize_path(const String &p_path) const { memdelete(dir); - if (!cwd.begins_with(resource_path)) { + // Ensure that we end with a '/'. + // This is important to ensure that we do not wrongly localize the resource path + // in an absolute path that just happens to contain this string but points to a + // different folder (e.g. "/my/project" as resource_path would be contained in + // "/my/project_data", even though the latter is not part of res://. + // `plus_file("")` is an easy way to ensure we have a trailing '/'. + const String res_path = resource_path.plus_file(""); + + if (!cwd.begins_with(res_path)) { return p_path; }; - return cwd.replace_first(resource_path, "res:/"); + return cwd.replace_first(res_path, "res://"); } else { memdelete(dir); @@ -481,7 +489,7 @@ Error ProjectSettings::_load_settings_binary(const String p_path) { memdelete(f); ERR_EXPLAIN("Corrupted header in binary project.binary (not ECFG)"); - ERR_FAIL_V(ERR_FILE_CORRUPT;) + ERR_FAIL_V(ERR_FILE_CORRUPT); } uint32_t count = f->get_32(); @@ -571,10 +579,6 @@ Error ProjectSettings::_load_settings_text(const String p_path) { section = next_tag.name; } } - - memdelete(f); - - return OK; } Error ProjectSettings::_load_settings_text_or_binary(const String p_text_path, const String p_bin_path) { @@ -632,7 +636,7 @@ Error ProjectSettings::_save_settings_binary(const String &p_file, const Map<Str if (err != OK) { ERR_EXPLAIN("Couldn't save project.binary at " + p_file); - ERR_FAIL_COND_V(err, err) + ERR_FAIL_COND_V(err, err); } uint8_t hdr[4] = { 'E', 'C', 'F', 'G' }; @@ -724,7 +728,7 @@ Error ProjectSettings::_save_settings_text(const String &p_file, const Map<Strin if (err) { ERR_EXPLAIN("Couldn't save project.godot - " + p_file); - ERR_FAIL_COND_V(err, err) + ERR_FAIL_COND_V(err, err); } file->store_line("; Engine configuration file."); @@ -1007,6 +1011,15 @@ ProjectSettings::ProjectSettings() { GLOBAL_DEF("audio/default_bus_layout", "res://default_bus_layout.tres"); custom_prop_info["audio/default_bus_layout"] = PropertyInfo(Variant::STRING, "audio/default_bus_layout", PROPERTY_HINT_FILE, "*.tres"); + PoolStringArray extensions = PoolStringArray(); + extensions.push_back("gd"); + if (Engine::get_singleton()->has_singleton("GodotSharp")) + extensions.push_back("cs"); + extensions.push_back("shader"); + + GLOBAL_DEF("editor/search_in_file_extensions", extensions); + custom_prop_info["editor/search_in_file_extensions"] = PropertyInfo(Variant::POOL_STRING_ARRAY, "editor/search_in_file_extensions"); + action = Dictionary(); action["deadzone"] = Variant(0.5f); events = Array(); diff --git a/core/register_core_types.cpp b/core/register_core_types.cpp index 97c96b4018..135df4e5bd 100644 --- a/core/register_core_types.cpp +++ b/core/register_core_types.cpp @@ -184,6 +184,7 @@ void register_core_types() { ClassDB::register_class<PackedDataContainer>(); ClassDB::register_virtual_class<PackedDataContainerRef>(); ClassDB::register_class<AStar>(); + ClassDB::register_class<AStar2D>(); ClassDB::register_class<EncodedObjectAsID>(); ClassDB::register_class<RandomNumberGenerator>(); diff --git a/core/script_language.h b/core/script_language.h index b2dab666c4..b0c60b4e90 100644 --- a/core/script_language.h +++ b/core/script_language.h @@ -250,7 +250,7 @@ public: virtual Error open_in_external_editor(const Ref<Script> &p_script, int p_line, int p_col) { return ERR_UNAVAILABLE; } virtual bool overrides_external_editor() { return false; } - virtual Error complete_code(const String &p_code, const String &p_base_path, Object *p_owner, List<String> *r_options, bool &r_force, String &r_call_hint) { return ERR_UNAVAILABLE; } + virtual Error complete_code(const String &p_code, const String &p_path, Object *p_owner, List<String> *r_options, bool &r_force, String &r_call_hint) { return ERR_UNAVAILABLE; } struct LookupResult { enum Type { @@ -269,7 +269,7 @@ public: int location; }; - virtual Error lookup_code(const String &p_code, const String &p_symbol, const String &p_base_path, Object *p_owner, LookupResult &r_result) { return ERR_UNAVAILABLE; } + virtual Error lookup_code(const String &p_code, const String &p_symbol, const String &p_path, Object *p_owner, LookupResult &r_result) { return ERR_UNAVAILABLE; } virtual void auto_indent_code(String &p_code, int p_from_line, int p_to_line) const = 0; virtual void add_global_constant(const StringName &p_variable, const Variant &p_value) = 0; diff --git a/core/sort_array.h b/core/sort_array.h index 0f258aec3e..8660ee3333 100644 --- a/core/sort_array.h +++ b/core/sort_array.h @@ -179,14 +179,14 @@ public: while (true) { while (compare(p_array[p_first], p_pivot)) { if (Validate) { - ERR_BAD_COMPARE(p_first == unmodified_last - 1) + ERR_BAD_COMPARE(p_first == unmodified_last - 1); } p_first++; } p_last--; while (compare(p_pivot, p_array[p_last])) { if (Validate) { - ERR_BAD_COMPARE(p_last == unmodified_first) + ERR_BAD_COMPARE(p_last == unmodified_first); } p_last--; } @@ -259,7 +259,7 @@ public: int next = p_last - 1; while (compare(p_value, p_array[next])) { if (Validate) { - ERR_BAD_COMPARE(next == 0) + ERR_BAD_COMPARE(next == 0); } p_array[p_last] = p_array[next]; p_last = next; diff --git a/core/ustring.cpp b/core/ustring.cpp index 954c39c150..686aa6f8e3 100644 --- a/core/ustring.cpp +++ b/core/ustring.cpp @@ -2331,6 +2331,9 @@ String String::insert(int p_at_pos, const String &p_string) const { } String String::substr(int p_from, int p_chars) const { + if (p_chars == -1) + p_chars = length() - p_from; + if (empty() || p_from < 0 || p_from >= length() || p_chars <= 0) return ""; @@ -2956,26 +2959,12 @@ String String::replace(const char *p_key, const char *p_with) const { String String::replace_first(const String &p_key, const String &p_with) const { - String new_string; - int search_from = 0; - int result = 0; - - while ((result = find(p_key, search_from)) >= 0) { - - new_string += substr(search_from, result - search_from); - new_string += p_with; - search_from = result + p_key.length(); - break; + int pos = find(p_key); + if (pos >= 0) { + return substr(0, pos) + p_with + substr(pos + p_key.length(), length()); } - if (search_from == 0) { - - return *this; - } - - new_string += substr(search_from, length() - search_from); - - return new_string; + return *this; } String String::replacen(const String &p_key, const String &p_with) const { @@ -3102,29 +3091,16 @@ String String::strip_edges(bool left, bool right) const { String String::strip_escapes() const { - int len = length(); - int beg = 0, end = len; - + String new_string; for (int i = 0; i < length(); i++) { - if (operator[](i) <= 31) - beg++; - else - break; - } - - for (int i = (int)(length() - 1); i >= 0; i--) { - - if (operator[](i) <= 31) - end--; - else - break; + // Escape characters on first page of the ASCII table, before 32 (Space). + if (operator[](i) < 32) + continue; + new_string += operator[](i); } - if (beg == 0 && end == len) - return *this; - - return substr(beg, end - beg); + return new_string; } String String::lstrip(const String &p_chars) const { @@ -3248,7 +3224,7 @@ static int _humanize_digits(int p_num) { String String::humanize_size(size_t p_size) { uint64_t _div = 1; - static const char *prefix[] = { " Bytes", " KB", " MB", " GB", "TB", " PB", "HB", "" }; + static const char *prefix[] = { " Bytes", " KB", " MB", " GB", " TB", " PB", " EB", "" }; int prefix_idx = 0; while (p_size > (_div * 1024) && prefix[prefix_idx][0]) { @@ -3259,7 +3235,7 @@ String String::humanize_size(size_t p_size) { int digits = prefix_idx > 0 ? _humanize_digits(p_size / _div) : 0; double divisor = prefix_idx > 0 ? _div : 1; - return String::num(p_size / divisor, digits) + prefix[prefix_idx]; + return String::num(p_size / divisor).pad_decimals(digits) + prefix[prefix_idx]; } bool String::is_abs_path() const { diff --git a/core/ustring.h b/core/ustring.h index be6300ac5b..ecf934a26b 100644 --- a/core/ustring.h +++ b/core/ustring.h @@ -201,7 +201,7 @@ public: } /* complex helpers */ - String substr(int p_from, int p_chars) const; + String substr(int p_from, int p_chars = -1) const; int find(const String &p_str, int p_from = 0) const; ///< return <0 if failed int find(const char *p_str, int p_from = 0) const; ///< return <0 if failed int find_char(const CharType &p_char, int p_from = 0) const; ///< return <0 if failed @@ -415,16 +415,16 @@ _FORCE_INLINE_ bool is_str_less(const L *l_ptr, const R *r_ptr) { //gets parsed String TTR(const String &); -//use for c strings -#define TTRC(m_value) m_value +//use for C strings +#define TTRC(m_value) (m_value) //use to avoid parsing (for use later with C strings) #define TTRGET(m_value) TTR(m_value) #else -#define TTR(m_val) (String()) -#define TTRCDEF(m_value) (m_value) +#define TTR(m_value) (String()) #define TTRC(m_value) (m_value) +#define TTRGET(m_value) (m_value) #endif diff --git a/core/variant_call.cpp b/core/variant_call.cpp index f9f73b4e51..dc28f1ca02 100644 --- a/core/variant_call.cpp +++ b/core/variant_call.cpp @@ -265,6 +265,7 @@ struct _VariantCall { VCALL_LOCALMEM1R(String, right); VCALL_LOCALMEM0R(String, dedent); VCALL_LOCALMEM2R(String, strip_edges); + VCALL_LOCALMEM0R(String, strip_escapes); VCALL_LOCALMEM1R(String, lstrip); VCALL_LOCALMEM1R(String, rstrip); VCALL_LOCALMEM0R(String, get_extension); @@ -284,6 +285,8 @@ struct _VariantCall { VCALL_LOCALMEM0R(String, get_file); VCALL_LOCALMEM0R(String, xml_escape); VCALL_LOCALMEM0R(String, xml_unescape); + VCALL_LOCALMEM0R(String, http_escape); + VCALL_LOCALMEM0R(String, http_unescape); VCALL_LOCALMEM0R(String, c_escape); VCALL_LOCALMEM0R(String, c_unescape); VCALL_LOCALMEM0R(String, json_escape); @@ -347,6 +350,7 @@ struct _VariantCall { VCALL_LOCALMEM2R(Vector2, linear_interpolate); VCALL_LOCALMEM2R(Vector2, slerp); VCALL_LOCALMEM4R(Vector2, cubic_interpolate); + VCALL_LOCALMEM2R(Vector2, move_toward); VCALL_LOCALMEM1R(Vector2, rotated); VCALL_LOCALMEM0R(Vector2, tangent); VCALL_LOCALMEM0R(Vector2, floor); @@ -388,6 +392,7 @@ struct _VariantCall { VCALL_LOCALMEM2R(Vector3, linear_interpolate); VCALL_LOCALMEM2R(Vector3, slerp); VCALL_LOCALMEM4R(Vector3, cubic_interpolate); + VCALL_LOCALMEM2R(Vector3, move_toward); VCALL_LOCALMEM1R(Vector3, dot); VCALL_LOCALMEM1R(Vector3, cross); VCALL_LOCALMEM1R(Vector3, outer); @@ -1494,7 +1499,7 @@ void register_variant_methods() { ADDFUNC1R(STRING, INT, String, casecmp_to, STRING, "to", varray()); ADDFUNC1R(STRING, INT, String, nocasecmp_to, STRING, "to", varray()); ADDFUNC0R(STRING, INT, String, length, varray()); - ADDFUNC2R(STRING, STRING, String, substr, INT, "from", INT, "len", varray()); + ADDFUNC2R(STRING, STRING, String, substr, INT, "from", INT, "len", varray(-1)); ADDFUNC2R(STRING, INT, String, find, STRING, "what", INT, "from", varray(0)); @@ -1516,9 +1521,9 @@ void register_variant_methods() { ADDFUNC2R(STRING, STRING, String, replacen, STRING, "what", STRING, "forwhat", varray()); ADDFUNC2R(STRING, STRING, String, insert, INT, "position", STRING, "what", varray()); ADDFUNC0R(STRING, STRING, String, capitalize, varray()); - ADDFUNC3R(STRING, POOL_STRING_ARRAY, String, split, STRING, "divisor", BOOL, "allow_empty", INT, "maxsplit", varray(true, 0)); - ADDFUNC3R(STRING, POOL_STRING_ARRAY, String, rsplit, STRING, "divisor", BOOL, "allow_empty", INT, "maxsplit", varray(true, 0)); - ADDFUNC2R(STRING, POOL_REAL_ARRAY, String, split_floats, STRING, "divisor", BOOL, "allow_empty", varray(true)); + ADDFUNC3R(STRING, POOL_STRING_ARRAY, String, split, STRING, "delimiter", BOOL, "allow_empty", INT, "maxsplit", varray(true, 0)); + ADDFUNC3R(STRING, POOL_STRING_ARRAY, String, rsplit, STRING, "delimiter", BOOL, "allow_empty", INT, "maxsplit", varray(true, 0)); + ADDFUNC2R(STRING, POOL_REAL_ARRAY, String, split_floats, STRING, "delimiter", BOOL, "allow_empty", varray(true)); ADDFUNC0R(STRING, STRING, String, to_upper, varray()); ADDFUNC0R(STRING, STRING, String, to_lower, varray()); @@ -1526,6 +1531,7 @@ void register_variant_methods() { ADDFUNC1R(STRING, STRING, String, left, INT, "position", varray()); ADDFUNC1R(STRING, STRING, String, right, INT, "position", varray()); ADDFUNC2R(STRING, STRING, String, strip_edges, BOOL, "left", BOOL, "right", varray(true, true)); + ADDFUNC0R(STRING, STRING, String, strip_escapes, varray()); ADDFUNC1R(STRING, STRING, String, lstrip, STRING, "chars", varray()); ADDFUNC1R(STRING, STRING, String, rstrip, STRING, "chars", varray()); ADDFUNC0R(STRING, STRING, String, get_extension, varray()); @@ -1546,6 +1552,8 @@ void register_variant_methods() { ADDFUNC0R(STRING, STRING, String, get_file, varray()); ADDFUNC0R(STRING, STRING, String, xml_escape, varray()); ADDFUNC0R(STRING, STRING, String, xml_unescape, varray()); + ADDFUNC0R(STRING, STRING, String, http_escape, varray()); + ADDFUNC0R(STRING, STRING, String, http_unescape, varray()); ADDFUNC0R(STRING, STRING, String, c_escape, varray()); ADDFUNC0R(STRING, STRING, String, c_unescape, varray()); ADDFUNC0R(STRING, STRING, String, json_escape, varray()); @@ -1583,6 +1591,7 @@ void register_variant_methods() { ADDFUNC2R(VECTOR2, VECTOR2, Vector2, linear_interpolate, VECTOR2, "b", REAL, "t", varray()); ADDFUNC2R(VECTOR2, VECTOR2, Vector2, slerp, VECTOR2, "b", REAL, "t", varray()); ADDFUNC4R(VECTOR2, VECTOR2, Vector2, cubic_interpolate, VECTOR2, "b", VECTOR2, "pre_a", VECTOR2, "post_b", REAL, "t", varray()); + ADDFUNC2R(VECTOR2, VECTOR2, Vector2, move_toward, VECTOR2, "to", REAL, "delta", varray()); ADDFUNC1R(VECTOR2, VECTOR2, Vector2, rotated, REAL, "phi", varray()); ADDFUNC0R(VECTOR2, VECTOR2, Vector2, tangent, varray()); ADDFUNC0R(VECTOR2, VECTOR2, Vector2, floor, varray()); @@ -1624,6 +1633,7 @@ void register_variant_methods() { ADDFUNC2R(VECTOR3, VECTOR3, Vector3, slerp, VECTOR3, "b", REAL, "t", varray()); ADDFUNC4R(VECTOR3, VECTOR3, Vector3, cubic_interpolate, VECTOR3, "b", VECTOR3, "pre_a", VECTOR3, "post_b", REAL, "t", varray()); ADDFUNC1R(VECTOR3, VECTOR3, Vector3, direction_to, VECTOR3, "b", varray()); + ADDFUNC2R(VECTOR3, VECTOR3, Vector3, move_toward, VECTOR3, "to", REAL, "delta", varray()); ADDFUNC1R(VECTOR3, REAL, Vector3, dot, VECTOR3, "b", varray()); ADDFUNC1R(VECTOR3, VECTOR3, Vector3, cross, VECTOR3, "b", varray()); ADDFUNC1R(VECTOR3, BASIS, Vector3, outer, VECTOR3, "b", varray()); diff --git a/core/vector.h b/core/vector.h index 93ee003519..e6bb4a96fc 100644 --- a/core/vector.h +++ b/core/vector.h @@ -150,7 +150,7 @@ template <class T> bool Vector<T>::push_back(const T &p_elem) { Error err = resize(size() + 1); - ERR_FAIL_COND_V(err, true) + ERR_FAIL_COND_V(err, true); set(size() - 1, p_elem); return false; |