diff options
Diffstat (limited to 'core')
41 files changed, 493 insertions, 216 deletions
diff --git a/core/array.cpp b/core/array.cpp index 44c553e4eb..ebad0df126 100644 --- a/core/array.cpp +++ b/core/array.cpp @@ -355,11 +355,58 @@ Variant Array::pop_front() { return Variant(); } +Variant Array::min() const { + + Variant minval; + for (int i = 0; i < size(); i++) { + if (i == 0) { + minval = get(i); + } else { + bool valid; + Variant ret; + Variant test = get(i); + Variant::evaluate(Variant::OP_LESS, test, minval, ret, valid); + if (!valid) { + return Variant(); //not a valid comparison + } + if (bool(ret)) { + //is less + minval = test; + } + } + } + return minval; +} + +Variant Array::max() const { + + Variant maxval; + for (int i = 0; i < size(); i++) { + if (i == 0) { + maxval = get(i); + } else { + bool valid; + Variant ret; + Variant test = get(i); + Variant::evaluate(Variant::OP_GREATER, test, maxval, ret, valid); + if (!valid) { + return Variant(); //not a valid comparison + } + if (bool(ret)) { + //is less + maxval = test; + } + } + } + return maxval; +} + Array::Array(const Array &p_from) { _p = NULL; _ref(p_from); } + Array::Array() { _p = memnew(ArrayPrivate); diff --git a/core/array.h b/core/array.h index e549a886e6..c824c9b4f7 100644 --- a/core/array.h +++ b/core/array.h @@ -90,6 +90,9 @@ public: Array duplicate(bool p_deep = false) const; + Variant min() const; + Variant max() const; + Array(const Array &p_from); Array(); ~Array(); diff --git a/core/bind/core_bind.cpp b/core/bind/core_bind.cpp index 26ba28370f..2bd271205a 100644 --- a/core/bind/core_bind.cpp +++ b/core/bind/core_bind.cpp @@ -240,6 +240,14 @@ PoolStringArray _OS::get_connected_midi_inputs() { return OS::get_singleton()->get_connected_midi_inputs(); } +void _OS::open_midi_inputs() { + return OS::get_singleton()->open_midi_inputs(); +} + +void _OS::close_midi_inputs() { + return OS::get_singleton()->close_midi_inputs(); +} + void _OS::set_video_mode(const Size2 &p_size, bool p_fullscreen, bool p_resizeable, int p_screen) { OS::VideoMode vm; @@ -1085,6 +1093,8 @@ void _OS::_bind_methods() { ClassDB::bind_method(D_METHOD("get_audio_driver_count"), &_OS::get_audio_driver_count); ClassDB::bind_method(D_METHOD("get_audio_driver_name", "driver"), &_OS::get_audio_driver_name); ClassDB::bind_method(D_METHOD("get_connected_midi_inputs"), &_OS::get_connected_midi_inputs); + ClassDB::bind_method(D_METHOD("open_midi_inputs"), &_OS::open_midi_inputs); + ClassDB::bind_method(D_METHOD("close_midi_inputs"), &_OS::close_midi_inputs); ClassDB::bind_method(D_METHOD("get_screen_count"), &_OS::get_screen_count); ClassDB::bind_method(D_METHOD("get_current_screen"), &_OS::get_current_screen); diff --git a/core/bind/core_bind.h b/core/bind/core_bind.h index b587b9257f..21aea12b23 100644 --- a/core/bind/core_bind.h +++ b/core/bind/core_bind.h @@ -157,6 +157,8 @@ public: virtual String get_audio_driver_name(int p_driver) const; virtual PoolStringArray get_connected_midi_inputs(); + virtual void open_midi_inputs(); + virtual void close_midi_inputs(); virtual int get_screen_count() const; virtual int get_current_screen() const; diff --git a/core/class_db.h b/core/class_db.h index f1d1879236..66a67f6c9f 100644 --- a/core/class_db.h +++ b/core/class_db.h @@ -39,6 +39,10 @@ @author Juan Linietsky <reduzio@gmail.com> */ +/** To bind more then 6 parameters include this: + * #include "method_bind_ext.gen.inc" + */ + #define DEFVAL(m_defval) (m_defval) //#define SIMPLE_METHODDEF diff --git a/core/color.cpp b/core/color.cpp index fcfcf20355..17c9e2daeb 100644 --- a/core/color.cpp +++ b/core/color.cpp @@ -253,6 +253,21 @@ Color Color::hex64(uint64_t p_hex) { return Color(r, g, b, a); } +Color Color::from_rgbe9995(uint32_t p_rgbe) { + + float r = p_rgbe & 0x1ff; + float g = (p_rgbe >> 9) & 0x1ff; + float b = (p_rgbe >> 18) & 0x1ff; + float e = (p_rgbe >> 27); + float m = Math::pow(2, e - 15.0 - 9.0); + + float rd = r * m; + float gd = g * m; + float bd = b * m; + + return Color(rd, gd, bd, 1.0f); +} + static float _parse_col(const String &p_str, int p_ofs) { int ig = 0; @@ -506,8 +521,11 @@ Color Color::from_hsv(float p_h, float p_s, float p_v, float p_a) { return Color(m + r, m + g, m + b, p_a); } +// FIXME: Remove once Godot 3.1 has been released 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 return (r + g + b) / 3.0; } diff --git a/core/color.h b/core/color.h index c0516e55fe..00f4c9e9e8 100644 --- a/core/color.h +++ b/core/color.h @@ -195,6 +195,7 @@ struct Color { static Color named(const String &p_name); String to_html(bool p_alpha = true) const; Color from_hsv(float p_h, float p_s, float p_v, float p_a); + static Color from_rgbe9995(uint32_t p_color); _FORCE_INLINE_ bool operator<(const Color &p_color) const; //used in set keys operator String() const; diff --git a/core/compressed_translation.cpp b/core/compressed_translation.cpp index 5c1fd26e2a..46df63066b 100644 --- a/core/compressed_translation.cpp +++ b/core/compressed_translation.cpp @@ -50,7 +50,6 @@ void PHashTranslation::generate(const Ref<Translation> &p_from) { int size = Math::larger_prime(keys.size()); - print_line("compressing keys: " + itos(keys.size())); Vector<Vector<Pair<int, CharString> > > buckets; Vector<Map<uint32_t, int> > table; Vector<uint32_t> hfunc_table; @@ -107,7 +106,6 @@ void PHashTranslation::generate(const Ref<Translation> &p_from) { } int bucket_table_size = 0; - print_line("total compressed string size: " + itos(total_compression_size) + " (" + itos(total_string_size) + " uncompressed)."); for (int i = 0; i < size; i++) { @@ -117,8 +115,6 @@ void PHashTranslation::generate(const Ref<Translation> &p_from) { if (b.size() == 0) continue; - //print_line("bucket: "+itos(i)+" - elements: "+itos(b.size())); - int d = 1; int item = 0; @@ -140,9 +136,6 @@ void PHashTranslation::generate(const Ref<Translation> &p_from) { bucket_table_size += 2 + b.size() * 4; } - print_line("bucket table size: " + itos(bucket_table_size * 4)); - print_line("hash table size: " + itos(size * 4)); - hash_table.resize(size); bucket_table.resize(bucket_table_size); @@ -178,8 +171,6 @@ void PHashTranslation::generate(const Ref<Translation> &p_from) { } } - print_line("total collisions: " + itos(collisions)); - strings.resize(total_compression_size); PoolVector<uint8_t>::Write cw = strings.write(); @@ -198,15 +189,11 @@ bool PHashTranslation::_set(const StringName &p_name, const Variant &p_value) { String name = p_name.operator String(); if (name == "hash_table") { hash_table = p_value; - //print_line("translation: loaded hash table of size: "+itos(hash_table.size())); } else if (name == "bucket_table") { bucket_table = p_value; - //print_line("translation: loaded bucket table of size: "+itos(bucket_table.size())); } else if (name == "strings") { strings = p_value; - //print_line("translation: loaded string table of size: "+itos(strings.size())); } else if (name == "load_from") { - //print_line("generating"); generate(p_value); } else return false; @@ -248,11 +235,7 @@ StringName PHashTranslation::get_message(const StringName &p_src_text) const { uint32_t p = htptr[h % htsize]; - //print_line("String: "+p_src_text.operator String()); - //print_line("Hash: "+itos(p)); - if (p == 0xFFFFFFFF) { - //print_line("GETMSG: Nothing!"); return StringName(); //nothing } @@ -271,9 +254,7 @@ StringName PHashTranslation::get_message(const StringName &p_src_text) const { } } - //print_line("bucket pos: "+itos(idx)); if (idx == -1) { - //print_line("GETMSG: Not in Bucket!"); return StringName(); } @@ -281,8 +262,6 @@ StringName PHashTranslation::get_message(const StringName &p_src_text) const { String rstr; rstr.parse_utf8(&sptr[bucket.elem[idx].str_offset], bucket.elem[idx].uncomp_size); - //print_line("Uncompressed, size: "+itos(bucket.elem[idx].comp_size)); - //print_line("Return: "+rstr); return rstr; } else { @@ -292,8 +271,6 @@ StringName PHashTranslation::get_message(const StringName &p_src_text) const { smaz_decompress(&sptr[bucket.elem[idx].str_offset], bucket.elem[idx].comp_size, uncomp.ptrw(), bucket.elem[idx].uncomp_size); String rstr; rstr.parse_utf8(uncomp.get_data()); - //print_line("Compressed, size: "+itos(bucket.elem[idx].comp_size)); - //print_line("Return: "+rstr); return rstr; } } diff --git a/core/global_constants.cpp b/core/global_constants.cpp index 187813f9d0..962881e720 100644 --- a/core/global_constants.cpp +++ b/core/global_constants.cpp @@ -532,6 +532,7 @@ void register_global_constants() { BIND_GLOBAL_ENUM_CONSTANT(PROPERTY_HINT_GLOBAL_DIR); BIND_GLOBAL_ENUM_CONSTANT(PROPERTY_HINT_RESOURCE_TYPE); BIND_GLOBAL_ENUM_CONSTANT(PROPERTY_HINT_MULTILINE_TEXT); + BIND_GLOBAL_ENUM_CONSTANT(PROPERTY_HINT_PLACEHOLDER_TEXT); BIND_GLOBAL_ENUM_CONSTANT(PROPERTY_HINT_COLOR_NO_ALPHA); BIND_GLOBAL_ENUM_CONSTANT(PROPERTY_HINT_IMAGE_COMPRESS_LOSSY); BIND_GLOBAL_ENUM_CONSTANT(PROPERTY_HINT_IMAGE_COMPRESS_LOSSLESS); diff --git a/core/image.cpp b/core/image.cpp index c94f2c3534..7778169995 100644 --- a/core/image.cpp +++ b/core/image.cpp @@ -37,6 +37,7 @@ #include "print_string.h" #include "io/resource_loader.h" +#include "math_funcs.h" #include "thirdparty/misc/hq2x.h" #include <stdio.h> @@ -525,7 +526,7 @@ static double _bicubic_interp_kernel(double x) { return bc; } -template <int CC> +template <int CC, class T> static void _scale_cubic(const uint8_t *__restrict p_src, uint8_t *__restrict p_dst, uint32_t p_src_width, uint32_t p_src_height, uint32_t p_dst_width, uint32_t p_dst_height) { // get source image size @@ -556,7 +557,7 @@ static void _scale_cubic(const uint8_t *__restrict p_src, uint8_t *__restrict p_ // initial pixel value - uint8_t *__restrict dst = p_dst + (y * p_dst_width + x) * CC; + T *__restrict dst = ((T *)p_dst) + (y * p_dst_width + x) * CC; double color[CC]; for (int i = 0; i < CC; i++) { @@ -584,23 +585,32 @@ static void _scale_cubic(const uint8_t *__restrict p_src, uint8_t *__restrict p_ ox2 = xmax; // get pixel of original image - const uint8_t *__restrict p = p_src + (oy2 * p_src_width + ox2) * CC; + const T *__restrict p = ((T *)p_src) + (oy2 * p_src_width + ox2) * CC; for (int i = 0; i < CC; i++) { - - color[i] += p[i] * k2; + if (sizeof(T) == 2) { //half float + color[i] = Math::half_to_float(p[i]); + } else { + color[i] += p[i] * k2; + } } } } for (int i = 0; i < CC; i++) { - dst[i] = CLAMP(Math::fast_ftoi(color[i]), 0, 255); + if (sizeof(T) == 1) { //byte + dst[i] = CLAMP(Math::fast_ftoi(color[i]), 0, 255); + } else if (sizeof(T) == 2) { //half float + dst[i] = Math::make_half_float(color[i]); + } else { + dst[i] = color[i]; + } } } } } -template <int CC> +template <int CC, class T> static void _scale_bilinear(const uint8_t *__restrict p_src, uint8_t *__restrict p_dst, uint32_t p_src_width, uint32_t p_src_height, uint32_t p_dst_width, uint32_t p_dst_height) { enum { @@ -640,22 +650,58 @@ static void _scale_bilinear(const uint8_t *__restrict p_src, uint8_t *__restrict for (uint32_t l = 0; l < CC; l++) { - uint32_t p00 = p_src[y_ofs_up + src_xofs_left + l] << FRAC_BITS; - uint32_t p10 = p_src[y_ofs_up + src_xofs_right + l] << FRAC_BITS; - uint32_t p01 = p_src[y_ofs_down + src_xofs_left + l] << FRAC_BITS; - uint32_t p11 = p_src[y_ofs_down + src_xofs_right + l] << FRAC_BITS; - - uint32_t interp_up = p00 + (((p10 - p00) * src_xofs_frac) >> FRAC_BITS); - uint32_t interp_down = p01 + (((p11 - p01) * src_xofs_frac) >> FRAC_BITS); - uint32_t interp = interp_up + (((interp_down - interp_up) * src_yofs_frac) >> FRAC_BITS); - interp >>= FRAC_BITS; - p_dst[i * p_dst_width * CC + j * CC + l] = interp; + if (sizeof(T) == 1) { //uint8 + uint32_t p00 = p_src[y_ofs_up + src_xofs_left + l] << FRAC_BITS; + uint32_t p10 = p_src[y_ofs_up + src_xofs_right + l] << FRAC_BITS; + uint32_t p01 = p_src[y_ofs_down + src_xofs_left + l] << FRAC_BITS; + uint32_t p11 = p_src[y_ofs_down + src_xofs_right + l] << FRAC_BITS; + + uint32_t interp_up = p00 + (((p10 - p00) * src_xofs_frac) >> FRAC_BITS); + uint32_t interp_down = p01 + (((p11 - p01) * src_xofs_frac) >> FRAC_BITS); + uint32_t interp = interp_up + (((interp_down - interp_up) * src_yofs_frac) >> FRAC_BITS); + interp >>= FRAC_BITS; + p_dst[i * p_dst_width * CC + j * CC + l] = interp; + } else if (sizeof(T) == 2) { //half float + + float xofs_frac = float(src_xofs_frac) / (1 << FRAC_BITS); + float yofs_frac = float(src_yofs_frac) / (1 << FRAC_BITS); + const T *src = ((const T *)p_src); + T *dst = ((T *)p_dst); + + float p00 = Math::half_to_float(src[y_ofs_up + src_xofs_left + l]); + float p10 = Math::half_to_float(src[y_ofs_up + src_xofs_right + l]); + float p01 = Math::half_to_float(src[y_ofs_down + src_xofs_left + l]); + float p11 = Math::half_to_float(src[y_ofs_down + src_xofs_right + l]); + + float interp_up = p00 + (p10 - p00) * xofs_frac; + float interp_down = p01 + (p11 - p01) * xofs_frac; + float interp = interp_up + ((interp_down - interp_up) * yofs_frac); + + dst[i * p_dst_width * CC + j * CC + l] = Math::make_half_float(interp); + } else if (sizeof(T) == 4) { //float + + float xofs_frac = float(src_xofs_frac) / (1 << FRAC_BITS); + float yofs_frac = float(src_yofs_frac) / (1 << FRAC_BITS); + const T *src = ((const T *)p_src); + T *dst = ((T *)p_dst); + + float p00 = src[y_ofs_up + src_xofs_left + l]; + float p10 = src[y_ofs_up + src_xofs_right + l]; + float p01 = src[y_ofs_down + src_xofs_left + l]; + float p11 = src[y_ofs_down + src_xofs_right + l]; + + float interp_up = p00 + (p10 - p00) * xofs_frac; + float interp_down = p01 + (p11 - p01) * xofs_frac; + float interp = interp_up + ((interp_down - interp_up) * yofs_frac); + + dst[i * p_dst_width * CC + j * CC + l] = interp; + } } } } } -template <int CC> +template <int CC, class T> static void _scale_nearest(const uint8_t *__restrict p_src, uint8_t *__restrict p_dst, uint32_t p_src_width, uint32_t p_src_height, uint32_t p_dst_width, uint32_t p_dst_height) { for (uint32_t i = 0; i < p_dst_height; i++) { @@ -670,8 +716,11 @@ static void _scale_nearest(const uint8_t *__restrict p_src, uint8_t *__restrict for (uint32_t l = 0; l < CC; l++) { - uint32_t p = p_src[y_ofs + src_xofs + l]; - p_dst[i * p_dst_width * CC + j * CC + l] = p; + const T *src = ((const T *)p_src); + T *dst = ((T *)p_dst); + + T p = src[y_ofs + src_xofs + l]; + dst[i * p_dst_width * CC + j * CC + l] = p; } } } @@ -766,12 +815,30 @@ void Image::resize(int p_width, int p_height, Interpolation p_interpolation) { case INTERPOLATE_NEAREST: { - switch (get_format_pixel_size(format)) { - case 1: _scale_nearest<1>(r_ptr, w_ptr, width, height, p_width, p_height); break; - case 2: _scale_nearest<2>(r_ptr, w_ptr, width, height, p_width, p_height); break; - case 3: _scale_nearest<3>(r_ptr, w_ptr, width, height, p_width, p_height); break; - case 4: _scale_nearest<4>(r_ptr, w_ptr, width, height, p_width, p_height); break; + if (format >= FORMAT_L8 && format <= FORMAT_RGBA8) { + switch (get_format_pixel_size(format)) { + case 1: _scale_nearest<1, uint8_t>(r_ptr, w_ptr, width, height, p_width, p_height); break; + case 2: _scale_nearest<2, uint8_t>(r_ptr, w_ptr, width, height, p_width, p_height); break; + case 3: _scale_nearest<3, uint8_t>(r_ptr, w_ptr, width, height, p_width, p_height); break; + case 4: _scale_nearest<4, uint8_t>(r_ptr, w_ptr, width, height, p_width, p_height); break; + } + } else if (format >= FORMAT_RF && format <= FORMAT_RGBAF) { + switch (get_format_pixel_size(format)) { + case 4: _scale_nearest<1, float>(r_ptr, w_ptr, width, height, p_width, p_height); break; + case 8: _scale_nearest<2, float>(r_ptr, w_ptr, width, height, p_width, p_height); break; + case 12: _scale_nearest<3, float>(r_ptr, w_ptr, width, height, p_width, p_height); break; + case 16: _scale_nearest<4, float>(r_ptr, w_ptr, width, height, p_width, p_height); break; + } + + } else if (format >= FORMAT_RH && format <= FORMAT_RGBAH) { + switch (get_format_pixel_size(format)) { + case 2: _scale_nearest<1, uint16_t>(r_ptr, w_ptr, width, height, p_width, p_height); break; + case 4: _scale_nearest<2, uint16_t>(r_ptr, w_ptr, width, height, p_width, p_height); break; + case 6: _scale_nearest<3, uint16_t>(r_ptr, w_ptr, width, height, p_width, p_height); break; + case 8: _scale_nearest<4, uint16_t>(r_ptr, w_ptr, width, height, p_width, p_height); break; + } } + } break; case INTERPOLATE_BILINEAR: case INTERPOLATE_TRILINEAR: { @@ -812,11 +879,27 @@ void Image::resize(int p_width, int p_height, Interpolation p_interpolation) { } } - switch (get_format_pixel_size(format)) { - case 1: _scale_bilinear<1>(src_ptr, w_ptr, src_width, src_height, p_width, p_height); break; - case 2: _scale_bilinear<2>(src_ptr, w_ptr, src_width, src_height, p_width, p_height); break; - case 3: _scale_bilinear<3>(src_ptr, w_ptr, src_width, src_height, p_width, p_height); break; - case 4: _scale_bilinear<4>(src_ptr, w_ptr, src_width, src_height, p_width, p_height); break; + if (format >= FORMAT_L8 && format <= FORMAT_RGBA8) { + switch (get_format_pixel_size(format)) { + case 1: _scale_bilinear<1, uint8_t>(src_ptr, w_ptr, src_width, src_height, p_width, p_height); break; + case 2: _scale_bilinear<2, uint8_t>(src_ptr, w_ptr, src_width, src_height, p_width, p_height); break; + case 3: _scale_bilinear<3, uint8_t>(src_ptr, w_ptr, src_width, src_height, p_width, p_height); break; + case 4: _scale_bilinear<4, uint8_t>(src_ptr, w_ptr, src_width, src_height, p_width, p_height); break; + } + } else if (format >= FORMAT_RF && format <= FORMAT_RGBAF) { + switch (get_format_pixel_size(format)) { + case 4: _scale_bilinear<1, float>(src_ptr, w_ptr, src_width, src_height, p_width, p_height); break; + case 8: _scale_bilinear<2, float>(src_ptr, w_ptr, src_width, src_height, p_width, p_height); break; + case 12: _scale_bilinear<3, float>(src_ptr, w_ptr, src_width, src_height, p_width, p_height); break; + case 16: _scale_bilinear<4, float>(src_ptr, w_ptr, src_width, src_height, p_width, p_height); break; + } + } else if (format >= FORMAT_RH && format <= FORMAT_RGBAH) { + switch (get_format_pixel_size(format)) { + case 2: _scale_bilinear<1, uint16_t>(src_ptr, w_ptr, src_width, src_height, p_width, p_height); break; + case 4: _scale_bilinear<2, uint16_t>(src_ptr, w_ptr, src_width, src_height, p_width, p_height); break; + case 6: _scale_bilinear<3, uint16_t>(src_ptr, w_ptr, src_width, src_height, p_width, p_height); break; + case 8: _scale_bilinear<4, uint16_t>(src_ptr, w_ptr, src_width, src_height, p_width, p_height); break; + } } } @@ -829,13 +912,28 @@ void Image::resize(int p_width, int p_height, Interpolation p_interpolation) { } break; case INTERPOLATE_CUBIC: { - switch (get_format_pixel_size(format)) { - case 1: _scale_cubic<1>(r_ptr, w_ptr, width, height, p_width, p_height); break; - case 2: _scale_cubic<2>(r_ptr, w_ptr, width, height, p_width, p_height); break; - case 3: _scale_cubic<3>(r_ptr, w_ptr, width, height, p_width, p_height); break; - case 4: _scale_cubic<4>(r_ptr, w_ptr, width, height, p_width, p_height); break; + if (format >= FORMAT_L8 && format <= FORMAT_RGBA8) { + switch (get_format_pixel_size(format)) { + case 1: _scale_cubic<1, uint8_t>(r_ptr, w_ptr, width, height, p_width, p_height); break; + case 2: _scale_cubic<2, uint8_t>(r_ptr, w_ptr, width, height, p_width, p_height); break; + case 3: _scale_cubic<3, uint8_t>(r_ptr, w_ptr, width, height, p_width, p_height); break; + case 4: _scale_cubic<4, uint8_t>(r_ptr, w_ptr, width, height, p_width, p_height); break; + } + } else if (format >= FORMAT_RF && format <= FORMAT_RGBAF) { + switch (get_format_pixel_size(format)) { + case 4: _scale_cubic<1, float>(r_ptr, w_ptr, width, height, p_width, p_height); break; + case 8: _scale_cubic<2, float>(r_ptr, w_ptr, width, height, p_width, p_height); break; + case 12: _scale_cubic<3, float>(r_ptr, w_ptr, width, height, p_width, p_height); break; + case 16: _scale_cubic<4, float>(r_ptr, w_ptr, width, height, p_width, p_height); break; + } + } else if (format >= FORMAT_RH && format <= FORMAT_RGBAH) { + switch (get_format_pixel_size(format)) { + case 2: _scale_cubic<1, uint16_t>(r_ptr, w_ptr, width, height, p_width, p_height); break; + case 4: _scale_cubic<2, uint16_t>(r_ptr, w_ptr, width, height, p_width, p_height); break; + case 6: _scale_cubic<3, uint16_t>(r_ptr, w_ptr, width, height, p_width, p_height); break; + case 8: _scale_cubic<4, uint16_t>(r_ptr, w_ptr, width, height, p_width, p_height); break; + } } - } break; } @@ -1029,8 +1127,10 @@ bool Image::_can_modify(Format p_format) const { return p_format <= FORMAT_RGBE9995; } -template <int CC, bool renormalize> -static void _generate_po2_mipmap(const uint8_t *p_src, uint8_t *p_dst, uint32_t p_width, uint32_t p_height) { +template <class Component, int CC, bool renormalize, + void (*average_func)(Component &, const Component &, const Component &, const Component &, const Component &), + void (*renormalize_func)(Component *)> +static void _generate_po2_mipmap(const Component *p_src, Component *p_dst, uint32_t p_width, uint32_t p_height) { //fast power of 2 mipmap generation uint32_t dst_w = p_width >> 1; @@ -1038,34 +1138,19 @@ static void _generate_po2_mipmap(const uint8_t *p_src, uint8_t *p_dst, uint32_t for (uint32_t i = 0; i < dst_h; i++) { - const uint8_t *rup_ptr = &p_src[i * 2 * p_width * CC]; - const uint8_t *rdown_ptr = rup_ptr + p_width * CC; - uint8_t *dst_ptr = &p_dst[i * dst_w * CC]; + const Component *rup_ptr = &p_src[i * 2 * p_width * CC]; + const Component *rdown_ptr = rup_ptr + p_width * CC; + Component *dst_ptr = &p_dst[i * dst_w * CC]; uint32_t count = dst_w; while (count--) { for (int j = 0; j < CC; j++) { - - uint16_t val = 0; - val += rup_ptr[j]; - val += rup_ptr[j + CC]; - val += rdown_ptr[j]; - val += rdown_ptr[j + CC]; - dst_ptr[j] = val >> 2; + average_func(dst_ptr[j], rup_ptr[j], rup_ptr[j + CC], rdown_ptr[j], rdown_ptr[j + CC]); } if (renormalize) { - Vector3 n(dst_ptr[0] / 255.0, dst_ptr[1] / 255.0, dst_ptr[2] / 255.0); - n *= 2.0; - n -= Vector3(1, 1, 1); - n.normalize(); - n += Vector3(1, 1, 1); - n *= 0.5; - n *= 255; - dst_ptr[0] = CLAMP(int(n.x), 0, 255); - dst_ptr[1] = CLAMP(int(n.y), 0, 255); - dst_ptr[2] = CLAMP(int(n.z), 0, 255); + renormalize_func(dst_ptr); } dst_ptr += CC; @@ -1150,11 +1235,23 @@ void Image::shrink_x2() { switch (format) { case FORMAT_L8: - case FORMAT_R8: _generate_po2_mipmap<1, false>(r.ptr(), w.ptr(), width, height); break; - case FORMAT_LA8: _generate_po2_mipmap<2, false>(r.ptr(), w.ptr(), width, height); break; - case FORMAT_RG8: _generate_po2_mipmap<2, false>(r.ptr(), w.ptr(), width, height); break; - case FORMAT_RGB8: _generate_po2_mipmap<3, false>(r.ptr(), w.ptr(), width, height); break; - case FORMAT_RGBA8: _generate_po2_mipmap<4, false>(r.ptr(), w.ptr(), width, height); break; + case FORMAT_R8: _generate_po2_mipmap<uint8_t, 1, false, Image::average_4_uint8, Image::renormalize_uint8>(r.ptr(), w.ptr(), width, height); break; + case FORMAT_LA8: _generate_po2_mipmap<uint8_t, 2, false, Image::average_4_uint8, Image::renormalize_uint8>(r.ptr(), w.ptr(), width, height); break; + case FORMAT_RG8: _generate_po2_mipmap<uint8_t, 2, false, Image::average_4_uint8, Image::renormalize_uint8>(r.ptr(), w.ptr(), width, height); break; + case FORMAT_RGB8: _generate_po2_mipmap<uint8_t, 3, false, Image::average_4_uint8, Image::renormalize_uint8>(r.ptr(), w.ptr(), width, height); break; + case FORMAT_RGBA8: _generate_po2_mipmap<uint8_t, 4, false, Image::average_4_uint8, Image::renormalize_uint8>(r.ptr(), w.ptr(), width, height); break; + + case FORMAT_RF: _generate_po2_mipmap<float, 1, false, Image::average_4_float, Image::renormalize_float>(reinterpret_cast<const float *>(r.ptr()), reinterpret_cast<float *>(w.ptr()), width, height); break; + case FORMAT_RGF: _generate_po2_mipmap<float, 2, false, Image::average_4_float, Image::renormalize_float>(reinterpret_cast<const float *>(r.ptr()), reinterpret_cast<float *>(w.ptr()), width, height); break; + case FORMAT_RGBF: _generate_po2_mipmap<float, 3, false, Image::average_4_float, Image::renormalize_float>(reinterpret_cast<const float *>(r.ptr()), reinterpret_cast<float *>(w.ptr()), width, height); break; + case FORMAT_RGBAF: _generate_po2_mipmap<float, 4, false, Image::average_4_float, Image::renormalize_float>(reinterpret_cast<const float *>(r.ptr()), reinterpret_cast<float *>(w.ptr()), width, height); break; + + case FORMAT_RH: _generate_po2_mipmap<uint16_t, 1, false, Image::average_4_half, Image::renormalize_half>(reinterpret_cast<const uint16_t *>(r.ptr()), reinterpret_cast<uint16_t *>(w.ptr()), width, height); break; + case FORMAT_RGH: _generate_po2_mipmap<uint16_t, 2, false, Image::average_4_half, Image::renormalize_half>(reinterpret_cast<const uint16_t *>(r.ptr()), reinterpret_cast<uint16_t *>(w.ptr()), width, height); break; + case FORMAT_RGBH: _generate_po2_mipmap<uint16_t, 3, false, Image::average_4_half, Image::renormalize_half>(reinterpret_cast<const uint16_t *>(r.ptr()), reinterpret_cast<uint16_t *>(w.ptr()), width, height); break; + case FORMAT_RGBAH: _generate_po2_mipmap<uint16_t, 4, false, Image::average_4_half, Image::renormalize_half>(reinterpret_cast<const uint16_t *>(r.ptr()), reinterpret_cast<uint16_t *>(w.ptr()), width, height); break; + + case FORMAT_RGBE9995: _generate_po2_mipmap<uint32_t, 1, false, Image::average_4_rgbe9995, Image::renormalize_rgbe9995>(reinterpret_cast<const uint32_t *>(r.ptr()), reinterpret_cast<uint32_t *>(w.ptr()), width, height); break; default: {} } } @@ -1224,21 +1321,68 @@ Error Image::generate_mipmaps(bool p_renormalize) { switch (format) { case FORMAT_L8: - case FORMAT_R8: _generate_po2_mipmap<1, false>(&wp[prev_ofs], &wp[ofs], prev_w, prev_h); break; + case FORMAT_R8: _generate_po2_mipmap<uint8_t, 1, false, Image::average_4_uint8, Image::renormalize_uint8>(&wp[prev_ofs], &wp[ofs], prev_w, prev_h); break; case FORMAT_LA8: - case FORMAT_RG8: _generate_po2_mipmap<2, false>(&wp[prev_ofs], &wp[ofs], prev_w, prev_h); break; + case FORMAT_RG8: _generate_po2_mipmap<uint8_t, 2, false, Image::average_4_uint8, Image::renormalize_uint8>(&wp[prev_ofs], &wp[ofs], prev_w, prev_h); break; case FORMAT_RGB8: if (p_renormalize) - _generate_po2_mipmap<3, true>(&wp[prev_ofs], &wp[ofs], prev_w, prev_h); + _generate_po2_mipmap<uint8_t, 3, true, Image::average_4_uint8, Image::renormalize_uint8>(&wp[prev_ofs], &wp[ofs], prev_w, prev_h); else - _generate_po2_mipmap<3, false>(&wp[prev_ofs], &wp[ofs], prev_w, prev_h); + _generate_po2_mipmap<uint8_t, 3, false, Image::average_4_uint8, Image::renormalize_uint8>(&wp[prev_ofs], &wp[ofs], prev_w, prev_h); break; case FORMAT_RGBA8: if (p_renormalize) - _generate_po2_mipmap<4, true>(&wp[prev_ofs], &wp[ofs], prev_w, prev_h); + _generate_po2_mipmap<uint8_t, 4, true, Image::average_4_uint8, Image::renormalize_uint8>(&wp[prev_ofs], &wp[ofs], prev_w, prev_h); + else + _generate_po2_mipmap<uint8_t, 4, false, Image::average_4_uint8, Image::renormalize_uint8>(&wp[prev_ofs], &wp[ofs], prev_w, prev_h); + break; + case FORMAT_RF: + _generate_po2_mipmap<float, 1, false, Image::average_4_float, Image::renormalize_float>(reinterpret_cast<const float *>(&wp[prev_ofs]), reinterpret_cast<float *>(&wp[ofs]), prev_w, prev_h); + break; + case FORMAT_RGF: + _generate_po2_mipmap<float, 2, false, Image::average_4_float, Image::renormalize_float>(reinterpret_cast<const float *>(&wp[prev_ofs]), reinterpret_cast<float *>(&wp[ofs]), prev_w, prev_h); + break; + case FORMAT_RGBF: + if (p_renormalize) + _generate_po2_mipmap<float, 3, true, Image::average_4_float, Image::renormalize_float>(reinterpret_cast<const float *>(&wp[prev_ofs]), reinterpret_cast<float *>(&wp[ofs]), prev_w, prev_h); + else + _generate_po2_mipmap<float, 3, false, Image::average_4_float, Image::renormalize_float>(reinterpret_cast<const float *>(&wp[prev_ofs]), reinterpret_cast<float *>(&wp[ofs]), prev_w, prev_h); + + break; + case FORMAT_RGBAF: + if (p_renormalize) + _generate_po2_mipmap<float, 4, true, Image::average_4_float, Image::renormalize_float>(reinterpret_cast<const float *>(&wp[prev_ofs]), reinterpret_cast<float *>(&wp[ofs]), prev_w, prev_h); + else + _generate_po2_mipmap<float, 4, false, Image::average_4_float, Image::renormalize_float>(reinterpret_cast<const float *>(&wp[prev_ofs]), reinterpret_cast<float *>(&wp[ofs]), prev_w, prev_h); + + break; + case FORMAT_RH: + _generate_po2_mipmap<uint16_t, 1, false, Image::average_4_half, Image::renormalize_half>(reinterpret_cast<const uint16_t *>(&wp[prev_ofs]), reinterpret_cast<uint16_t *>(&wp[ofs]), prev_w, prev_h); + break; + case FORMAT_RGH: + _generate_po2_mipmap<uint16_t, 2, false, Image::average_4_half, Image::renormalize_half>(reinterpret_cast<const uint16_t *>(&wp[prev_ofs]), reinterpret_cast<uint16_t *>(&wp[ofs]), prev_w, prev_h); + break; + case FORMAT_RGBH: + if (p_renormalize) + _generate_po2_mipmap<uint16_t, 3, true, Image::average_4_half, Image::renormalize_half>(reinterpret_cast<const uint16_t *>(&wp[prev_ofs]), reinterpret_cast<uint16_t *>(&wp[ofs]), prev_w, prev_h); else - _generate_po2_mipmap<4, false>(&wp[prev_ofs], &wp[ofs], prev_w, prev_h); + _generate_po2_mipmap<uint16_t, 3, false, Image::average_4_half, Image::renormalize_half>(reinterpret_cast<const uint16_t *>(&wp[prev_ofs]), reinterpret_cast<uint16_t *>(&wp[ofs]), prev_w, prev_h); + + break; + case FORMAT_RGBAH: + if (p_renormalize) + _generate_po2_mipmap<uint16_t, 4, true, Image::average_4_half, Image::renormalize_half>(reinterpret_cast<const uint16_t *>(&wp[prev_ofs]), reinterpret_cast<uint16_t *>(&wp[ofs]), prev_w, prev_h); + else + _generate_po2_mipmap<uint16_t, 4, false, Image::average_4_half, Image::renormalize_half>(reinterpret_cast<const uint16_t *>(&wp[prev_ofs]), reinterpret_cast<uint16_t *>(&wp[ofs]), prev_w, prev_h); + + break; + case FORMAT_RGBE9995: + if (p_renormalize) + _generate_po2_mipmap<uint32_t, 1, true, Image::average_4_rgbe9995, Image::renormalize_rgbe9995>(reinterpret_cast<const uint32_t *>(&wp[prev_ofs]), reinterpret_cast<uint32_t *>(&wp[ofs]), prev_w, prev_h); + else + _generate_po2_mipmap<uint32_t, 1, false, Image::average_4_rgbe9995, Image::renormalize_rgbe9995>(reinterpret_cast<const uint32_t *>(&wp[prev_ofs]), reinterpret_cast<uint32_t *>(&wp[ofs]), prev_w, prev_h); + break; default: {} } @@ -1617,8 +1761,10 @@ bool Image::is_compressed() const { Error Image::decompress() { - if (format >= FORMAT_DXT1 && format <= FORMAT_BPTC_RGBFU && _image_decompress_bc) + if (format >= FORMAT_DXT1 && format <= FORMAT_RGTC_RG && _image_decompress_bc) _image_decompress_bc(this); + else if (format >= FORMAT_BPTC_RGBA && format <= FORMAT_BPTC_RGBFU && _image_decompress_bptc) + _image_decompress_bptc(this); else if (format >= FORMAT_PVRTC2 && format <= FORMAT_PVRTC4A && _image_decompress_pvrtc) _image_decompress_pvrtc(this); else if (format == FORMAT_ETC && _image_decompress_etc1) @@ -1637,7 +1783,7 @@ Error Image::compress(CompressMode p_mode, CompressSource p_source, float p_loss case COMPRESS_S3TC: { ERR_FAIL_COND_V(!_image_compress_bc_func, ERR_UNAVAILABLE); - _image_compress_bc_func(this, p_source); + _image_compress_bc_func(this, p_lossy_quality, p_source); } break; case COMPRESS_PVRTC2: { @@ -1659,6 +1805,11 @@ Error Image::compress(CompressMode p_mode, CompressSource p_source, float p_loss ERR_FAIL_COND_V(!_image_compress_etc2_func, ERR_UNAVAILABLE); _image_compress_etc2_func(this, p_lossy_quality, p_source); } break; + case COMPRESS_BPTC: { + + ERR_FAIL_COND_V(!_image_compress_bptc_func, ERR_UNAVAILABLE); + _image_compress_bptc_func(this, p_lossy_quality, p_source); + } break; } return OK; @@ -1995,13 +2146,15 @@ ImageMemLoadFunc Image::_png_mem_loader_func = NULL; ImageMemLoadFunc Image::_jpg_mem_loader_func = NULL; ImageMemLoadFunc Image::_webp_mem_loader_func = NULL; -void (*Image::_image_compress_bc_func)(Image *, Image::CompressSource) = NULL; +void (*Image::_image_compress_bc_func)(Image *, float, Image::CompressSource) = NULL; +void (*Image::_image_compress_bptc_func)(Image *, float, Image::CompressSource) = NULL; void (*Image::_image_compress_pvrtc2_func)(Image *) = NULL; void (*Image::_image_compress_pvrtc4_func)(Image *) = NULL; void (*Image::_image_compress_etc1_func)(Image *, float) = NULL; void (*Image::_image_compress_etc2_func)(Image *, float, Image::CompressSource) = NULL; void (*Image::_image_decompress_pvrtc)(Image *) = NULL; void (*Image::_image_decompress_bc)(Image *) = NULL; +void (*Image::_image_decompress_bptc)(Image *) = NULL; void (*Image::_image_decompress_etc1)(Image *) = NULL; void (*Image::_image_decompress_etc2)(Image *) = NULL; @@ -2185,18 +2338,7 @@ Color Image::get_pixel(int p_x, int p_y) const { return Color(Math::half_to_float(r), Math::half_to_float(g), Math::half_to_float(b), Math::half_to_float(a)); } break; case FORMAT_RGBE9995: { - uint32_t rgbe = ((uint32_t *)ptr)[ofs]; - float r = rgbe & 0x1ff; - float g = (rgbe >> 9) & 0x1ff; - float b = (rgbe >> 18) & 0x1ff; - float e = (rgbe >> 27); - float m = Math::pow(2, e - 15.0 - 9.0); - ; - float rd = r * m; - float gd = g * m; - float bd = b * m; - - return Color(rd, gd, bd, 1.0); + return Color::from_rgbe9995(((uint32_t *)ptr)[ofs]); } break; default: { @@ -2230,10 +2372,10 @@ void Image::set_pixel(int p_x, int p_y, const Color &p_color) { switch (format) { case FORMAT_L8: { - ptr[ofs] = uint8_t(CLAMP(p_color.gray() * 255.0, 0, 255)); + ptr[ofs] = uint8_t(CLAMP(p_color.get_v() * 255.0, 0, 255)); } break; case FORMAT_LA8: { - ptr[ofs * 2 + 0] = uint8_t(CLAMP(p_color.gray() * 255.0, 0, 255)); + ptr[ofs * 2 + 0] = uint8_t(CLAMP(p_color.get_v() * 255.0, 0, 255)); ptr[ofs * 2 + 1] = uint8_t(CLAMP(p_color.a * 255.0, 0, 255)); } break; case FORMAT_R8: { @@ -2525,11 +2667,16 @@ void Image::_bind_methods() { BIND_ENUM_CONSTANT(COMPRESS_SOURCE_NORMAL); } -void Image::set_compress_bc_func(void (*p_compress_func)(Image *, CompressSource)) { +void Image::set_compress_bc_func(void (*p_compress_func)(Image *, float, CompressSource)) { _image_compress_bc_func = p_compress_func; } +void Image::set_compress_bptc_func(void (*p_compress_func)(Image *, float, CompressSource)) { + + _image_compress_bptc_func = p_compress_func; +} + void Image::normalmap_to_xy() { convert(Image::FORMAT_RGBA8); @@ -2783,6 +2930,55 @@ Error Image::_load_from_buffer(const PoolVector<uint8_t> &p_array, ImageMemLoadF return OK; } +void Image::average_4_uint8(uint8_t &p_out, const uint8_t &p_a, const uint8_t &p_b, const uint8_t &p_c, const uint8_t &p_d) { + p_out = static_cast<uint8_t>((p_a + p_b + p_c + p_d + 2) >> 2); +} + +void Image::average_4_float(float &p_out, const float &p_a, const float &p_b, const float &p_c, const float &p_d) { + p_out = (p_a + p_b + p_c + p_d) * 0.25f; +} + +void Image::average_4_half(uint16_t &p_out, const uint16_t &p_a, const uint16_t &p_b, const uint16_t &p_c, const uint16_t &p_d) { + p_out = Math::make_half_float((Math::half_to_float(p_a) + Math::half_to_float(p_b) + Math::half_to_float(p_c) + Math::half_to_float(p_d)) * 0.25f); +} + +void Image::average_4_rgbe9995(uint32_t &p_out, const uint32_t &p_a, const uint32_t &p_b, const uint32_t &p_c, const uint32_t &p_d) { + p_out = ((Color::from_rgbe9995(p_a) + Color::from_rgbe9995(p_b) + Color::from_rgbe9995(p_c) + Color::from_rgbe9995(p_d)) * 0.25f).to_rgbe9995(); +} + +void Image::renormalize_uint8(uint8_t *p_rgb) { + Vector3 n(p_rgb[0] / 255.0, p_rgb[1] / 255.0, p_rgb[2] / 255.0); + n *= 2.0; + n -= Vector3(1, 1, 1); + n.normalize(); + n += Vector3(1, 1, 1); + n *= 0.5; + n *= 255; + p_rgb[0] = CLAMP(int(n.x), 0, 255); + p_rgb[1] = CLAMP(int(n.y), 0, 255); + p_rgb[2] = CLAMP(int(n.z), 0, 255); +} + +void Image::renormalize_float(float *p_rgb) { + Vector3 n(p_rgb[0], p_rgb[1], p_rgb[2]); + n.normalize(); + p_rgb[0] = n.x; + p_rgb[1] = n.y; + p_rgb[2] = n.z; +} + +void Image::renormalize_half(uint16_t *p_rgb) { + Vector3 n(Math::half_to_float(p_rgb[0]), Math::half_to_float(p_rgb[1]), Math::half_to_float(p_rgb[2])); + n.normalize(); + p_rgb[0] = Math::make_half_float(n.x); + p_rgb[1] = Math::make_half_float(n.y); + p_rgb[2] = Math::make_half_float(n.z); +} + +void Image::renormalize_rgbe9995(uint32_t *p_rgb) { + // Never used +} + Image::Image(const uint8_t *p_mem_png_jpg, int p_len) { width = 0; diff --git a/core/image.h b/core/image.h index c450e88290..6af55ca8d9 100644 --- a/core/image.h +++ b/core/image.h @@ -126,7 +126,8 @@ public: static ImageMemLoadFunc _jpg_mem_loader_func; static ImageMemLoadFunc _webp_mem_loader_func; - static void (*_image_compress_bc_func)(Image *, CompressSource p_source); + static void (*_image_compress_bc_func)(Image *, float, CompressSource p_source); + static void (*_image_compress_bptc_func)(Image *, float p_lossy_quality, CompressSource p_source); static void (*_image_compress_pvrtc2_func)(Image *); static void (*_image_compress_pvrtc4_func)(Image *); static void (*_image_compress_etc1_func)(Image *, float); @@ -134,6 +135,7 @@ public: static void (*_image_decompress_pvrtc)(Image *); static void (*_image_decompress_bc)(Image *); + static void (*_image_decompress_bptc)(Image *); static void (*_image_decompress_etc1)(Image *); static void (*_image_decompress_etc2)(Image *); @@ -182,6 +184,15 @@ private: Error _load_from_buffer(const PoolVector<uint8_t> &p_array, ImageMemLoadFunc p_loader); + static void average_4_uint8(uint8_t &p_out, const uint8_t &p_a, const uint8_t &p_b, const uint8_t &p_c, const uint8_t &p_d); + static void average_4_float(float &p_out, const float &p_a, const float &p_b, const float &p_c, const float &p_d); + static void average_4_half(uint16_t &p_out, const uint16_t &p_a, const uint16_t &p_b, const uint16_t &p_c, const uint16_t &p_d); + static void average_4_rgbe9995(uint32_t &p_out, const uint32_t &p_a, const uint32_t &p_b, const uint32_t &p_c, const uint32_t &p_d); + static void renormalize_uint8(uint8_t *p_rgb); + static void renormalize_float(float *p_rgb); + static void renormalize_half(uint16_t *p_rgb); + static void renormalize_rgbe9995(uint32_t *p_rgb); + public: int get_width() const; ///< Get image width int get_height() const; ///< Get image height @@ -282,6 +293,7 @@ public: COMPRESS_PVRTC4, COMPRESS_ETC, COMPRESS_ETC2, + COMPRESS_BPTC }; Error compress(CompressMode p_mode = COMPRESS_S3TC, CompressSource p_source = COMPRESS_SOURCE_GENERIC, float p_lossy_quality = 0.7); @@ -304,7 +316,8 @@ public: Rect2 get_used_rect() const; Ref<Image> get_rect(const Rect2 &p_area) const; - static void set_compress_bc_func(void (*p_compress_func)(Image *, CompressSource)); + static void set_compress_bc_func(void (*p_compress_func)(Image *, float, CompressSource)); + static void set_compress_bptc_func(void (*p_compress_func)(Image *, float, CompressSource)); static String get_format_name(Format p_format); Error load_png_from_buffer(const PoolVector<uint8_t> &p_array); diff --git a/core/input_map.cpp b/core/input_map.cpp index d33f40cbcf..ffc8a39da5 100644 --- a/core/input_map.cpp +++ b/core/input_map.cpp @@ -44,7 +44,7 @@ void InputMap::_bind_methods() { ClassDB::bind_method(D_METHOD("add_action", "action", "deadzone"), &InputMap::add_action, DEFVAL(0.5f)); ClassDB::bind_method(D_METHOD("erase_action", "action"), &InputMap::erase_action); - ClassDB::bind_method(D_METHOD("action_set_deadzone", "deadzone"), &InputMap::action_set_deadzone); + ClassDB::bind_method(D_METHOD("action_set_deadzone", "action", "deadzone"), &InputMap::action_set_deadzone); ClassDB::bind_method(D_METHOD("action_add_event", "action", "event"), &InputMap::action_add_event); ClassDB::bind_method(D_METHOD("action_has_event", "action", "event"), &InputMap::action_has_event); ClassDB::bind_method(D_METHOD("action_erase_event", "action", "event"), &InputMap::action_erase_event); diff --git a/core/io/file_access_encrypted.cpp b/core/io/file_access_encrypted.cpp index bb7a444ccc..812e881114 100644 --- a/core/io/file_access_encrypted.cpp +++ b/core/io/file_access_encrypted.cpp @@ -43,7 +43,6 @@ Error FileAccessEncrypted::open_and_parse(FileAccess *p_base, const Vector<uint8_t> &p_key, Mode p_mode) { - //print_line("open and parse!"); ERR_FAIL_COND_V(file != NULL, ERR_ALREADY_IN_USE); ERR_FAIL_COND_V(p_key.size() != 32, ERR_INVALID_PARAMETER); diff --git a/core/io/file_access_network.cpp b/core/io/file_access_network.cpp index e0a2dbf507..d72d3ca9f1 100644 --- a/core/io/file_access_network.cpp +++ b/core/io/file_access_network.cpp @@ -93,8 +93,6 @@ void FileAccessNetworkClient::_thread_func() { DEBUG_TIME("sem_unlock"); //DEBUG_PRINT("semwait returned "+itos(werr)); DEBUG_PRINT("MUTEX LOCK " + itos(lockcount)); - DEBUG_PRINT("POPO"); - DEBUG_PRINT("PEPE"); lock_mutex(); DEBUG_PRINT("MUTEX PASS"); diff --git a/core/io/file_access_pack.h b/core/io/file_access_pack.h index 8a40e6d78c..f29e431d9a 100644 --- a/core/io/file_access_pack.h +++ b/core/io/file_access_pack.h @@ -175,7 +175,6 @@ public: FileAccess *PackedData::try_open_path(const String &p_path) { - //print_line("try open path " + p_path); PathMD5 pmd5(p_path.md5_buffer()); Map<PathMD5, PackedFile>::Element *E = files.find(pmd5); if (!E) diff --git a/core/io/resource_import.cpp b/core/io/resource_import.cpp index cfe6655504..83e8a40da9 100644 --- a/core/io/resource_import.cpp +++ b/core/io/resource_import.cpp @@ -78,7 +78,7 @@ Error ResourceFormatImporter::_get_path_and_type(const String &p_path, PathAndTy if (assign != String()) { if (!path_found && assign.begins_with("path.") && r_path_and_type.path == String()) { String feature = assign.get_slicec('.', 1); - if (OS::get_singleton()->has_feature(feature)) { + if (feature == "fallback" || OS::get_singleton()->has_feature(feature)) { r_path_and_type.path = value; path_found = true; //first match must have priority } diff --git a/core/io/resource_loader.cpp b/core/io/resource_loader.cpp index 8b0655deb0..c01aff9144 100644 --- a/core/io/resource_loader.cpp +++ b/core/io/resource_loader.cpp @@ -204,8 +204,7 @@ RES ResourceLoader::load(const String &p_path, const String &p_type_hint, bool p if (!p_no_cache && ResourceCache::has(local_path)) { - if (OS::get_singleton()->is_stdout_verbose()) - print_line("load resource: " + local_path + " (cached)"); + print_verbose("Loading resource: " + local_path + " (cached)"); if (r_error) *r_error = OK; return RES(ResourceCache::get(local_path)); @@ -216,9 +215,7 @@ RES ResourceLoader::load(const String &p_path, const String &p_type_hint, bool p ERR_FAIL_COND_V(path == "", RES()); - if (OS::get_singleton()->is_stdout_verbose()) - print_line("load resource: " + path); - + print_verbose("Loading resource: " + path); RES res = _load(path, local_path, p_type_hint, p_no_cache, r_error); if (res.is_null()) { @@ -286,9 +283,7 @@ Ref<ResourceInteractiveLoader> ResourceLoader::load_interactive(const String &p_ if (!p_no_cache && ResourceCache::has(local_path)) { - if (OS::get_singleton()->is_stdout_verbose()) - print_line("load resource: " + local_path + " (cached)"); - + print_verbose("Loading resource: " + local_path + " (cached)"); Ref<Resource> res_cached = ResourceCache::get(local_path); Ref<ResourceInteractiveLoaderDefault> ril = Ref<ResourceInteractiveLoaderDefault>(memnew(ResourceInteractiveLoaderDefault)); @@ -298,14 +293,10 @@ Ref<ResourceInteractiveLoader> ResourceLoader::load_interactive(const String &p_ bool xl_remapped = false; String path = _path_remap(local_path, &xl_remapped); - ERR_FAIL_COND_V(path == "", Ref<ResourceInteractiveLoader>()); - - if (OS::get_singleton()->is_stdout_verbose()) - print_line("load resource: "); + print_verbose("Loading resource: " + path); bool found = false; - for (int i = 0; i < loader_count; i++) { if (!loader[i]->recognize_path(path, p_type_hint)) diff --git a/core/io/stream_peer_ssl.cpp b/core/io/stream_peer_ssl.cpp index e7e9662d24..25adb6a6ee 100644 --- a/core/io/stream_peer_ssl.cpp +++ b/core/io/stream_peer_ssl.cpp @@ -81,7 +81,7 @@ PoolByteArray StreamPeerSSL::get_project_cert_array() { memdelete(f); #ifdef DEBUG_ENABLED - print_line("Loaded certs from '" + certs_path); + print_verbose(vformat("Loaded certs from '%s'.", certs_path)); #endif } } diff --git a/core/math/expression.cpp b/core/math/expression.cpp index a161dbddba..ba40cb4586 100644 --- a/core/math/expression.cpp +++ b/core/math/expression.cpp @@ -177,7 +177,7 @@ int Expression::get_func_argument_count(BuiltinFunc p_func) { } void Expression::exec_func(BuiltinFunc p_func, const Variant **p_inputs, Variant *r_return, Variant::CallError &r_error, String &r_error_str) { - + r_error.error = Variant::CallError::CALL_OK; switch (p_func) { case MATH_SIN: { @@ -622,15 +622,12 @@ void Expression::exec_func(BuiltinFunc p_func, const Variant **p_inputs, Variant case TEXT_PRINTERR: { String str = *p_inputs[0]; - - //str+="\n"; print_error(str); } break; case TEXT_PRINTRAW: { - String str = *p_inputs[0]; - //str+="\n"; + String str = *p_inputs[0]; OS::get_singleton()->print("%s", str.utf8().get_data()); } break; @@ -1916,7 +1913,7 @@ bool Expression::_execute(const Array &p_inputs, Object *p_instance, Expression: bool valid; r_ret = base.get_named(index->name, &valid); if (!valid) { - r_error_str = vformat(RTR("Invalid named index '%s' for base type "), String(index->name), Variant::get_type_name(base.get_type())); + r_error_str = vformat(RTR("Invalid named index '%s' for base type %s"), String(index->name), Variant::get_type_name(base.get_type())); return true; } diff --git a/core/math/geometry.cpp b/core/math/geometry.cpp index 7ab28daf20..d8cb657b5e 100644 --- a/core/math/geometry.cpp +++ b/core/math/geometry.cpp @@ -626,7 +626,6 @@ PoolVector<Face3> Geometry::wrap_geometry(PoolVector<Face3> p_array, real_t *p_e voxelsize.z /= div_z; // create and initialize cells to zero - //print_line("Wrapper: Initializing Cells"); uint8_t ***cell_status = memnew_arr(uint8_t **, div_x); for (int i = 0; i < div_x; i++) { @@ -645,7 +644,6 @@ PoolVector<Face3> Geometry::wrap_geometry(PoolVector<Face3> p_array, real_t *p_e } // plot faces into cells - //print_line("Wrapper (1/6): Plotting Faces"); for (int i = 0; i < face_count; i++) { @@ -659,8 +657,6 @@ PoolVector<Face3> Geometry::wrap_geometry(PoolVector<Face3> p_array, real_t *p_e // determine which cells connect to the outside by traversing the outside and recursively flood-fill marking - //print_line("Wrapper (2/6): Flood Filling"); - for (int i = 0; i < div_x; i++) { for (int j = 0; j < div_y; j++) { @@ -690,8 +686,6 @@ PoolVector<Face3> Geometry::wrap_geometry(PoolVector<Face3> p_array, real_t *p_e // build faces for the inside-outside cell divisors - //print_line("Wrapper (3/6): Building Faces"); - PoolVector<Face3> wrapped_faces; for (int i = 0; i < div_x; i++) { @@ -705,8 +699,6 @@ PoolVector<Face3> Geometry::wrap_geometry(PoolVector<Face3> p_array, real_t *p_e } } - //print_line("Wrapper (4/6): Transforming Back Vertices"); - // transform face vertices to global coords int wrapped_faces_count = wrapped_faces.size(); @@ -724,7 +716,6 @@ PoolVector<Face3> Geometry::wrap_geometry(PoolVector<Face3> p_array, real_t *p_e } // clean up grid - //print_line("Wrapper (5/6): Grid Cleanup"); for (int i = 0; i < div_x; i++) { @@ -740,7 +731,6 @@ PoolVector<Face3> Geometry::wrap_geometry(PoolVector<Face3> p_array, real_t *p_e if (p_error) *p_error = voxelsize.length(); - //print_line("Wrapper (6/6): Finished."); return wrapped_faces; } diff --git a/core/math/quick_hull.cpp b/core/math/quick_hull.cpp index 45c106102e..9d4f4f66b7 100644 --- a/core/math/quick_hull.cpp +++ b/core/math/quick_hull.cpp @@ -62,7 +62,6 @@ Error QuickHull::build(const Vector<Vector3> &p_points, Geometry::MeshData &r_me Vector3 sp = p_points[i].snapped(Vector3(0.0001, 0.0001, 0.0001)); if (valid_cache.has(sp)) { valid_points.write[i] = false; - //print_line("INVALIDATED: "+itos(i)); } else { valid_points.write[i] = true; valid_cache.insert(sp); @@ -455,7 +454,6 @@ Error QuickHull::build(const Vector<Vector3> &p_points, Geometry::MeshData &r_me //fill mesh r_mesh.faces.clear(); r_mesh.faces.resize(ret_faces.size()); - //print_line("FACECOUNT: "+itos(r_mesh.faces.size())); int idx = 0; for (List<Geometry::MeshData::Face>::Element *E = ret_faces.front(); E; E = E->next()) { @@ -473,12 +471,5 @@ Error QuickHull::build(const Vector<Vector3> &p_points, Geometry::MeshData &r_me r_mesh.vertices = p_points; - //r_mesh.optimize_vertices(); - /* - print_line("FACES: "+itos(r_mesh.faces.size())); - print_line("EDGES: "+itos(r_mesh.edges.size())); - print_line("VERTICES: "+itos(r_mesh.vertices.size())); -*/ - return OK; } diff --git a/core/math/vector2.cpp b/core/math/vector2.cpp index 75d9b8b311..84c9f0fca6 100644 --- a/core/math/vector2.cpp +++ b/core/math/vector2.cpp @@ -122,7 +122,7 @@ Vector2 Vector2::rotated(real_t p_by) const { } Vector2 Vector2::project(const Vector2 &p_b) const { - return p_b * (dot(p_b) / p_b.dot(p_b)); + return p_b * (dot(p_b) / p_b.length_squared()); } Vector2 Vector2::snapped(const Vector2 &p_by) const { diff --git a/core/math/vector3.h b/core/math/vector3.h index a719e3965d..5f0e8919ff 100644 --- a/core/math/vector3.h +++ b/core/math/vector3.h @@ -241,7 +241,7 @@ real_t Vector3::distance_squared_to(const Vector3 &p_b) const { } Vector3 Vector3::project(const Vector3 &p_b) const { - return p_b * (dot(p_b) / p_b.dot(p_b)); + return p_b * (dot(p_b) / p_b.length_squared()); } real_t Vector3::angle_to(const Vector3 &p_b) const { diff --git a/core/message_queue.cpp b/core/message_queue.cpp index 3adaad868a..97ee236a46 100644 --- a/core/message_queue.cpp +++ b/core/message_queue.cpp @@ -50,9 +50,9 @@ Error MessageQueue::push_call(ObjectID p_id, const StringName &p_method, const V String type; if (ObjectDB::get_instance(p_id)) type = ObjectDB::get_instance(p_id)->get_class(); - print_line("failed method: " + type + ":" + p_method + " target ID: " + itos(p_id)); + print_line("Failed method: " + type + ":" + p_method + " target ID: " + itos(p_id)); statistics(); - ERR_EXPLAIN("Message queue out of memory. Try increasing 'message_queue_size_kb' in project settings"); + ERR_EXPLAIN("Message queue out of memory. Try increasing 'message_queue_size_kb' in project settings."); ERR_FAIL_V(ERR_OUT_OF_MEMORY); } @@ -101,9 +101,9 @@ Error MessageQueue::push_set(ObjectID p_id, const StringName &p_prop, const Vari String type; if (ObjectDB::get_instance(p_id)) type = ObjectDB::get_instance(p_id)->get_class(); - print_line("failed set: " + type + ":" + p_prop + " target ID: " + itos(p_id)); + print_line("Failed set: " + type + ":" + p_prop + " target ID: " + itos(p_id)); statistics(); - ERR_EXPLAIN("Message queue out of memory. Try increasing 'message_queue_size_kb' in project settings"); + ERR_EXPLAIN("Message queue out of memory. Try increasing 'message_queue_size_kb' in project settings."); ERR_FAIL_V(ERR_OUT_OF_MEMORY); } @@ -134,9 +134,9 @@ Error MessageQueue::push_notification(ObjectID p_id, int p_notification) { String type; if (ObjectDB::get_instance(p_id)) type = ObjectDB::get_instance(p_id)->get_class(); - print_line("failed notification: " + itos(p_notification) + " target ID: " + itos(p_id)); + print_line("Failed notification: " + itos(p_notification) + " target ID: " + itos(p_id)); statistics(); - ERR_EXPLAIN("Message queue out of memory. Try increasing 'message_queue_size_kb' in project settings"); + ERR_EXPLAIN("Message queue out of memory. Try increasing 'message_queue_size_kb' in project settings."); ERR_FAIL_V(ERR_OUT_OF_MEMORY); } @@ -210,8 +210,7 @@ void MessageQueue::statistics() { } //object was deleted - //WARN_PRINT("Object was deleted while awaiting a callback") - //should it print a warning? + print_line("Object was deleted while awaiting a callback"); } else { null_count++; @@ -226,17 +225,14 @@ void MessageQueue::statistics() { print_line("NULL count: " + itos(null_count)); for (Map<StringName, int>::Element *E = set_count.front(); E; E = E->next()) { - print_line("SET " + E->key() + ": " + itos(E->get())); } for (Map<StringName, int>::Element *E = call_count.front(); E; E = E->next()) { - print_line("CALL " + E->key() + ": " + itos(E->get())); } for (Map<int, int>::Element *E = notify_count.front(); E; E = E->next()) { - print_line("NOTIFY " + itos(E->key()) + ": " + itos(E->get())); } } @@ -268,7 +264,6 @@ void MessageQueue::flush() { if (buffer_end > buffer_max_used) { buffer_max_used = buffer_end; - //statistics(); } uint32_t read_pos = 0; diff --git a/core/oa_hash_map.h b/core/oa_hash_map.h index 0b3b40f30c..3a17fc21f3 100644 --- a/core/oa_hash_map.h +++ b/core/oa_hash_map.h @@ -320,7 +320,7 @@ public: memdelete_arr(keys); memdelete_arr(values); - memdelete(hashes); + memdelete_arr(hashes); } }; diff --git a/core/object.cpp b/core/object.cpp index ba8b710a84..e83abaece7 100644 --- a/core/object.cpp +++ b/core/object.cpp @@ -1476,8 +1476,13 @@ Error Object::connect(const StringName &p_signal, Object *p_to_object, const Str Signal::Target target(p_to_object->get_instance_id(), p_to_method); if (s->slot_map.has(target)) { - ERR_EXPLAIN("Signal '" + p_signal + "' is already connected to given method '" + p_to_method + "' in that object."); - ERR_FAIL_COND_V(s->slot_map.has(target), ERR_INVALID_PARAMETER); + if (p_flags & CONNECT_REFERENCE_COUNTED) { + s->slot_map[target].reference_count++; + return OK; + } else { + ERR_EXPLAIN("Signal '" + p_signal + "' is already connected to given method '" + p_to_method + "' in that object."); + ERR_FAIL_COND_V(s->slot_map.has(target), ERR_INVALID_PARAMETER); + } } Signal::Slot slot; @@ -1491,6 +1496,10 @@ Error Object::connect(const StringName &p_signal, Object *p_to_object, const Str conn.binds = p_binds; slot.conn = conn; slot.cE = p_to_object->connections.push_back(conn); + if (p_flags & CONNECT_REFERENCE_COUNTED) { + slot.reference_count = 1; + } + s->slot_map[target] = slot; return OK; @@ -1521,6 +1530,10 @@ bool Object::is_connected(const StringName &p_signal, Object *p_to_object, const void Object::disconnect(const StringName &p_signal, Object *p_to_object, const StringName &p_to_method) { + _disconnect(p_signal, p_to_object, p_to_method); +} +void Object::_disconnect(const StringName &p_signal, Object *p_to_object, const StringName &p_to_method, bool p_force) { + ERR_FAIL_NULL(p_to_object); Signal *s = signal_map.getptr(p_signal); if (!s) { @@ -1539,7 +1552,16 @@ void Object::disconnect(const StringName &p_signal, Object *p_to_object, const S ERR_FAIL(); } - p_to_object->connections.erase(s->slot_map[target].cE); + Signal::Slot *slot = &s->slot_map[target]; + + if (!p_force) { + slot->reference_count--; // by default is zero, if it was not referenced it will go below it + if (slot->reference_count >= 0) { + return; + } + } + + p_to_object->connections.erase(slot->cE); s->slot_map.erase(target); if (s->slot_map.empty() && ClassDB::has_signal(get_class_name(), p_signal)) { @@ -1761,6 +1783,7 @@ void Object::_bind_methods() { BIND_ENUM_CONSTANT(CONNECT_DEFERRED); BIND_ENUM_CONSTANT(CONNECT_PERSIST); BIND_ENUM_CONSTANT(CONNECT_ONESHOT); + BIND_ENUM_CONSTANT(CONNECT_REFERENCE_COUNTED); } void Object::call_deferred(const StringName &p_method, VARIANT_ARG_DECLARE) { @@ -1948,13 +1971,13 @@ Object::~Object() { Connection &c = E->get(); ERR_CONTINUE(c.source != this); //bug? - this->disconnect(c.signal, c.target, c.method); + this->_disconnect(c.signal, c.target, c.method, true); } while (connections.size()) { Connection c = connections.front()->get(); - c.source->disconnect(c.signal, c.target, c.method); + c.source->_disconnect(c.signal, c.target, c.method, true); } ObjectDB::remove_instance(this); @@ -2057,10 +2080,10 @@ void ObjectDB::cleanup() { String node_name; if (instances[*K]->is_class("Node")) - node_name = " - Node Name: " + String(instances[*K]->call("get_name")); + node_name = " - Node name: " + String(instances[*K]->call("get_name")); if (instances[*K]->is_class("Resource")) - node_name = " - Resource Name: " + String(instances[*K]->call("get_name")) + " Path: " + String(instances[*K]->call("get_path")); - print_line("Leaked Instance: " + String(instances[*K]->get_class()) + ":" + itos(*K) + node_name); + node_name = " - Resource name: " + String(instances[*K]->call("get_name")) + " Path: " + String(instances[*K]->call("get_path")); + print_line("Leaked instance: " + String(instances[*K]->get_class()) + ":" + itos(*K) + node_name); } } } diff --git a/core/object.h b/core/object.h index 8dc3426d1d..d741371306 100644 --- a/core/object.h +++ b/core/object.h @@ -71,6 +71,7 @@ enum PropertyHint { PROPERTY_HINT_GLOBAL_DIR, ///< a directory path must be passed PROPERTY_HINT_RESOURCE_TYPE, ///< a resource object type PROPERTY_HINT_MULTILINE_TEXT, ///< used for string properties that can contain multiple lines + PROPERTY_HINT_PLACEHOLDER_TEXT, ///< used to set a placeholder text for string properties PROPERTY_HINT_COLOR_NO_ALPHA, ///< used for ignoring alpha component when editing a color PROPERTY_HINT_IMAGE_COMPRESS_LOSSY, PROPERTY_HINT_IMAGE_COMPRESS_LOSSLESS, @@ -391,7 +392,8 @@ public: CONNECT_DEFERRED = 1, CONNECT_PERSIST = 2, // hint for scene to save this connection - CONNECT_ONESHOT = 4 + CONNECT_ONESHOT = 4, + CONNECT_REFERENCE_COUNTED = 8, }; struct Connection { @@ -442,8 +444,10 @@ private: struct Slot { + int reference_count; Connection conn; List<Connection>::Element *cE; + Slot() { reference_count = 0; } }; MethodInfo user; @@ -547,6 +551,8 @@ protected: friend class ClassDB; virtual void _validate_property(PropertyInfo &property) const; + void _disconnect(const StringName &p_signal, Object *p_to_object, const StringName &p_to_method, bool p_force = false); + public: //should be protected, but bug in clang++ static void initialize_class(); _FORCE_INLINE_ static void register_custom_data_to_otdb(){}; diff --git a/core/os/dir_access.cpp b/core/os/dir_access.cpp index 330a9153ef..e631d6e994 100644 --- a/core/os/dir_access.cpp +++ b/core/os/dir_access.cpp @@ -98,22 +98,18 @@ static Error _erase_recursive(DirAccess *da) { err = _erase_recursive(da); if (err) { - print_line("err recurso " + E->get()); da->change_dir(".."); return err; } err = da->change_dir(".."); if (err) { - print_line("no go back " + E->get()); return err; } err = da->remove(da->get_current_dir().plus_file(E->get())); if (err) { - print_line("no remove dir" + E->get()); return err; } } else { - print_line("no change to " + E->get()); return err; } } @@ -122,8 +118,6 @@ static Error _erase_recursive(DirAccess *da) { Error err = da->remove(da->get_current_dir().plus_file(E->get())); if (err) { - - print_line("no remove file" + E->get()); return err; } } diff --git a/core/os/os.cpp b/core/os/os.cpp index 97dae05919..e90d714450 100644 --- a/core/os/os.cpp +++ b/core/os/os.cpp @@ -689,6 +689,18 @@ PoolStringArray OS::get_connected_midi_inputs() { return list; } +void OS::open_midi_inputs() { + + if (MIDIDriver::get_singleton()) + MIDIDriver::get_singleton()->open(); +} + +void OS::close_midi_inputs() { + + if (MIDIDriver::get_singleton()) + MIDIDriver::get_singleton()->close(); +} + OS::OS() { void *volatile stack_bottom; diff --git a/core/os/os.h b/core/os/os.h index dd783408e8..6f9a72d451 100644 --- a/core/os/os.h +++ b/core/os/os.h @@ -190,6 +190,8 @@ public: virtual const char *get_audio_driver_name(int p_driver) const; virtual PoolStringArray get_connected_midi_inputs(); + virtual void open_midi_inputs(); + virtual void close_midi_inputs(); virtual int get_screen_count() const { return 1; } virtual int get_current_screen() const { return 0; } @@ -254,7 +256,7 @@ public: virtual String get_executable_path() const; virtual Error execute(const String &p_path, const List<String> &p_arguments, bool p_blocking, ProcessID *r_child_id = NULL, String *r_pipe = NULL, int *r_exitcode = NULL, bool read_stderr = false) = 0; - virtual Error kill(const ProcessID &p_pid) = 0; + virtual Error kill(const ProcessID &p_pid, const int p_max_wait_msec = -1) = 0; virtual int get_process_id() const; virtual Error shell_open(String p_uri); diff --git a/core/os/rw_lock.h b/core/os/rw_lock.h index 9053794c83..3e53300c9f 100644 --- a/core/os/rw_lock.h +++ b/core/os/rw_lock.h @@ -56,8 +56,10 @@ class RWLockRead { RWLock *lock; public: - RWLockRead(RWLock *p_lock) { - lock = p_lock; + RWLockRead(const RWLock *p_lock) { + if (p_lock) { + lock = const_cast<RWLock *>(p_lock); + } if (lock) lock->read_lock(); } ~RWLockRead() { diff --git a/core/print_string.cpp b/core/print_string.cpp index 0355154488..e1e42d2b56 100644 --- a/core/print_string.cpp +++ b/core/print_string.cpp @@ -107,3 +107,10 @@ void print_error(String p_string) { _global_unlock(); } + +void print_verbose(String p_string) { + + if (OS::get_singleton()->is_stdout_verbose()) { + print_line(p_string); + } +} diff --git a/core/print_string.h b/core/print_string.h index 3465888d4c..c1d2d0ff3a 100644 --- a/core/print_string.h +++ b/core/print_string.h @@ -58,5 +58,6 @@ extern bool _print_line_enabled; extern bool _print_error_enabled; extern void print_line(String p_string); extern void print_error(String p_string); +extern void print_verbose(String p_string); #endif diff --git a/core/project_settings.cpp b/core/project_settings.cpp index 87a5c3e493..890789ec6f 100644 --- a/core/project_settings.cpp +++ b/core/project_settings.cpp @@ -191,7 +191,7 @@ bool ProjectSettings::_get(const StringName &p_name, Variant &r_ret) const { name = feature_overrides[name]; } if (!props.has(name)) { - print_line("WARNING: not found: " + String(name)); + WARN_PRINTS("Property not found: " + String(name)); return false; } r_ret = props[name].variant; diff --git a/core/reference.h b/core/reference.h index 0d6b1ced6e..25e02180fa 100644 --- a/core/reference.h +++ b/core/reference.h @@ -87,6 +87,13 @@ class Ref { //virtual Reference * get_reference() const { return reference; } public: + _FORCE_INLINE_ bool operator==(const T *p_ptr) const { + return reference == p_ptr; + } + _FORCE_INLINE_ bool operator!=(const T *p_ptr) const { + return reference != p_ptr; + } + _FORCE_INLINE_ bool operator<(const Ref<T> &p_r) const { return reference < p_r.reference; diff --git a/core/resource.cpp b/core/resource.cpp index 87ff4d3c2a..3078eb135a 100644 --- a/core/resource.cpp +++ b/core/resource.cpp @@ -151,7 +151,7 @@ Ref<Resource> Resource::duplicate_for_local_scene(Node *p_for_scene, Map<Ref<Res List<PropertyInfo> plist; get_property_list(&plist); - Resource *r = (Resource *)ClassDB::instance(get_class()); + Resource *r = Object::cast_to<Resource>(ClassDB::instance(get_class())); ERR_FAIL_COND_V(!r, Ref<Resource>()); r->local_scene = p_for_scene; @@ -182,7 +182,9 @@ Ref<Resource> Resource::duplicate_for_local_scene(Node *p_for_scene, Map<Ref<Res r->set(E->get().name, p); } - return Ref<Resource>(r); + RES res = Ref<Resource>(r); + + return res; } void Resource::configure_for_local_scene(Node *p_for_scene, Map<Ref<Resource>, Ref<Resource> > &remap_cache) { diff --git a/core/script_debugger_remote.cpp b/core/script_debugger_remote.cpp index c5daaeea47..2b9b5d6037 100644 --- a/core/script_debugger_remote.cpp +++ b/core/script_debugger_remote.cpp @@ -82,17 +82,16 @@ Error ScriptDebuggerRemote::connect_to_host(const String &p_host, uint16_t p_por const int ms = waits[i]; OS::get_singleton()->delay_usec(ms * 1000); - print_line("Remote Debugger: Connection failed with status: '" + String::num(tcp_client->get_status()) + "', retrying in " + String::num(ms) + " msec."); + ERR_PRINTS("Remote Debugger: Connection failed with status: '" + String::num(tcp_client->get_status()) + "', retrying in " + String::num(ms) + " msec."); }; }; if (tcp_client->get_status() != StreamPeerTCP::STATUS_CONNECTED) { - print_line("Remote Debugger: Unable to connect"); + ERR_PRINTS("Remote Debugger: Unable to connect."); return FAILED; }; - // print_line("Remote Debugger: Connection OK!"); packet_peer_stream->set_stream_peer(tcp_client); return OK; diff --git a/core/string_db.cpp b/core/string_db.cpp index 2475cbe3e8..067e4493a1 100644 --- a/core/string_db.cpp +++ b/core/string_db.cpp @@ -73,7 +73,6 @@ void StringName::cleanup() { _Data *d = _table[i]; lost_strings++; if (OS::get_singleton()->is_stdout_verbose()) { - if (d->cname) { print_line("Orphan StringName: " + String(d->cname)); } else { @@ -85,8 +84,8 @@ void StringName::cleanup() { memdelete(d); } } - if (OS::get_singleton()->is_stdout_verbose() && lost_strings) { - print_line("StringName: " + itos(lost_strings) + " unclaimed string names at exit."); + if (lost_strings) { + print_verbose("StringName: " + itos(lost_strings) + " unclaimed string names at exit."); } lock->unlock(); diff --git a/core/translation.cpp b/core/translation.cpp index 78115c3749..82a16d0b17 100644 --- a/core/translation.cpp +++ b/core/translation.cpp @@ -1098,7 +1098,6 @@ bool TranslationServer::_load_translations(const String &p_from) { for (int i = 0; i < tcount; i++) { - //print_line( "Loading translation from " + r[i] ); Ref<Translation> tr = ResourceLoader::load(r[i]); if (tr.is_valid()) add_translation(tr); diff --git a/core/ustring.cpp b/core/ustring.cpp index 35cd27f7f3..96e3a3d784 100644 --- a/core/ustring.cpp +++ b/core/ustring.cpp @@ -1340,7 +1340,7 @@ String String::utf8(const char *p_utf8, int p_len) { bool String::parse_utf8(const char *p_utf8, int p_len) { -#define _UNICERROR(m_err) print_line("unicode error: " + String(m_err)); +#define _UNICERROR(m_err) print_line("Unicode error: " + String(m_err)); String aux; diff --git a/core/variant_call.cpp b/core/variant_call.cpp index ea51419233..8b18b274b6 100644 --- a/core/variant_call.cpp +++ b/core/variant_call.cpp @@ -516,6 +516,8 @@ struct _VariantCall { VCALL_LOCALMEM4R(Array, bsearch_custom); VCALL_LOCALMEM1R(Array, duplicate); VCALL_LOCALMEM0(Array, invert); + VCALL_LOCALMEM0R(Array, max); + VCALL_LOCALMEM0R(Array, min); static void _call_PoolByteArray_get_string_from_ascii(Variant &r_ret, Variant &p_self, const Variant **p_args) { @@ -1705,6 +1707,8 @@ void register_variant_methods() { ADDFUNC4R(ARRAY, INT, Array, bsearch_custom, NIL, "value", OBJECT, "obj", STRING, "func", BOOL, "before", varray(true)); ADDFUNC0NC(ARRAY, NIL, Array, invert, varray()); ADDFUNC1R(ARRAY, ARRAY, Array, duplicate, BOOL, "deep", varray(false)); + ADDFUNC0R(ARRAY, NIL, Array, max, varray()); + ADDFUNC0R(ARRAY, NIL, Array, min, varray()); ADDFUNC0R(POOL_BYTE_ARRAY, INT, PoolByteArray, size, varray()); ADDFUNC2(POOL_BYTE_ARRAY, NIL, PoolByteArray, set, INT, "idx", INT, "byte", varray()); @@ -1920,23 +1924,11 @@ void register_variant_methods() { transform_x.set(1, 0, 0, 0, 1, 0, 0, 0, -1, 0, 0, 0); _VariantCall::add_variant_constant(Variant::TRANSFORM, "FLIP_Z", transform_z); - _VariantCall::add_variant_constant(Variant::PLANE, "X", Plane(Vector3(1, 0, 0), 0)); - _VariantCall::add_variant_constant(Variant::PLANE, "Y", Plane(Vector3(0, 1, 0), 0)); - _VariantCall::add_variant_constant(Variant::PLANE, "Z", Plane(Vector3(0, 0, 1), 0)); + _VariantCall::add_variant_constant(Variant::PLANE, "PLANE_YZ", Plane(Vector3(1, 0, 0), 0)); + _VariantCall::add_variant_constant(Variant::PLANE, "PLANE_XZ", Plane(Vector3(0, 1, 0), 0)); + _VariantCall::add_variant_constant(Variant::PLANE, "PLANE_XY", Plane(Vector3(0, 0, 1), 0)); _VariantCall::add_variant_constant(Variant::QUAT, "IDENTITY", Quat(0, 0, 0, 1)); - - CharType black_circle[2] = { 0x25CF, 0 }; - _VariantCall::add_variant_constant(Variant::STRING, "BLACK_CIRCLE", String(black_circle)); - CharType white_circle[2] = { 0x25CB, 0 }; - _VariantCall::add_variant_constant(Variant::STRING, "WHITE_CIRCLE", String(white_circle)); - CharType black_diamond[2] = { 0x25C6, 0 }; - _VariantCall::add_variant_constant(Variant::STRING, "BLACK_DIAMOND", String(black_diamond)); - CharType white_diamond[2] = { 0x25C7, 0 }; - _VariantCall::add_variant_constant(Variant::STRING, "WHITE_DIAMOND", String(white_diamond)); - - _VariantCall::add_variant_constant(Variant::NODE_PATH, "CURRENT", String(".")); - _VariantCall::add_variant_constant(Variant::NODE_PATH, "PARENT", String("..")); } void unregister_variant_methods() { |