diff options
98 files changed, 745 insertions, 241 deletions
diff --git a/SConstruct b/SConstruct index 96aa3ed96b..55b061a6f7 100644 --- a/SConstruct +++ b/SConstruct @@ -339,7 +339,6 @@ if selected_platform in platform_list: if (env["werror"]): env.Append(CCFLAGS=['/WX']) else: # Rest of the world - disable_nonessential_warnings = ['-Wno-sign-compare'] shadow_local_warning = [] all_plus_warnings = ['-Wwrite-strings'] @@ -350,9 +349,9 @@ if selected_platform in platform_list: if (env["warnings"] == 'extra'): env.Append(CCFLAGS=['-Wall', '-Wextra'] + all_plus_warnings + shadow_local_warning) elif (env["warnings"] == 'all'): - env.Append(CCFLAGS=['-Wall'] + all_plus_warnings + shadow_local_warning + disable_nonessential_warnings) + env.Append(CCFLAGS=['-Wall'] + shadow_local_warning) elif (env["warnings"] == 'moderate'): - env.Append(CCFLAGS=['-Wall', '-Wno-unused'] + shadow_local_warning + disable_nonessential_warnings) + env.Append(CCFLAGS=['-Wall', '-Wno-unused'] + shadow_local_warning) else: # 'no' env.Append(CCFLAGS=['-w']) if (env["werror"]): diff --git a/core/io/logger.h b/core/io/logger.h index 0b871a13de..ff5b8ce489 100644 --- a/core/io/logger.h +++ b/core/io/logger.h @@ -49,11 +49,11 @@ public: ERR_SHADER }; - virtual void logv(const char *p_format, va_list p_list, bool p_err) = 0; + virtual void logv(const char *p_format, va_list p_list, bool p_err) _PRINTF_FORMAT_ATTRIBUTE_2_0 = 0; virtual void log_error(const char *p_function, const char *p_file, int p_line, const char *p_code, const char *p_rationale, ErrorType p_type = ERR_ERROR); - void logf(const char *p_format, ...); - void logf_error(const char *p_format, ...); + void logf(const char *p_format, ...) _PRINTF_FORMAT_ATTRIBUTE_2_3; + void logf_error(const char *p_format, ...) _PRINTF_FORMAT_ATTRIBUTE_2_3; virtual ~Logger(); }; @@ -64,7 +64,7 @@ public: class StdLogger : public Logger { public: - virtual void logv(const char *p_format, va_list p_list, bool p_err); + virtual void logv(const char *p_format, va_list p_list, bool p_err) _PRINTF_FORMAT_ATTRIBUTE_2_0; virtual ~StdLogger(); }; @@ -88,7 +88,7 @@ class RotatedFileLogger : public Logger { public: RotatedFileLogger(const String &p_base_path, int p_max_files = 10); - virtual void logv(const char *p_format, va_list p_list, bool p_err); + virtual void logv(const char *p_format, va_list p_list, bool p_err) _PRINTF_FORMAT_ATTRIBUTE_2_0; virtual ~RotatedFileLogger(); }; @@ -99,7 +99,7 @@ class CompositeLogger : public Logger { public: CompositeLogger(Vector<Logger *> p_loggers); - virtual void logv(const char *p_format, va_list p_list, bool p_err); + virtual void logv(const char *p_format, va_list p_list, bool p_err) _PRINTF_FORMAT_ATTRIBUTE_2_0; virtual void log_error(const char *p_function, const char *p_file, int p_line, const char *p_code, const char *p_rationale, ErrorType p_type = ERR_ERROR); void add_logger(Logger *p_logger); diff --git a/core/io/packet_peer.cpp b/core/io/packet_peer.cpp index 3aa1fcfd8f..d7bfdbbb37 100644 --- a/core/io/packet_peer.cpp +++ b/core/io/packet_peer.cpp @@ -224,7 +224,7 @@ Error PacketPeerStream::get_packet(const uint8_t **r_buffer, int &r_buffer_size) uint32_t len = decode_uint32(lbuf); ERR_FAIL_COND_V(remaining < (int)len, ERR_UNAVAILABLE); - ERR_FAIL_COND_V(input_buffer.size() < len, ERR_UNAVAILABLE); + ERR_FAIL_COND_V(input_buffer.size() < (int)len, ERR_UNAVAILABLE); ring_buffer.read(lbuf, 4); //get rid of first 4 bytes ring_buffer.read(input_buffer.ptrw(), len); // read packet diff --git a/core/io/resource_format_binary.cpp b/core/io/resource_format_binary.cpp index 6c48942d72..42070cd132 100644 --- a/core/io/resource_format_binary.cpp +++ b/core/io/resource_format_binary.cpp @@ -106,7 +106,7 @@ StringName ResourceInteractiveLoaderBinary::_get_string() { uint32_t id = f->get_32(); if (id & 0x80000000) { uint32_t len = id & 0x7FFFFFFF; - if (len > str_buf.size()) { + if ((int)len > str_buf.size()) { str_buf.resize(len); } if (len == 0) diff --git a/core/io/resource_importer.cpp b/core/io/resource_importer.cpp index 9327e000f5..427ce2c2cd 100644 --- a/core/io/resource_importer.cpp +++ b/core/io/resource_importer.cpp @@ -33,6 +33,10 @@ #include "core/os/os.h" #include "core/variant_parser.h" +bool ResourceFormatImporter::SortImporterByName::operator()(const Ref<ResourceImporter> &p_a, const Ref<ResourceImporter> &p_b) const { + return p_a->get_importer_name() < p_b->get_importer_name(); +} + Error ResourceFormatImporter::_get_path_and_type(const String &p_path, PathAndType &r_path_and_type, bool *r_valid) const { Error err; @@ -90,6 +94,8 @@ Error ResourceFormatImporter::_get_path_and_type(const String &p_path, PathAndTy r_path_and_type.type = value; } else if (assign == "importer") { r_path_and_type.importer = value; + } else if (assign == "metadata") { + r_path_and_type.metadata = value; } else if (assign == "valid") { if (r_valid) { *r_valid = value; @@ -304,6 +310,18 @@ String ResourceFormatImporter::get_resource_type(const String &p_path) const { return pat.type; } +Variant ResourceFormatImporter::get_resource_metadata(const String &p_path) const { + PathAndType pat; + Error err = _get_path_and_type(p_path, pat); + + if (err != OK) { + + return Variant(); + } + + return pat.metadata; +} + void ResourceFormatImporter::get_dependencies(const String &p_path, List<String> *p_dependencies, bool p_add_types) { PathAndType pat; @@ -366,6 +384,35 @@ String ResourceFormatImporter::get_import_base_path(const String &p_for_file) co return "res://.import/" + p_for_file.get_file() + "-" + p_for_file.md5_text(); } +bool ResourceFormatImporter::are_import_settings_valid(const String &p_path) const { + + bool valid = true; + PathAndType pat; + _get_path_and_type(p_path, pat, &valid); + + if (!valid) { + return false; + } + + for (int i = 0; i < importers.size(); i++) { + if (importers[i]->get_importer_name() == pat.importer) { + if (!importers[i]->are_import_settings_valid(p_path)) { //importer thinks this is not valid + return false; + } + } + } + + return true; +} + +String ResourceFormatImporter::get_import_settings_hash() const { + String hash; + for (int i = 0; i < importers.size(); i++) { + hash += ":" + importers[i]->get_importer_name() + ":" + importers[i]->get_import_settings_string(); + } + return hash.md5_text(); +} + ResourceFormatImporter *ResourceFormatImporter::singleton = NULL; ResourceFormatImporter::ResourceFormatImporter() { diff --git a/core/io/resource_importer.h b/core/io/resource_importer.h index 32c39a8085..db1befb51e 100644 --- a/core/io/resource_importer.h +++ b/core/io/resource_importer.h @@ -43,12 +43,18 @@ class ResourceFormatImporter : public ResourceFormatLoader { String path; String type; String importer; + Variant metadata; }; Error _get_path_and_type(const String &p_path, PathAndType &r_path_and_type, bool *r_valid = NULL) const; static ResourceFormatImporter *singleton; + //need them to stay in order to compute the settings hash + struct SortImporterByName { + bool operator()(const Ref<ResourceImporter> &p_a, const Ref<ResourceImporter> &p_b) const; + }; + Vector<Ref<ResourceImporter> > importers; public: @@ -59,6 +65,7 @@ public: virtual bool recognize_path(const String &p_path, const String &p_for_type = String()) const; virtual bool handles_type(const String &p_type) const; virtual String get_resource_type(const String &p_path) const; + virtual Variant get_resource_metadata(const String &p_path) const; virtual bool is_import_valid(const String &p_path) const; virtual void get_dependencies(const String &p_path, List<String> *p_dependencies, bool p_add_types = false); @@ -68,12 +75,18 @@ public: String get_internal_resource_path(const String &p_path) const; void get_internal_resource_path_list(const String &p_path, List<String> *r_paths); - void add_importer(const Ref<ResourceImporter> &p_importer) { importers.push_back(p_importer); } + void add_importer(const Ref<ResourceImporter> &p_importer) { + importers.push_back(p_importer); + importers.sort_custom<SortImporterByName>(); + } void remove_importer(const Ref<ResourceImporter> &p_importer) { importers.erase(p_importer); } Ref<ResourceImporter> get_importer_by_name(const String &p_name) const; Ref<ResourceImporter> get_importer_by_extension(const String &p_extension) const; void get_importers_for_extension(const String &p_extension, List<Ref<ResourceImporter> > *r_importers); + bool are_import_settings_valid(const String &p_path) const; + String get_import_settings_hash() const; + String get_import_base_path(const String &p_for_file) const; ResourceFormatImporter(); }; @@ -107,7 +120,9 @@ public: virtual void get_import_options(List<ImportOption> *r_options, int p_preset = 0) const = 0; virtual bool get_option_visibility(const String &p_option, const Map<StringName, Variant> &p_options) const = 0; - virtual Error import(const String &p_source_file, const String &p_save_path, const Map<StringName, Variant> &p_options, List<String> *r_platform_variants, List<String> *r_gen_files = NULL) = 0; + virtual Error import(const String &p_source_file, const String &p_save_path, const Map<StringName, Variant> &p_options, List<String> *r_platform_variants, List<String> *r_gen_files = NULL, Variant *r_metadata = NULL) = 0; + virtual bool are_import_settings_valid(const String &p_path) const { return true; } + virtual String get_import_settings_string() const { return String(); } }; #endif // RESOURCE_IMPORTER_H diff --git a/core/math/basis.cpp b/core/math/basis.cpp index c293e753a6..8816e3639a 100644 --- a/core/math/basis.cpp +++ b/core/math/basis.cpp @@ -76,23 +76,17 @@ void Basis::invert() { } void Basis::orthonormalize() { - /* this check is undesired, the matrix could be wrong but we still may want to generate a valid one - * for practical purposes + #ifdef MATH_CHECKS ERR_FAIL_COND(determinant() == 0); #endif -*/ + // Gram-Schmidt Process Vector3 x = get_axis(0); Vector3 y = get_axis(1); Vector3 z = get_axis(2); -#ifdef MATH_CHECKS - ERR_FAIL_COND(x.length_squared() == 0); - ERR_FAIL_COND(y.length_squared() == 0); - ERR_FAIL_COND(z.length_squared() == 0); -#endif x.normalize(); y = (y - x * (x.dot(y))); y.normalize(); diff --git a/core/os/os.cpp b/core/os/os.cpp index d2d39d253a..03e63f636e 100644 --- a/core/os/os.cpp +++ b/core/os/os.cpp @@ -569,6 +569,11 @@ int OS::get_power_percent_left() { return -1; } +void OS::set_has_server_feature_callback(HasServerFeatureCallback p_callback) { + + has_server_feature_callback = p_callback; +} + bool OS::has_feature(const String &p_feature) { if (p_feature == get_name()) @@ -625,6 +630,10 @@ bool OS::has_feature(const String &p_feature) { if (_check_internal_feature_support(p_feature)) return true; + if (has_server_feature_callback && has_server_feature_callback(p_feature)) { + return true; + } + if (ProjectSettings::get_singleton()->has_custom_feature(p_feature)) return true; @@ -729,6 +738,8 @@ OS::OS() { _logger = NULL; + has_server_feature_callback = NULL; + Vector<Logger *> loggers; loggers.push_back(memnew(StdLogger)); _set_logger(memnew(CompositeLogger(loggers))); diff --git a/core/os/os.h b/core/os/os.h index 396555970a..d6541034fd 100644 --- a/core/os/os.h +++ b/core/os/os.h @@ -77,6 +77,7 @@ protected: public: typedef void (*ImeCallback)(void *p_inp, String p_text, Point2 p_selection); + typedef bool (*HasServerFeatureCallback)(const String &p_feature); enum PowerState { POWERSTATE_UNKNOWN, /**< cannot determine power status */ @@ -121,6 +122,7 @@ public: protected: friend class Main; + HasServerFeatureCallback has_server_feature_callback; RenderThreadMode _render_thread_mode; // functions used by main to initialize/deinitialize the OS @@ -146,8 +148,8 @@ public: static OS *get_singleton(); void print_error(const char *p_function, const char *p_file, int p_line, const char *p_code, const char *p_rationale, Logger::ErrorType p_type = Logger::ERR_ERROR); - void print(const char *p_format, ...); - void printerr(const char *p_format, ...); + void print(const char *p_format, ...) _PRINTF_FORMAT_ATTRIBUTE_2_3; + void printerr(const char *p_format, ...) _PRINTF_FORMAT_ATTRIBUTE_2_3; virtual void alert(const String &p_alert, const String &p_title = "ALERT!") = 0; virtual String get_stdin_string(bool p_block = true) = 0; @@ -507,6 +509,8 @@ public: virtual void force_process_input(){}; bool has_feature(const String &p_feature); + void set_has_server_feature_callback(HasServerFeatureCallback p_callback); + bool is_layered_allowed() const { return _allow_layered; } bool is_hidpi_allowed() const { return _allow_hidpi; } diff --git a/core/script_debugger_remote.cpp b/core/script_debugger_remote.cpp index 9780cc48ea..3ed25f118d 100644 --- a/core/script_debugger_remote.cpp +++ b/core/script_debugger_remote.cpp @@ -1054,7 +1054,6 @@ void ScriptDebuggerRemote::profiling_set_frame_times(float p_frame_time, float p physics_frame_time = p_physics_frame_time; } - ScriptDebuggerRemote::ResourceUsageFunc ScriptDebuggerRemote::resource_usage_func = NULL; ScriptDebuggerRemote::ScriptDebuggerRemote() : diff --git a/core/typedefs.h b/core/typedefs.h index e01e1c00b9..966360d4f2 100644 --- a/core/typedefs.h +++ b/core/typedefs.h @@ -307,4 +307,12 @@ struct _GlobalLock { #define unlikely(x) x #endif +#if defined(__GNUC__) +#define _PRINTF_FORMAT_ATTRIBUTE_2_0 __attribute__((format(printf, 2, 0))) +#define _PRINTF_FORMAT_ATTRIBUTE_2_3 __attribute__((format(printf, 2, 3))) +#else +#define _PRINTF_FORMAT_ATTRIBUTE_2_0 +#define _PRINTF_FORMAT_ATTRIBUTE_2_3 +#endif + #endif // TYPEDEFS_H diff --git a/doc/classes/MultiMesh.xml b/doc/classes/MultiMesh.xml index 565e19c229..0cc9764e36 100644 --- a/doc/classes/MultiMesh.xml +++ b/doc/classes/MultiMesh.xml @@ -65,6 +65,7 @@ </argument> <description> Set the color of a specific instance. + For the color to take effect, ensure that [member color_format] is non-[code]null[/code] on the [code]MultiMesh[/code] and [member SpatialMaterial.vertex_color_use_as_albedo] is [code]true[/code] on the material. </description> </method> <method name="set_instance_custom_data"> diff --git a/drivers/gles2/rasterizer_canvas_gles2.cpp b/drivers/gles2/rasterizer_canvas_gles2.cpp index e922320e08..5d336d2a25 100644 --- a/drivers/gles2/rasterizer_canvas_gles2.cpp +++ b/drivers/gles2/rasterizer_canvas_gles2.cpp @@ -509,7 +509,7 @@ void RasterizerCanvasGLES2::_canvas_item_render_commands(Item *p_item, Item *cur texture = texture->get_ptr(); - if (next_power_of_2(texture->alloc_width) != texture->alloc_width && next_power_of_2(texture->alloc_height) != texture->alloc_height) { + if (next_power_of_2(texture->alloc_width) != (unsigned int)texture->alloc_width && next_power_of_2(texture->alloc_height) != (unsigned int)texture->alloc_height) { state.canvas_shader.set_conditional(CanvasShaderGLES2::USE_FORCE_REPEAT, true); can_tile = false; } diff --git a/drivers/gles2/rasterizer_scene_gles2.cpp b/drivers/gles2/rasterizer_scene_gles2.cpp index de77c2c63e..0fd36cfb9c 100644 --- a/drivers/gles2/rasterizer_scene_gles2.cpp +++ b/drivers/gles2/rasterizer_scene_gles2.cpp @@ -42,8 +42,6 @@ #define glClearDepth glClearDepthf #endif -#define _DEPTH_COMPONENT24_OES 0x81A6 - static const GLenum _cube_side_enum[6] = { GL_TEXTURE_CUBE_MAP_NEGATIVE_X, @@ -158,7 +156,7 @@ void RasterizerSceneGLES2::shadow_atlas_set_quadrant_subdivision(RID p_atlas, in subdiv = int(Math::sqrt((float)subdiv)); - if (shadow_atlas->quadrants[p_quadrant].shadows.size() == subdiv) + if (shadow_atlas->quadrants[p_quadrant].shadows.size() == (int)subdiv) return; // erase all data from the quadrant @@ -569,7 +567,7 @@ bool RasterizerSceneGLES2::reflection_probe_instance_begin_render(RID p_instance glBindFramebuffer(GL_FRAMEBUFFER, rpi->fbo[i]); glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, _cube_side_enum[i], rpi->cubemap, 0); glBindRenderbuffer(GL_RENDERBUFFER, rpi->depth); - glRenderbufferStorage(GL_RENDERBUFFER, _DEPTH_COMPONENT24_OES, size, size); + glRenderbufferStorage(GL_RENDERBUFFER, GL_DEPTH_COMPONENT, size, size); // Note: used to be _DEPTH_COMPONENT24_OES. GL_DEPTH_COMPONENT untested. glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_DEPTH_ATTACHMENT, GL_RENDERBUFFER, rpi->depth); #ifdef DEBUG_ENABLED diff --git a/drivers/gles2/rasterizer_storage_gles2.cpp b/drivers/gles2/rasterizer_storage_gles2.cpp index 0acbb8cf51..9d2e609e5e 100644 --- a/drivers/gles2/rasterizer_storage_gles2.cpp +++ b/drivers/gles2/rasterizer_storage_gles2.cpp @@ -54,8 +54,6 @@ GLuint RasterizerStorageGLES2::system_fbo = 0; #define _EXT_TEXTURE_CUBE_MAP_SEAMLESS 0x884F -#define _DEPTH_COMPONENT24_OES 0x81A6 - #define _RED_OES 0x1903 void RasterizerStorageGLES2::bind_quad_array() const { @@ -4309,11 +4307,8 @@ void RasterizerStorageGLES2::_render_target_allocate(RenderTarget *rt) { glGenTextures(1, &rt->depth); glBindTexture(GL_TEXTURE_2D, rt->depth); -#ifdef JAVASCRIPT_ENABLED glTexImage2D(GL_TEXTURE_2D, 0, GL_DEPTH_COMPONENT, rt->width, rt->height, 0, GL_DEPTH_COMPONENT, GL_UNSIGNED_INT, NULL); -#else - glTexImage2D(GL_TEXTURE_2D, 0, _DEPTH_COMPONENT24_OES, rt->width, rt->height, 0, GL_DEPTH_COMPONENT, GL_UNSIGNED_INT, NULL); -#endif + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE); @@ -4536,15 +4531,17 @@ RID RasterizerStorageGLES2::canvas_light_shadow_buffer_create(int p_width) { glGenFramebuffers(1, &cls->fbo); glBindFramebuffer(GL_FRAMEBUFFER, cls->fbo); - glGenRenderbuffers(1, &cls->depth); - glBindRenderbuffer(GL_RENDERBUFFER, cls->depth); -#ifdef JAVASCRIPT_ENABLED - glRenderbufferStorage(GL_RENDERBUFFER, GL_DEPTH_COMPONENT16, cls->size, cls->height); -#else - glRenderbufferStorage(GL_RENDERBUFFER, _DEPTH_COMPONENT24_OES, cls->size, cls->height); -#endif - glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_DEPTH_ATTACHMENT, GL_RENDERBUFFER, cls->depth); - glBindRenderbuffer(GL_RENDERBUFFER, 0); + glGenTextures(1, &cls->depth); + glBindTexture(GL_TEXTURE_2D, cls->depth); + + glTexImage2D(GL_TEXTURE_2D, 0, GL_DEPTH_COMPONENT, cls->size, cls->height, 0, GL_DEPTH_COMPONENT, GL_UNSIGNED_INT, NULL); + + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE); + + glFramebufferTexture2D(GL_FRAMEBUFFER, GL_DEPTH_ATTACHMENT, GL_TEXTURE_2D, cls->depth, 0); glGenTextures(1, &cls->distance); glBindTexture(GL_TEXTURE_2D, cls->distance); @@ -4909,7 +4906,7 @@ bool RasterizerStorageGLES2::free(RID p_rid) { CanvasLightShadow *cls = canvas_light_shadow_owner.get(p_rid); glDeleteFramebuffers(1, &cls->fbo); - glDeleteRenderbuffers(1, &cls->depth); + glDeleteTextures(1, &cls->depth); glDeleteTextures(1, &cls->distance); canvas_light_shadow_owner.free(p_rid); memdelete(cls); @@ -4922,6 +4919,9 @@ bool RasterizerStorageGLES2::free(RID p_rid) { bool RasterizerStorageGLES2::has_os_feature(const String &p_feature) const { + if (p_feature == "pvrtc") + return config.pvrtc_supported; + if (p_feature == "s3tc") return config.s3tc_supported; @@ -4971,12 +4971,14 @@ void RasterizerStorageGLES2::initialize() { #ifdef GLES_OVER_GL config.float_texture_supported = true; config.s3tc_supported = true; + config.pvrtc_supported = false; config.etc1_supported = false; config.support_npot_repeat_mipmap = true; #else config.float_texture_supported = config.extensions.has("GL_ARB_texture_float") || config.extensions.has("GL_OES_texture_float"); config.s3tc_supported = config.extensions.has("GL_EXT_texture_compression_s3tc") || config.extensions.has("WEBGL_compressed_texture_s3tc"); config.etc1_supported = config.extensions.has("GL_OES_compressed_ETC1_RGB8_texture") || config.extensions.has("WEBGL_compressed_texture_etc1"); + config.pvrtc_supported = config.extensions.has("IMG_texture_compression_pvrtc"); config.support_npot_repeat_mipmap = config.extensions.has("GL_OES_texture_npot"); #endif diff --git a/drivers/gles2/rasterizer_storage_gles2.h b/drivers/gles2/rasterizer_storage_gles2.h index 8e177ba57f..f6c8faa497 100644 --- a/drivers/gles2/rasterizer_storage_gles2.h +++ b/drivers/gles2/rasterizer_storage_gles2.h @@ -72,6 +72,7 @@ public: bool float_texture_supported; bool s3tc_supported; bool etc1_supported; + bool pvrtc_supported; bool keep_original_textures; diff --git a/drivers/gles2/shaders/canvas.glsl b/drivers/gles2/shaders/canvas.glsl index c292897ad0..b13801946f 100644 --- a/drivers/gles2/shaders/canvas.glsl +++ b/drivers/gles2/shaders/canvas.glsl @@ -349,7 +349,7 @@ void main() { vec2 uv = uv_interp; #ifdef USE_FORCE_REPEAT //needs to use this to workaround GLES2/WebGL1 forcing tiling that textures that dont support it - uv = mod(uv,vec2(1.0,1.0)); + uv = mod(uv, vec2(1.0, 1.0)); #endif #if !defined(COLOR_USED) diff --git a/drivers/gles2/shaders/cubemap_filter.glsl b/drivers/gles2/shaders/cubemap_filter.glsl index c32aabc4bf..a6902836ed 100644 --- a/drivers/gles2/shaders/cubemap_filter.glsl +++ b/drivers/gles2/shaders/cubemap_filter.glsl @@ -194,7 +194,7 @@ void main() { gl_FragColor = vec4(texturePanorama(source_panorama, N).rgb, 1.0); #else - gl_FragColor = vec4(textureCube(source_cube,N).rgb, 1.0); + gl_FragColor = vec4(textureCube(source_cube, N).rgb, 1.0); #endif //USE_SOURCE_PANORAMA #else diff --git a/drivers/gles2/shaders/scene.glsl b/drivers/gles2/shaders/scene.glsl index fa359125b2..371ea8498a 100644 --- a/drivers/gles2/shaders/scene.glsl +++ b/drivers/gles2/shaders/scene.glsl @@ -660,7 +660,6 @@ VERTEX_SHADER_CODE #if defined(RENDER_DEPTH) && defined(USE_RGBA_SHADOWS) position_interp = gl_Position; #endif - } /* clang-format off */ @@ -1358,12 +1357,9 @@ LIGHT_SHADER_CODE #endif - #define SAMPLE_SHADOW_TEXEL(p_shadow, p_pos, p_depth) step(p_depth, SHADOW_DEPTH(texture2D(p_shadow, p_pos))) #define SAMPLE_SHADOW_TEXEL_PROJ(p_shadow, p_pos) step(p_pos.z, SHADOW_DEPTH(texture2DProj(p_shadow, p_pos))) - - float sample_shadow(highp sampler2D shadow, highp vec4 spos) { #ifdef SHADOW_MODE_PCF_13 diff --git a/drivers/gles3/rasterizer_scene_gles3.cpp b/drivers/gles3/rasterizer_scene_gles3.cpp index 4cf9054bf6..e645e39f3f 100644 --- a/drivers/gles3/rasterizer_scene_gles3.cpp +++ b/drivers/gles3/rasterizer_scene_gles3.cpp @@ -5053,7 +5053,7 @@ void RasterizerSceneGLES3::initialize() { state.scene_shader.add_custom_define("#define MAX_LIGHT_DATA_STRUCTS " + itos(state.max_ubo_lights) + "\n"); state.scene_shader.add_custom_define("#define MAX_FORWARD_LIGHTS " + itos(state.max_forward_lights_per_object) + "\n"); - state.max_ubo_reflections = MIN(RenderList::MAX_REFLECTIONS, max_ubo_size / sizeof(ReflectionProbeDataUBO)); + state.max_ubo_reflections = MIN((int)RenderList::MAX_REFLECTIONS, max_ubo_size / sizeof(ReflectionProbeDataUBO)); state.reflection_array_tmp = (uint8_t *)memalloc(sizeof(ReflectionProbeDataUBO) * state.max_ubo_reflections); diff --git a/drivers/unix/file_access_unix.cpp b/drivers/unix/file_access_unix.cpp index 072ffd96e7..6e045817bc 100644 --- a/drivers/unix/file_access_unix.cpp +++ b/drivers/unix/file_access_unix.cpp @@ -246,7 +246,7 @@ void FileAccessUnix::store_8(uint8_t p_dest) { void FileAccessUnix::store_buffer(const uint8_t *p_src, int p_length) { ERR_FAIL_COND(!f); - ERR_FAIL_COND(fwrite(p_src, 1, p_length, f) != p_length); + ERR_FAIL_COND((int)fwrite(p_src, 1, p_length, f) != p_length); } bool FileAccessUnix::file_exists(const String &p_path) { diff --git a/drivers/unix/syslog_logger.h b/drivers/unix/syslog_logger.h index 5cfe3964f6..49a34dacc3 100644 --- a/drivers/unix/syslog_logger.h +++ b/drivers/unix/syslog_logger.h @@ -37,7 +37,7 @@ class SyslogLogger : public Logger { public: - virtual void logv(const char *p_format, va_list p_list, bool p_err); + virtual void logv(const char *p_format, va_list p_list, bool p_err) _PRINTF_FORMAT_ATTRIBUTE_2_0; virtual void print_error(const char *p_function, const char *p_file, int p_line, const char *p_code, const char *p_rationale, ErrorType p_type); virtual ~SyslogLogger(); diff --git a/editor/editor_export.cpp b/editor/editor_export.cpp index 39e6df4450..2b9007de04 100644 --- a/editor/editor_export.cpp +++ b/editor/editor_export.cpp @@ -1160,6 +1160,17 @@ void EditorExport::add_export_preset(const Ref<EditorExportPreset> &p_preset, in export_presets.insert(p_at_pos, p_preset); } +String EditorExportPlatform::test_etc2() const { + + String driver = ProjectSettings::get_singleton()->get("rendering/quality/driver/driver_name"); + bool etc2_supported = ProjectSettings::get_singleton()->get("rendering/vram_compression/import_etc"); + + if (driver == "GLES2" && !etc2_supported) { + return TTR("Target platform requires 'ETC' texture compression for GLES2. Enable support in Project Settings."); + } + return String(); +} + int EditorExport::get_export_preset_count() const { return export_presets.size(); diff --git a/editor/editor_export.h b/editor/editor_export.h index c7c2b76327..bd864c528c 100644 --- a/editor/editor_export.h +++ b/editor/editor_export.h @@ -258,6 +258,7 @@ public: virtual Error run(const Ref<EditorExportPreset> &p_preset, int p_device, int p_debug_flags) { return OK; } virtual Ref<Texture> get_run_icon() const { return get_logo(); } + String test_etc2() const; //generic test for etc2 since most platforms use it virtual bool can_export(const Ref<EditorExportPreset> &p_preset, String &r_error, bool &r_missing_templates) const = 0; virtual List<String> get_binary_extensions(const Ref<EditorExportPreset> &p_preset) const = 0; diff --git a/editor/editor_file_system.cpp b/editor/editor_file_system.cpp index ea36410cc3..3d9d5e26be 100644 --- a/editor/editor_file_system.cpp +++ b/editor/editor_file_system.cpp @@ -42,6 +42,8 @@ #include "editor_settings.h" EditorFileSystem *EditorFileSystem::singleton = NULL; +//the name is the version, to keep compatibility with different versions of Godot +#define CACHE_FILE_NAME "filesystem_cache5" void EditorFileSystemDirectory::sort_files() { @@ -203,14 +205,30 @@ void EditorFileSystem::_scan_filesystem() { String project = ProjectSettings::get_singleton()->get_resource_path(); - String fscache = EditorSettings::get_singleton()->get_project_settings_dir().plus_file("filesystem_cache4"); + String fscache = EditorSettings::get_singleton()->get_project_settings_dir().plus_file(CACHE_FILE_NAME); FileAccess *f = FileAccess::open(fscache, FileAccess::READ); + bool first = true; if (f) { //read the disk cache while (!f->eof_reached()) { String l = f->get_line().strip_edges(); + if (first) { + if (first_scan) { + // only use this on first scan, afterwards it gets ignored + // this is so on first reimport we synchronize versions, then + // we dont care until editor restart. This is for usability mainly so + // your workflow is not killed after changing a setting by forceful reimporting + // everything there is. + filesystem_settings_version_for_import = l.strip_edges(); + if (filesystem_settings_version_for_import != ResourceFormatImporter::get_singleton()->get_import_settings_hash()) { + revalidate_import_files = true; + } + } + first = false; + continue; + } if (l == String()) continue; @@ -291,25 +309,22 @@ void EditorFileSystem::_scan_filesystem() { memdelete(d); - f = FileAccess::open(fscache, FileAccess::WRITE); - if (f == NULL) { - ERR_PRINTS("Error writing fscache: " + fscache); - } else { - _save_filesystem_cache(new_filesystem, f); - f->close(); - memdelete(f); + if (!first_scan) { + //on the first scan this is done from the main thread after re-importing + _save_filesystem_cache(); } scanning = false; } void EditorFileSystem::_save_filesystem_cache() { - String fscache = EditorSettings::get_singleton()->get_project_settings_dir().plus_file("filesystem_cache4"); + String fscache = EditorSettings::get_singleton()->get_project_settings_dir().plus_file(CACHE_FILE_NAME); FileAccess *f = FileAccess::open(fscache, FileAccess::WRITE); if (f == NULL) { ERR_PRINTS("Error writing fscache: " + fscache); } else { + f->store_line(filesystem_settings_version_for_import); _save_filesystem_cache(filesystem, f); f->close(); memdelete(f); @@ -327,6 +342,15 @@ bool EditorFileSystem::_test_for_reimport(const String &p_path, bool p_only_impo if (!reimport_on_missing_imported_files && p_only_imported_files) return false; + if (!FileAccess::exists(p_path + ".import")) { + return true; + } + + if (!ResourceFormatImporter::get_singleton()->are_import_settings_valid(p_path)) { + //reimport settings are not valid, reimport + return true; + } + Error err; FileAccess *f = FileAccess::open(p_path + ".import", FileAccess::READ, &err); @@ -562,6 +586,13 @@ bool EditorFileSystem::_update_scan_actions() { reimport_files(reimports); } + if (first_scan) { + //only on first scan this is valid and updated, then settings changed. + revalidate_import_files = false; + filesystem_settings_version_for_import = ResourceFormatImporter::get_singleton()->get_import_settings_hash(); + _save_filesystem_cache(); + } + if (reloads.size()) { emit_signal("resources_reload", reloads); } @@ -595,7 +626,7 @@ void EditorFileSystem::scan() { emit_signal("filesystem_changed"); emit_signal("sources_changed", sources_changed.size() > 0); _queue_update_script_classes(); - + first_scan = false; } else { ERR_FAIL_COND(thread); @@ -737,11 +768,20 @@ void EditorFileSystem::_scan_new_dir(EditorFileSystemDirectory *p_dir, DirAccess fi->deps = fc->deps; fi->modified_time = fc->modification_time; fi->import_modified_time = fc->import_modification_time; + fi->import_valid = fc->import_valid; fi->script_class_name = fc->script_class_name; fi->script_class_extends = fc->script_class_extends; fi->script_class_icon_path = fc->script_class_icon_path; + if (revalidate_import_files && !ResourceFormatImporter::get_singleton()->are_import_settings_valid(path)) { + ItemAction ia; + ia.action = ItemAction::ACTION_FILE_TEST_REIMPORT; + ia.dir = p_dir; + ia.file = E->get(); + scan_actions.push_back(ia); + } + if (fc->type == String()) { fi->type = ResourceLoader::get_resource_type(path); //there is also the chance that file type changed due to reimport, must probably check this somehow here (or kind of note it for next time in another file?) @@ -1101,6 +1141,7 @@ void EditorFileSystem::_notification(int p_what) { emit_signal("filesystem_changed"); emit_signal("sources_changed", sources_changed.size() > 0); _queue_update_script_classes(); + first_scan = false; } } else if (!scanning) { @@ -1117,6 +1158,7 @@ void EditorFileSystem::_notification(int p_what) { emit_signal("filesystem_changed"); emit_signal("sources_changed", sources_changed.size() > 0); _queue_update_script_classes(); + first_scan = false; } } } break; @@ -1569,8 +1611,8 @@ void EditorFileSystem::_reimport_file(const String &p_file) { List<String> import_variants; List<String> gen_files; - - Error err = importer->import(p_file, base_path, params, &import_variants, &gen_files); + Variant metadata; + Error err = importer->import(p_file, base_path, params, &import_variants, &gen_files, &metadata); if (err != OK) { ERR_PRINTS("Error importing: " + p_file); @@ -1615,6 +1657,10 @@ void EditorFileSystem::_reimport_file(const String &p_file) { f->store_line("valid=false"); } + if (metadata != Variant()) { + f->store_line("metadata=" + metadata.get_construct_string()); + } + f->store_line(""); f->store_line("[deps]\n"); @@ -1815,6 +1861,8 @@ EditorFileSystem::EditorFileSystem() { scan_total = 0; update_script_classes_queued = false; + first_scan = true; + revalidate_import_files = false; } EditorFileSystem::~EditorFileSystem() { diff --git a/editor/editor_file_system.h b/editor/editor_file_system.h index bb892baf57..2a9e325454 100644 --- a/editor/editor_file_system.h +++ b/editor/editor_file_system.h @@ -143,7 +143,10 @@ class EditorFileSystem : public Node { bool abort_scan; bool scanning; bool importing; + bool first_scan; float scan_total; + String filesystem_settings_version_for_import; + bool revalidate_import_files; void _scan_filesystem(); diff --git a/editor/editor_node.cpp b/editor/editor_node.cpp index e23afec5b8..754e8956a1 100644 --- a/editor/editor_node.cpp +++ b/editor/editor_node.cpp @@ -291,6 +291,8 @@ void EditorNode::_notification(int p_what) { get_tree()->get_root()->set_as_audio_listener_2d(false); get_tree()->set_auto_accept_quit(false); get_tree()->connect("files_dropped", this, "_dropped_files"); + + /* DO NOT LOAD SCENES HERE, WAIT FOR FILE SCANNING AND REIMPORT TO COMPLETE */ } if (p_what == NOTIFICATION_EXIT_TREE) { @@ -305,7 +307,8 @@ void EditorNode::_notification(int p_what) { _editor_select(EDITOR_3D); _update_debug_options(); - _load_docks(); + + /* DO NOT LOAD SCENES HERE, WAIT FOR FILE SCANNING AND REIMPORT TO COMPLETE */ } if (p_what == MainLoop::NOTIFICATION_WM_FOCUS_IN) { @@ -528,6 +531,8 @@ void EditorNode::_sources_changed(bool p_exist) { if (waiting_for_first_scan) { + _load_docks(); + if (defer_load_scene != "") { load_scene(defer_load_scene); @@ -1017,6 +1022,35 @@ bool EditorNode::_validate_scene_recursive(const String &p_filename, Node *p_nod return false; } +static bool _find_edited_resources(const Ref<Resource> &p_resource, Set<Ref<Resource> > &edited_resources) { + + if (p_resource->is_edited()) { + edited_resources.insert(p_resource); + return true; + } + + List<PropertyInfo> plist; + + p_resource->get_property_list(&plist); + + for (List<PropertyInfo>::Element *E = plist.front(); E; E = E->next()) { + if (E->get().type == Variant::OBJECT && E->get().usage & PROPERTY_USAGE_STORAGE && !(E->get().usage & PROPERTY_USAGE_RESOURCE_NOT_PERSISTENT)) { + RES res = p_resource->get(E->get().name); + if (res.is_null()) { + continue; + } + if (res->get_path().is_resource_file()) { //not a subresource, continue + continue; + } + if (_find_edited_resources(res, edited_resources)) { + return true; + } + } + } + + return false; +} + void EditorNode::_save_scene(String p_file, int idx) { Node *scene = editor_data.get_edited_scene_root(idx); @@ -1080,16 +1114,28 @@ void EditorNode::_save_scene(String p_file, int idx) { //_save_edited_subresources(scene, processed, flg); { //instead, just find globally unsaved subresources and save them + Set<Ref<Resource> > edited_subresources; + List<Ref<Resource> > cached; ResourceCache::get_cached_resources(&cached); for (List<Ref<Resource> >::Element *E = cached.front(); E; E = E->next()) { Ref<Resource> res = E->get(); - if (res->is_edited() && res->get_path().is_resource_file()) { + if (!res->get_path().is_resource_file()) + continue; + //not only check if this resourec is edited, check contained subresources too + if (_find_edited_resources(res, edited_subresources)) { ResourceSaver::save(res->get_path(), res, flg); - res->set_edited(false); } } + + // clear later, because user may have put the same subresource in two different resources, + // which will be shared until the next reload + + for (Set<Ref<Resource> >::Element *E = edited_subresources.front(); E; E = E->next()) { + Ref<Resource> res = E->get(); + res->set_edited(false); + } } editor_data.save_editor_external_data(); diff --git a/editor/editor_properties_array_dict.cpp b/editor/editor_properties_array_dict.cpp index 0851485208..0f6c6349ed 100644 --- a/editor/editor_properties_array_dict.cpp +++ b/editor/editor_properties_array_dict.cpp @@ -418,13 +418,14 @@ void EditorPropertyArray::_length_changed(double p_page) { return; Variant array = object->get_array(); + int previous_size = array.call("size"); + array.call("resize", int(p_page)); - emit_changed(get_edited_property(), array, "", false); if (array.get_type() == Variant::ARRAY) { if (subtype != Variant::NIL) { int size = array.call("size"); - for (int i = 0; i < size; i++) { + for (int i = previous_size; i < size; i++) { if (array.get(i).get_type() == Variant::NIL) { Variant::CallError ce; array.set(i, Variant::construct(subtype, NULL, 0, ce)); @@ -432,7 +433,16 @@ void EditorPropertyArray::_length_changed(double p_page) { } } array = array.call("duplicate"); //dupe, so undo/redo works better + } else { + int size = array.call("size"); + // Pool*Array don't initialize their elements, have to do it manually + for (int i = previous_size; i < size; i++) { + Variant::CallError ce; + array.set(i, Variant::construct(array.get(i).get_type(), NULL, 0, ce)); + } } + + emit_changed(get_edited_property(), array, "", false); object->set_array(array); update_property(); } diff --git a/editor/editor_run_native.cpp b/editor/editor_run_native.cpp index 887a102aa4..06cadca1c0 100644 --- a/editor/editor_run_native.cpp +++ b/editor/editor_run_native.cpp @@ -32,6 +32,7 @@ #include "editor_export.h" #include "editor_node.h" +#include "editor_scale.h" void EditorRunNative::_notification(int p_what) { @@ -49,7 +50,7 @@ void EditorRunNative::_notification(int p_what) { im->clear_mipmaps(); if (!im->empty()) { - im->resize(16, 16); + im->resize(16 * EDSCALE, 16 * EDSCALE); Ref<ImageTexture> small_icon; small_icon.instance(); small_icon->create_from_image(im, 0); diff --git a/editor/import/editor_import_plugin.cpp b/editor/import/editor_import_plugin.cpp index e365471733..98f4947c2d 100644 --- a/editor/import/editor_import_plugin.cpp +++ b/editor/import/editor_import_plugin.cpp @@ -130,7 +130,7 @@ bool EditorImportPlugin::get_option_visibility(const String &p_option, const Map return get_script_instance()->call("get_option_visibility", p_option, d); } -Error EditorImportPlugin::import(const String &p_source_file, const String &p_save_path, const Map<StringName, Variant> &p_options, List<String> *r_platform_variants, List<String> *r_gen_files) { +Error EditorImportPlugin::import(const String &p_source_file, const String &p_save_path, const Map<StringName, Variant> &p_options, List<String> *r_platform_variants, List<String> *r_gen_files, Variant *r_metadata) { ERR_FAIL_COND_V(!(get_script_instance() && get_script_instance()->has_method("import")), ERR_UNAVAILABLE); Dictionary options; diff --git a/editor/import/editor_import_plugin.h b/editor/import/editor_import_plugin.h index 607d99e6e2..d396dd6d5b 100644 --- a/editor/import/editor_import_plugin.h +++ b/editor/import/editor_import_plugin.h @@ -51,7 +51,7 @@ public: virtual int get_import_order() const; virtual void get_import_options(List<ImportOption> *r_options, int p_preset) const; virtual bool get_option_visibility(const String &p_option, const Map<StringName, Variant> &p_options) const; - virtual Error import(const String &p_source_file, const String &p_save_path, const Map<StringName, Variant> &p_options, List<String> *r_platform_variants, List<String> *r_gen_files); + virtual Error import(const String &p_source_file, const String &p_save_path, const Map<StringName, Variant> &p_options, List<String> *r_platform_variants, List<String> *r_gen_files, Variant *r_metadata = NULL); }; #endif //EDITOR_IMPORT_PLUGIN_H diff --git a/editor/import/resource_importer_bitmask.cpp b/editor/import/resource_importer_bitmask.cpp index b568cbda9b..18e53fc783 100644 --- a/editor/import/resource_importer_bitmask.cpp +++ b/editor/import/resource_importer_bitmask.cpp @@ -78,7 +78,7 @@ void ResourceImporterBitMap::get_import_options(List<ImportOption> *r_options, i r_options->push_back(ImportOption(PropertyInfo(Variant::REAL, "threshold", PROPERTY_HINT_RANGE, "0,1,0.01"), 0.5)); } -Error ResourceImporterBitMap::import(const String &p_source_file, const String &p_save_path, const Map<StringName, Variant> &p_options, List<String> *r_platform_variants, List<String> *r_gen_files) { +Error ResourceImporterBitMap::import(const String &p_source_file, const String &p_save_path, const Map<StringName, Variant> &p_options, List<String> *r_platform_variants, List<String> *r_gen_files, Variant *r_metadata) { int create_from = p_options["create_from"]; float threshold = p_options["threshold"]; diff --git a/editor/import/resource_importer_bitmask.h b/editor/import/resource_importer_bitmask.h index 7cfb0c4a98..166fa998e4 100644 --- a/editor/import/resource_importer_bitmask.h +++ b/editor/import/resource_importer_bitmask.h @@ -51,7 +51,7 @@ public: virtual void get_import_options(List<ImportOption> *r_options, int p_preset = 0) const; virtual bool get_option_visibility(const String &p_option, const Map<StringName, Variant> &p_options) const; - virtual Error import(const String &p_source_file, const String &p_save_path, const Map<StringName, Variant> &p_options, List<String> *r_platform_variants, List<String> *r_gen_files = NULL); + virtual Error import(const String &p_source_file, const String &p_save_path, const Map<StringName, Variant> &p_options, List<String> *r_platform_variants, List<String> *r_gen_files = NULL, Variant *r_metadata = NULL); ResourceImporterBitMap(); ~ResourceImporterBitMap(); diff --git a/editor/import/resource_importer_csv_translation.cpp b/editor/import/resource_importer_csv_translation.cpp index be5ce34c25..b4b3e0e551 100644 --- a/editor/import/resource_importer_csv_translation.cpp +++ b/editor/import/resource_importer_csv_translation.cpp @@ -77,7 +77,7 @@ void ResourceImporterCSVTranslation::get_import_options(List<ImportOption> *r_op r_options->push_back(ImportOption(PropertyInfo(Variant::INT, "delimiter", PROPERTY_HINT_ENUM, "Comma,Semicolon,Tab"), 0)); } -Error ResourceImporterCSVTranslation::import(const String &p_source_file, const String &p_save_path, const Map<StringName, Variant> &p_options, List<String> *r_platform_variants, List<String> *r_gen_files) { +Error ResourceImporterCSVTranslation::import(const String &p_source_file, const String &p_save_path, const Map<StringName, Variant> &p_options, List<String> *r_platform_variants, List<String> *r_gen_files, Variant *r_metadata) { bool compress = p_options["compress"]; diff --git a/editor/import/resource_importer_csv_translation.h b/editor/import/resource_importer_csv_translation.h index cf16826535..6785b68d87 100644 --- a/editor/import/resource_importer_csv_translation.h +++ b/editor/import/resource_importer_csv_translation.h @@ -48,7 +48,7 @@ public: virtual void get_import_options(List<ImportOption> *r_options, int p_preset = 0) const; virtual bool get_option_visibility(const String &p_option, const Map<StringName, Variant> &p_options) const; - virtual Error import(const String &p_source_file, const String &p_save_path, const Map<StringName, Variant> &p_options, List<String> *r_platform_variants, List<String> *r_gen_files = NULL); + virtual Error import(const String &p_source_file, const String &p_save_path, const Map<StringName, Variant> &p_options, List<String> *r_platform_variants, List<String> *r_gen_files = NULL, Variant *r_metadata = NULL); ResourceImporterCSVTranslation(); }; diff --git a/editor/import/resource_importer_image.cpp b/editor/import/resource_importer_image.cpp index c3421466f2..1259e81be7 100644 --- a/editor/import/resource_importer_image.cpp +++ b/editor/import/resource_importer_image.cpp @@ -74,7 +74,7 @@ String ResourceImporterImage::get_preset_name(int p_idx) const { void ResourceImporterImage::get_import_options(List<ImportOption> *r_options, int p_preset) const { } -Error ResourceImporterImage::import(const String &p_source_file, const String &p_save_path, const Map<StringName, Variant> &p_options, List<String> *r_platform_variants, List<String> *r_gen_files) { +Error ResourceImporterImage::import(const String &p_source_file, const String &p_save_path, const Map<StringName, Variant> &p_options, List<String> *r_platform_variants, List<String> *r_gen_files, Variant *r_metadata) { FileAccess *f = FileAccess::open(p_source_file, FileAccess::READ); if (!f) { diff --git a/editor/import/resource_importer_image.h b/editor/import/resource_importer_image.h index ffe05bdf58..3d5b99db2c 100644 --- a/editor/import/resource_importer_image.h +++ b/editor/import/resource_importer_image.h @@ -49,7 +49,7 @@ public: virtual void get_import_options(List<ImportOption> *r_options, int p_preset = 0) const; virtual bool get_option_visibility(const String &p_option, const Map<StringName, Variant> &p_options) const; - virtual Error import(const String &p_source_file, const String &p_save_path, const Map<StringName, Variant> &p_options, List<String> *r_platform_variants, List<String> *r_gen_files = NULL); + virtual Error import(const String &p_source_file, const String &p_save_path, const Map<StringName, Variant> &p_options, List<String> *r_platform_variants, List<String> *r_gen_files = NULL, Variant *r_metadata = NULL); ResourceImporterImage(); }; diff --git a/editor/import/resource_importer_layered_texture.cpp b/editor/import/resource_importer_layered_texture.cpp index e38265b619..7e3c4cecf4 100644 --- a/editor/import/resource_importer_layered_texture.cpp +++ b/editor/import/resource_importer_layered_texture.cpp @@ -191,7 +191,7 @@ void ResourceImporterLayeredTexture::_save_tex(const Vector<Ref<Image> > &p_imag memdelete(f); } -Error ResourceImporterLayeredTexture::import(const String &p_source_file, const String &p_save_path, const Map<StringName, Variant> &p_options, List<String> *r_platform_variants, List<String> *r_gen_files) { +Error ResourceImporterLayeredTexture::import(const String &p_source_file, const String &p_save_path, const Map<StringName, Variant> &p_options, List<String> *r_platform_variants, List<String> *r_gen_files, Variant *r_metadata) { int compress_mode = p_options["compress/mode"]; int no_bptc_if_rgb = p_options["compress/no_bptc_if_rgb"]; @@ -252,6 +252,7 @@ Error ResourceImporterLayeredTexture::import(const String &p_source_file, const } String extension = get_save_extension(); + Array formats_imported; if (compress_mode == COMPRESS_VIDEO_RAM) { //must import in all formats, in order of priority (so platform choses the best supported one. IE, etc2 over etc). @@ -270,6 +271,8 @@ Error ResourceImporterLayeredTexture::import(const String &p_source_file, const encode_bptc = false; } } + + formats_imported.push_back("bptc"); } if (encode_bptc) { @@ -284,23 +287,27 @@ Error ResourceImporterLayeredTexture::import(const String &p_source_file, const _save_tex(slices, p_save_path + ".s3tc." + extension, compress_mode, Image::COMPRESS_S3TC, mipmaps, tex_flags); r_platform_variants->push_back("s3tc"); ok_on_pc = true; + formats_imported.push_back("s3tc"); } if (ProjectSettings::get_singleton()->get("rendering/vram_compression/import_etc2")) { _save_tex(slices, p_save_path + ".etc2." + extension, compress_mode, Image::COMPRESS_ETC2, mipmaps, tex_flags); r_platform_variants->push_back("etc2"); + formats_imported.push_back("etc2"); } if (ProjectSettings::get_singleton()->get("rendering/vram_compression/import_etc")) { _save_tex(slices, p_save_path + ".etc." + extension, compress_mode, Image::COMPRESS_ETC, mipmaps, tex_flags); r_platform_variants->push_back("etc"); + formats_imported.push_back("etc"); } if (ProjectSettings::get_singleton()->get("rendering/vram_compression/import_pvrtc")) { _save_tex(slices, p_save_path + ".pvrtc." + extension, compress_mode, Image::COMPRESS_PVRTC4, mipmaps, tex_flags); r_platform_variants->push_back("pvrtc"); + formats_imported.push_back("pvrtc"); } if (!ok_on_pc) { @@ -311,9 +318,79 @@ Error ResourceImporterLayeredTexture::import(const String &p_source_file, const _save_tex(slices, p_save_path + "." + extension, compress_mode, Image::COMPRESS_S3TC /*this is ignored */, mipmaps, tex_flags); } + if (r_metadata) { + Dictionary metadata; + metadata["vram_texture"] = compress_mode == COMPRESS_VIDEO_RAM; + if (formats_imported.size()) { + metadata["imported_formats"] = formats_imported; + } + *r_metadata = metadata; + } + return OK; } +const char *ResourceImporterLayeredTexture::compression_formats[] = { + "bptc", + "s3tc", + "etc", + "etc2", + "pvrtc", + NULL +}; +String ResourceImporterLayeredTexture::get_import_settings_string() const { + + String s; + + int index = 0; + while (compression_formats[index]) { + String setting_path = "rendering/vram_compression/import_" + String(compression_formats[index]); + bool test = ProjectSettings::get_singleton()->get(setting_path); + if (test) { + s += String(compression_formats[index]); + } + index++; + } + + return s; +} + +bool ResourceImporterLayeredTexture::are_import_settings_valid(const String &p_path) const { + + //will become invalid if formats are missing to import + Dictionary metadata = ResourceFormatImporter::get_singleton()->get_resource_metadata(p_path); + + if (!metadata.has("vram_texture")) { + return false; + } + + bool vram = metadata["vram_texture"]; + if (!vram) { + return true; //do not care about non vram + } + + Vector<String> formats_imported; + if (metadata.has("imported_formats")) { + formats_imported = metadata["imported_formats"]; + } + + int index = 0; + bool valid = true; + while (compression_formats[index]) { + String setting_path = "rendering/vram_compression/import_" + String(compression_formats[index]); + bool test = ProjectSettings::get_singleton()->get(setting_path); + if (test) { + if (formats_imported.find(compression_formats[index]) == -1) { + valid = false; + break; + } + } + index++; + } + + return valid; +} + ResourceImporterLayeredTexture *ResourceImporterLayeredTexture::singleton = NULL; ResourceImporterLayeredTexture::ResourceImporterLayeredTexture() { diff --git a/editor/import/resource_importer_layered_texture.h b/editor/import/resource_importer_layered_texture.h index 6a616e09d6..6b393886b7 100644 --- a/editor/import/resource_importer_layered_texture.h +++ b/editor/import/resource_importer_layered_texture.h @@ -40,6 +40,7 @@ class ResourceImporterLayeredTexture : public ResourceImporter { GDCLASS(ResourceImporterLayeredTexture, ResourceImporter) bool is_3d; + static const char *compression_formats[]; protected: static void _texture_reimport_srgb(const Ref<StreamTexture> &p_tex); @@ -76,10 +77,13 @@ public: void _save_tex(const Vector<Ref<Image> > &p_images, const String &p_to_path, int p_compress_mode, Image::CompressMode p_vram_compression, bool p_mipmaps, int p_texture_flags); - virtual Error import(const String &p_source_file, const String &p_save_path, const Map<StringName, Variant> &p_options, List<String> *r_platform_variants, List<String> *r_gen_files = NULL); + virtual Error import(const String &p_source_file, const String &p_save_path, const Map<StringName, Variant> &p_options, List<String> *r_platform_variants, List<String> *r_gen_files = NULL, Variant *r_metadata = NULL); void update_imports(); + virtual bool are_import_settings_valid(const String &p_path) const; + virtual String get_import_settings_string() const; + void set_3d(bool p_3d) { is_3d = p_3d; } ResourceImporterLayeredTexture(); ~ResourceImporterLayeredTexture(); diff --git a/editor/import/resource_importer_obj.cpp b/editor/import/resource_importer_obj.cpp index 030b54a589..e950421476 100644 --- a/editor/import/resource_importer_obj.cpp +++ b/editor/import/resource_importer_obj.cpp @@ -499,7 +499,7 @@ bool ResourceImporterOBJ::get_option_visibility(const String &p_option, const Ma return true; } -Error ResourceImporterOBJ::import(const String &p_source_file, const String &p_save_path, const Map<StringName, Variant> &p_options, List<String> *r_platform_variants, List<String> *r_gen_files) { +Error ResourceImporterOBJ::import(const String &p_source_file, const String &p_save_path, const Map<StringName, Variant> &p_options, List<String> *r_platform_variants, List<String> *r_gen_files, Variant *r_metadata) { List<Ref<Mesh> > meshes; diff --git a/editor/import/resource_importer_obj.h b/editor/import/resource_importer_obj.h index effc56ad95..b2a53f582c 100644 --- a/editor/import/resource_importer_obj.h +++ b/editor/import/resource_importer_obj.h @@ -61,7 +61,7 @@ public: virtual void get_import_options(List<ImportOption> *r_options, int p_preset = 0) const; virtual bool get_option_visibility(const String &p_option, const Map<StringName, Variant> &p_options) const; - virtual Error import(const String &p_source_file, const String &p_save_path, const Map<StringName, Variant> &p_options, List<String> *r_platform_variants, List<String> *r_gen_files = NULL); + virtual Error import(const String &p_source_file, const String &p_save_path, const Map<StringName, Variant> &p_options, List<String> *r_platform_variants, List<String> *r_gen_files = NULL, Variant *r_metadata = NULL); ResourceImporterOBJ(); }; diff --git a/editor/import/resource_importer_scene.cpp b/editor/import/resource_importer_scene.cpp index ad436b2797..76552575da 100644 --- a/editor/import/resource_importer_scene.cpp +++ b/editor/import/resource_importer_scene.cpp @@ -1183,7 +1183,7 @@ Ref<Animation> ResourceImporterScene::import_animation_from_other_importer(Edito return importer->import_animation(p_path, p_flags, p_bake_fps); } -Error ResourceImporterScene::import(const String &p_source_file, const String &p_save_path, const Map<StringName, Variant> &p_options, List<String> *r_platform_variants, List<String> *r_gen_files) { +Error ResourceImporterScene::import(const String &p_source_file, const String &p_save_path, const Map<StringName, Variant> &p_options, List<String> *r_platform_variants, List<String> *r_gen_files, Variant *r_metadata) { String src_path = p_source_file; diff --git a/editor/import/resource_importer_scene.h b/editor/import/resource_importer_scene.h index 9d06b411d6..99f8b1a8e0 100644 --- a/editor/import/resource_importer_scene.h +++ b/editor/import/resource_importer_scene.h @@ -153,7 +153,7 @@ public: void _filter_tracks(Node *scene, const String &p_text); void _optimize_animations(Node *scene, float p_max_lin_error, float p_max_ang_error, float p_max_angle); - virtual Error import(const String &p_source_file, const String &p_save_path, const Map<StringName, Variant> &p_options, List<String> *r_platform_variants, List<String> *r_gen_files = NULL); + virtual Error import(const String &p_source_file, const String &p_save_path, const Map<StringName, Variant> &p_options, List<String> *r_platform_variants, List<String> *r_gen_files = NULL, Variant *r_metadata = NULL); Node *import_scene_from_other_importer(EditorSceneImporter *p_exception, const String &p_path, uint32_t p_flags, int p_bake_fps); Ref<Animation> import_animation_from_other_importer(EditorSceneImporter *p_exception, const String &p_path, uint32_t p_flags, int p_bake_fps); diff --git a/editor/import/resource_importer_texture.cpp b/editor/import/resource_importer_texture.cpp index 112e39cb4a..631b2359c5 100644 --- a/editor/import/resource_importer_texture.cpp +++ b/editor/import/resource_importer_texture.cpp @@ -235,7 +235,6 @@ void ResourceImporterTexture::_save_stex(const Ref<Image> &p_image, const String f->store_16(p_image->get_width()); f->store_16(next_power_of_2(p_image->get_height())); f->store_16(p_image->get_height()); - f->store_16(0); } else { f->store_16(p_image->get_width()); f->store_16(0); @@ -376,7 +375,7 @@ void ResourceImporterTexture::_save_stex(const Ref<Image> &p_image, const String memdelete(f); } -Error ResourceImporterTexture::import(const String &p_source_file, const String &p_save_path, const Map<StringName, Variant> &p_options, List<String> *r_platform_variants, List<String> *r_gen_files) { +Error ResourceImporterTexture::import(const String &p_source_file, const String &p_save_path, const Map<StringName, Variant> &p_options, List<String> *r_platform_variants, List<String> *r_gen_files, Variant *r_metadata) { int compress_mode = p_options["compress/mode"]; float lossy = p_options["compress/lossy_quality"]; @@ -402,6 +401,8 @@ Error ResourceImporterTexture::import(const String &p_source_file, const String if (err != OK) return err; + Array formats_imported; + int tex_flags = 0; if (repeat > 0) tex_flags |= Texture::FLAG_REPEAT; @@ -486,6 +487,8 @@ Error ResourceImporterTexture::import(const String &p_source_file, const String can_bptc = false; } } + + formats_imported.push_back("bptc"); } if (!can_bptc && is_hdr && !force_rgbe) { @@ -496,6 +499,7 @@ Error ResourceImporterTexture::import(const String &p_source_file, const String if (can_bptc || can_s3tc) { _save_stex(image, p_save_path + ".s3tc.stex", compress_mode, lossy, can_bptc ? Image::COMPRESS_BPTC : Image::COMPRESS_S3TC, mipmaps, tex_flags, stream, detect_3d, detect_srgb, force_rgbe, detect_normal, force_normal, false); r_platform_variants->push_back("s3tc"); + formats_imported.push_back("s3tc"); ok_on_pc = true; } @@ -503,17 +507,20 @@ Error ResourceImporterTexture::import(const String &p_source_file, const String _save_stex(image, p_save_path + ".etc2.stex", compress_mode, lossy, Image::COMPRESS_ETC2, mipmaps, tex_flags, stream, detect_3d, detect_srgb, force_rgbe, detect_normal, force_normal, false); r_platform_variants->push_back("etc2"); + formats_imported.push_back("etc2"); } if (ProjectSettings::get_singleton()->get("rendering/vram_compression/import_etc")) { _save_stex(image, p_save_path + ".etc.stex", compress_mode, lossy, Image::COMPRESS_ETC, mipmaps, tex_flags, stream, detect_3d, detect_srgb, force_rgbe, detect_normal, force_normal, true); r_platform_variants->push_back("etc"); + formats_imported.push_back("etc"); } if (ProjectSettings::get_singleton()->get("rendering/vram_compression/import_pvrtc")) { _save_stex(image, p_save_path + ".pvrtc.stex", compress_mode, lossy, Image::COMPRESS_PVRTC4, mipmaps, tex_flags, stream, detect_3d, detect_srgb, force_rgbe, detect_normal, force_normal, true); r_platform_variants->push_back("pvrtc"); + formats_imported.push_back("pvrtc"); } if (!ok_on_pc) { @@ -524,9 +531,78 @@ Error ResourceImporterTexture::import(const String &p_source_file, const String _save_stex(image, p_save_path + ".stex", compress_mode, lossy, Image::COMPRESS_S3TC /*this is ignored */, mipmaps, tex_flags, stream, detect_3d, detect_srgb, force_rgbe, detect_normal, force_normal, false); } + if (r_metadata) { + Dictionary metadata; + metadata["vram_texture"] = compress_mode == COMPRESS_VIDEO_RAM; + if (formats_imported.size()) { + metadata["imported_formats"] = formats_imported; + } + *r_metadata = metadata; + } return OK; } +const char *ResourceImporterTexture::compression_formats[] = { + "bptc", + "s3tc", + "etc", + "etc2", + "pvrtc", + NULL +}; +String ResourceImporterTexture::get_import_settings_string() const { + + String s; + + int index = 0; + while (compression_formats[index]) { + String setting_path = "rendering/vram_compression/import_" + String(compression_formats[index]); + bool test = ProjectSettings::get_singleton()->get(setting_path); + if (test) { + s += String(compression_formats[index]); + } + index++; + } + + return s; +} + +bool ResourceImporterTexture::are_import_settings_valid(const String &p_path) const { + + //will become invalid if formats are missing to import + Dictionary metadata = ResourceFormatImporter::get_singleton()->get_resource_metadata(p_path); + + if (!metadata.has("vram_texture")) { + return false; + } + + bool vram = metadata["vram_texture"]; + if (!vram) { + return true; //do not care about non vram + } + + Vector<String> formats_imported; + if (metadata.has("imported_formats")) { + formats_imported = metadata["imported_formats"]; + } + + int index = 0; + bool valid = true; + while (compression_formats[index]) { + String setting_path = "rendering/vram_compression/import_" + String(compression_formats[index]); + bool test = ProjectSettings::get_singleton()->get(setting_path); + if (test) { + if (formats_imported.find(compression_formats[index]) == -1) { + valid = false; + break; + } + } + index++; + } + + return valid; +} + ResourceImporterTexture *ResourceImporterTexture::singleton = NULL; ResourceImporterTexture::ResourceImporterTexture() { diff --git a/editor/import/resource_importer_texture.h b/editor/import/resource_importer_texture.h index 49a8b52b04..ef74e4e41e 100644 --- a/editor/import/resource_importer_texture.h +++ b/editor/import/resource_importer_texture.h @@ -54,6 +54,7 @@ protected: static void _texture_reimport_normal(const Ref<StreamTexture> &p_tex); static ResourceImporterTexture *singleton; + static const char *compression_formats[]; public: static ResourceImporterTexture *get_singleton() { return singleton; } @@ -85,10 +86,13 @@ public: void _save_stex(const Ref<Image> &p_image, const String &p_to_path, int p_compress_mode, float p_lossy_quality, Image::CompressMode p_vram_compression, bool p_mipmaps, int p_texture_flags, bool p_streamable, bool p_detect_3d, bool p_detect_srgb, bool p_force_rgbe, bool p_detect_normal, bool p_force_normal, bool p_force_po2_for_compressed); - virtual Error import(const String &p_source_file, const String &p_save_path, const Map<StringName, Variant> &p_options, List<String> *r_platform_variants, List<String> *r_gen_files = NULL); + virtual Error import(const String &p_source_file, const String &p_save_path, const Map<StringName, Variant> &p_options, List<String> *r_platform_variants, List<String> *r_gen_files = NULL, Variant *r_metadata = NULL); void update_imports(); + virtual bool are_import_settings_valid(const String &p_path) const; + virtual String get_import_settings_string() const; + ResourceImporterTexture(); ~ResourceImporterTexture(); }; diff --git a/editor/import/resource_importer_wav.cpp b/editor/import/resource_importer_wav.cpp index 76ab7a7037..857d8992fd 100644 --- a/editor/import/resource_importer_wav.cpp +++ b/editor/import/resource_importer_wav.cpp @@ -82,7 +82,7 @@ void ResourceImporterWAV::get_import_options(List<ImportOption> *r_options, int r_options->push_back(ImportOption(PropertyInfo(Variant::INT, "compress/mode", PROPERTY_HINT_ENUM, "Disabled,RAM (Ima-ADPCM)"), 0)); } -Error ResourceImporterWAV::import(const String &p_source_file, const String &p_save_path, const Map<StringName, Variant> &p_options, List<String> *r_platform_variants, List<String> *r_gen_files) { +Error ResourceImporterWAV::import(const String &p_source_file, const String &p_save_path, const Map<StringName, Variant> &p_options, List<String> *r_platform_variants, List<String> *r_gen_files, Variant *r_metadata) { /* STEP 1, READ WAVE FILE */ diff --git a/editor/import/resource_importer_wav.h b/editor/import/resource_importer_wav.h index 755dea3d84..f993f9e7bc 100644 --- a/editor/import/resource_importer_wav.h +++ b/editor/import/resource_importer_wav.h @@ -161,7 +161,7 @@ public: } } - virtual Error import(const String &p_source_file, const String &p_save_path, const Map<StringName, Variant> &p_options, List<String> *r_platform_variants, List<String> *r_gen_files = NULL); + virtual Error import(const String &p_source_file, const String &p_save_path, const Map<StringName, Variant> &p_options, List<String> *r_platform_variants, List<String> *r_gen_files = NULL, Variant *r_metadata = NULL); ResourceImporterWAV(); }; diff --git a/editor/plugins/editor_preview_plugins.cpp b/editor/plugins/editor_preview_plugins.cpp index 3cf46e5b91..58d7968723 100644 --- a/editor/plugins/editor_preview_plugins.cpp +++ b/editor/plugins/editor_preview_plugins.cpp @@ -92,7 +92,12 @@ Ref<Texture> EditorTexturePreviewPlugin::generate(const RES &p_from, const Size2 if (!tex.is_valid()) { return Ref<Texture>(); } + Ref<Image> atlas = tex->get_data(); + if (!atlas.is_valid()) { + return Ref<Texture>(); + } + img = atlas->get_rect(atex->get_region()); } else if (ltex.is_valid()) { img = ltex->to_image(); diff --git a/editor/plugins/tile_set_editor_plugin.cpp b/editor/plugins/tile_set_editor_plugin.cpp index 1bcb7513e0..5f4c4a610a 100644 --- a/editor/plugins/tile_set_editor_plugin.cpp +++ b/editor/plugins/tile_set_editor_plugin.cpp @@ -1425,6 +1425,7 @@ void TileSetEditor::_on_workspace_input(const Ref<InputEvent> &p_ie) { workspace->update(); } else { creating_shape = true; + edited_collision_shape = Ref<ConvexPolygonShape2D>(); current_shape.resize(0); current_shape.push_back(snap_point(pos)); workspace->update(); @@ -1444,6 +1445,7 @@ void TileSetEditor::_on_workspace_input(const Ref<InputEvent> &p_ie) { } else if (tools[SHAPE_NEW_RECTANGLE]->is_pressed()) { if (mb.is_valid()) { if (mb->is_pressed() && mb->get_button_index() == BUTTON_LEFT) { + edited_collision_shape = Ref<ConvexPolygonShape2D>(); current_shape.resize(0); current_shape.push_back(snap_point(shape_anchor)); current_shape.push_back(snap_point(shape_anchor + Vector2(current_tile_region.size.x, 0))); diff --git a/main/main.cpp b/main/main.cpp index 2ad59fd363..9b062d3951 100644 --- a/main/main.cpp +++ b/main/main.cpp @@ -757,7 +757,7 @@ Error Main::setup(const char *execpath, int argc, char *argv[], bool p_second_ph editor = false; #else String error_msg = "Error: Could not load game data at path '" + project_path + "'. Is the .pck file missing?\n"; - OS::get_singleton()->print(error_msg.ascii().get_data()); + OS::get_singleton()->print("%s", error_msg.ascii().get_data()); OS::get_singleton()->alert(error_msg); goto error; diff --git a/main/tests/test_string.cpp b/main/tests/test_string.cpp index edc4fb0c97..3465fd783e 100644 --- a/main/tests/test_string.cpp +++ b/main/tests/test_string.cpp @@ -457,7 +457,7 @@ bool test_27() { state = s.begins_with(sb) == tc[i].expected; } if (!state) { - OS::get_singleton()->print("\n\t Failure on:\n\t\tstring: ", tc[i].data, "\n\t\tbegin: ", tc[i].begin, "\n\t\texpected: ", tc[i].expected ? "true" : "false", "\n"); + OS::get_singleton()->print("\n\t Failure on:\n\t\tstring: %s\n\t\tbegin: %s\n\t\texpected: %s\n", tc[i].data, tc[i].begin, tc[i].expected ? "true" : "false"); break; } }; diff --git a/modules/gdnative/nativescript/nativescript.cpp b/modules/gdnative/nativescript/nativescript.cpp index 9fd0a2e8ec..c2b772df85 100644 --- a/modules/gdnative/nativescript/nativescript.cpp +++ b/modules/gdnative/nativescript/nativescript.cpp @@ -1599,18 +1599,20 @@ bool NativeScriptLanguage::handles_global_class_type(const String &p_type) const } String NativeScriptLanguage::get_global_class_name(const String &p_path, String *r_base_type, String *r_icon_path) const { - Ref<NativeScript> script = ResourceLoader::load(p_path, "NativeScript"); - if (script.is_valid()) { + if (!p_path.empty()) { + Ref<NativeScript> script = ResourceLoader::load(p_path, "NativeScript"); + if (script.is_valid()) { + if (r_base_type) + *r_base_type = script->get_instance_base_type(); + if (r_icon_path) + *r_icon_path = script->get_script_class_icon_path(); + return script->get_script_class_name(); + } if (r_base_type) - *r_base_type = script->get_instance_base_type(); + *r_base_type = String(); if (r_icon_path) - *r_icon_path = script->get_script_class_icon_path(); - return script->get_script_class_name(); + *r_icon_path = String(); } - if (r_base_type) - *r_base_type = String(); - if (r_icon_path) - *r_icon_path = String(); return String(); } diff --git a/modules/gdnative/videodecoder/video_stream_gdnative.cpp b/modules/gdnative/videodecoder/video_stream_gdnative.cpp index 8c2a84f60b..d1794b6c36 100644 --- a/modules/gdnative/videodecoder/video_stream_gdnative.cpp +++ b/modules/gdnative/videodecoder/video_stream_gdnative.cpp @@ -76,7 +76,7 @@ int64_t GDAPI godot_videodecoder_file_seek(void *ptr, int64_t pos, int whence) { } break; case SEEK_CUR: { // Just in case it doesn't exist - if (pos < 0 && -pos > file->get_position()) { + if (pos < 0 && (size_t)-pos > file->get_position()) { return -1; } pos = pos + static_cast<int>(file->get_position()); @@ -86,7 +86,7 @@ int64_t GDAPI godot_videodecoder_file_seek(void *ptr, int64_t pos, int whence) { } break; case SEEK_END: { // Just in case something goes wrong - if (-pos > len) { + if ((size_t)-pos > len) { return -1; } file->seek_end(pos); diff --git a/modules/gdscript/gdscript_parser.cpp b/modules/gdscript/gdscript_parser.cpp index adbd7e4e04..5ebf68177d 100644 --- a/modules/gdscript/gdscript_parser.cpp +++ b/modules/gdscript/gdscript_parser.cpp @@ -4691,6 +4691,16 @@ void GDScriptParser::_parse_class(ClassNode *p_class) { ConstantNode *cn = static_cast<ConstantNode *>(subexpr); if (cn->value.get_type() != Variant::NIL) { + if (member._export.type != Variant::NIL && cn->value.get_type() != member._export.type) { + if (Variant::can_convert(cn->value.get_type(), member._export.type)) { + Variant::CallError err; + const Variant *args = &cn->value; + cn->value = Variant::construct(member._export.type, &args, 1, err); + } else { + _set_error("Cannot convert the provided value to the export type."); + return; + } + } member.default_value = cn->value; } } diff --git a/modules/gdscript/gdscript_tokenizer.cpp b/modules/gdscript/gdscript_tokenizer.cpp index 480bf0fa3c..8b22d6f085 100644 --- a/modules/gdscript/gdscript_tokenizer.cpp +++ b/modules/gdscript/gdscript_tokenizer.cpp @@ -1417,7 +1417,7 @@ StringName GDScriptTokenizerBuffer::get_token_identifier(int p_offset) const { ERR_FAIL_INDEX_V(offset, tokens.size(), StringName()); uint32_t identifier = tokens[offset] >> TOKEN_BITS; - ERR_FAIL_UNSIGNED_INDEX_V(identifier, identifiers.size(), StringName()); + ERR_FAIL_UNSIGNED_INDEX_V(identifier, (uint32_t)identifiers.size(), StringName()); return identifiers[identifier]; } @@ -1473,7 +1473,7 @@ const Variant &GDScriptTokenizerBuffer::get_token_constant(int p_offset) const { int offset = token + p_offset; ERR_FAIL_INDEX_V(offset, tokens.size(), nil); uint32_t constant = tokens[offset] >> TOKEN_BITS; - ERR_FAIL_UNSIGNED_INDEX_V(constant, constants.size(), nil); + ERR_FAIL_UNSIGNED_INDEX_V(constant, (uint32_t)constants.size(), nil); return constants[constant]; } String GDScriptTokenizerBuffer::get_token_error(int p_offset) const { diff --git a/modules/mono/csharp_script.cpp b/modules/mono/csharp_script.cpp index 51615df64e..a7ac7f46c5 100644 --- a/modules/mono/csharp_script.cpp +++ b/modules/mono/csharp_script.cpp @@ -449,7 +449,7 @@ static String variant_type_to_managed_name(const String &p_var_type_name) { Variant::_RID }; - for (int i = 0; i < sizeof(var_types) / sizeof(Variant::Type); i++) { + for (unsigned int i = 0; i < sizeof(var_types) / sizeof(Variant::Type); i++) { if (p_var_type_name == Variant::get_type_name(var_types[i])) return p_var_type_name; } @@ -2172,7 +2172,7 @@ bool CSharpScript::_get_member_export(GDMonoClass *p_class, IMonoClassMember *p_ return false; } - if (val != i) { + if (val != (unsigned int)i) { uses_default_values = false; } diff --git a/modules/mono/editor/bindings_generator.cpp b/modules/mono/editor/bindings_generator.cpp index cffccd5cb5..890bea0d1d 100644 --- a/modules/mono/editor/bindings_generator.cpp +++ b/modules/mono/editor/bindings_generator.cpp @@ -703,7 +703,7 @@ Error BindingsGenerator::_generate_cs_type(const TypeInterface &itype, const Str List<InternalCall> &custom_icalls = itype.api_type == ClassDB::API_EDITOR ? editor_custom_icalls : core_custom_icalls; if (verbose_output) - OS::get_singleton()->print(String("Generating " + itype.proxy_name + ".cs...\n").utf8()); + OS::get_singleton()->print("Generating %s.cs...\n", itype.proxy_name.utf8().get_data()); String ctor_method(ICALL_PREFIX + itype.proxy_name + "_Ctor"); // Used only for derived types @@ -1280,7 +1280,7 @@ Error BindingsGenerator::generate_glue(const String &p_output_dir) { List<InternalCall> &custom_icalls = itype.api_type == ClassDB::API_EDITOR ? editor_custom_icalls : core_custom_icalls; - OS::get_singleton()->print(String("Generating " + itype.name + "...\n").utf8()); + OS::get_singleton()->print("Generating %s...\n", itype.name.utf8().get_data()); String ctor_method(ICALL_PREFIX + itype.proxy_name + "_Ctor"); // Used only for derived types diff --git a/modules/mono/editor/godotsharp_editor.cpp b/modules/mono/editor/godotsharp_editor.cpp index 17e29fba19..5b68810017 100644 --- a/modules/mono/editor/godotsharp_editor.cpp +++ b/modules/mono/editor/godotsharp_editor.cpp @@ -167,9 +167,6 @@ void GodotSharpEditor::_remove_create_sln_menu_option() { menu_popup->remove_item(menu_popup->get_item_index(MENU_CREATE_SLN)); - if (menu_popup->get_item_count() == 0) - menu_button->hide(); - bottom_panel_btn->show(); } @@ -277,43 +274,23 @@ Error GodotSharpEditor::open_in_external_editor(const Ref<Script> &p_script, int // TODO: Use initializer lists once C++11 is allowed - // Try with hint paths - static Vector<String> hint_paths; -#ifdef WINDOWS_ENABLED - if (hint_paths.empty()) { - hint_paths.push_back(OS::get_singleton()->get_environment("ProgramFiles") + "\\Microsoft VS Code\\Code.exe"); - if (sizeof(size_t) == 8) { - hint_paths.push_back(OS::get_singleton()->get_environment("ProgramFiles(x86)") + "\\Microsoft VS Code\\Code.exe"); - } + static Vector<String> vscode_names; + if (vscode_names.empty()) { + vscode_names.push_back("code"); + vscode_names.push_back("code-oss"); + vscode_names.push_back("vscode"); + vscode_names.push_back("vscode-oss"); + vscode_names.push_back("visual-studio-code"); + vscode_names.push_back("visual-studio-code-oss"); } -#endif - for (int i = 0; i < hint_paths.size(); i++) { - vscode_path = hint_paths[i]; - if (FileAccess::exists(vscode_path)) { + for (int i = 0; i < vscode_names.size(); i++) { + vscode_path = path_which(vscode_names[i]); + if (!vscode_path.empty()) { found = true; break; } } - if (!found) { - static Vector<String> vscode_names; - if (vscode_names.empty()) { - vscode_names.push_back("code"); - vscode_names.push_back("code-oss"); - vscode_names.push_back("vscode"); - vscode_names.push_back("vscode-oss"); - vscode_names.push_back("visual-studio-code"); - vscode_names.push_back("visual-studio-code-oss"); - } - for (int i = 0; i < vscode_names.size(); i++) { - vscode_path = path_which(vscode_names[i]); - if (!vscode_path.empty()) { - found = true; - break; - } - } - } - if (!found) vscode_path.clear(); // Not found, clear so next time the empty() check is enough } @@ -433,9 +410,12 @@ GodotSharpEditor::GodotSharpEditor(EditorNode *p_editor) { editor->add_child(memnew(MonoReloadNode)); - menu_button = memnew(MenuButton); - menu_button->set_text(TTR("Mono")); - menu_popup = menu_button->get_popup(); + menu_popup = memnew(PopupMenu); + menu_popup->hide(); + menu_popup->set_as_toplevel(true); + menu_popup->set_pass_on_modal_close_click(false); + + editor->add_tool_submenu_item("Mono", menu_popup); // TODO: Remove or edit this info dialog once Mono support is no longer in alpha { @@ -498,10 +478,12 @@ GodotSharpEditor::GodotSharpEditor(EditorNode *p_editor) { menu_popup->connect("id_pressed", this, "_menu_option_pressed"); - if (menu_popup->get_item_count() == 0) - menu_button->hide(); - - editor->get_menu_hb()->add_child(menu_button); + ToolButton *build_button = memnew(ToolButton); + build_button->set_text("Build"); + build_button->set_tooltip("Build solution"); + build_button->set_focus_mode(Control::FOCUS_NONE); + build_button->connect("pressed", MonoBottomPanel::get_singleton(), "_build_project_pressed"); + editor->get_menu_hb()->add_child(build_button); // External editor settings EditorSettings *ed_settings = EditorSettings::get_singleton(); diff --git a/modules/mono/editor/mono_bottom_panel.cpp b/modules/mono/editor/mono_bottom_panel.cpp index cc9822e319..21ce9ca5c4 100644 --- a/modules/mono/editor/mono_bottom_panel.cpp +++ b/modules/mono/editor/mono_bottom_panel.cpp @@ -125,9 +125,14 @@ void MonoBottomPanel::_build_tabs_item_selected(int p_idx) { void MonoBottomPanel::_build_tabs_nothing_selected() { - if (build_tabs->get_tab_count() != 0) // just in case + if (build_tabs->get_tab_count() != 0) { // just in case build_tabs->set_visible(false); + // This callback is called when clicking on the empty space of the list. + // ItemList won't deselect the items automatically, so we must do it ourselves. + build_tabs_list->unselect_all(); + } + warnings_btn->set_visible(false); errors_btn->set_visible(false); view_log_btn->set_visible(false); diff --git a/modules/mono/editor/mono_bottom_panel.h b/modules/mono/editor/mono_bottom_panel.h index d3109592a9..406e46f7ce 100644 --- a/modules/mono/editor/mono_bottom_panel.h +++ b/modules/mono/editor/mono_bottom_panel.h @@ -51,8 +51,8 @@ class MonoBottomPanel : public VBoxContainer { ItemList *build_tabs_list; TabContainer *build_tabs; - Button *warnings_btn; - Button *errors_btn; + ToolButton *warnings_btn; + ToolButton *errors_btn; Button *view_log_btn; void _update_build_tabs_list(); diff --git a/modules/mono/editor/script_class_parser.cpp b/modules/mono/editor/script_class_parser.cpp index 53a043b675..fcc58c22e8 100644 --- a/modules/mono/editor/script_class_parser.cpp +++ b/modules/mono/editor/script_class_parser.cpp @@ -567,7 +567,7 @@ Error ScriptClassParser::parse(const String &p_code) { if (full_name.length()) full_name += "."; full_name += class_decl.name; - OS::get_singleton()->print(String("Ignoring generic class declaration: " + class_decl.name).utf8()); + OS::get_singleton()->print("%s", String("Ignoring generic class declaration: " + class_decl.name).utf8().get_data()); } } } else if (tk == TK_IDENTIFIER && String(value) == "struct") { diff --git a/modules/mono/glue/collections_glue.cpp b/modules/mono/glue/collections_glue.cpp index 0e5747a014..d905810d66 100644 --- a/modules/mono/glue/collections_glue.cpp +++ b/modules/mono/glue/collections_glue.cpp @@ -86,7 +86,7 @@ bool godot_icall_Array_Contains(Array *ptr, MonoObject *item) { } void godot_icall_Array_CopyTo(Array *ptr, MonoArray *array, int array_index) { - int count = ptr->size(); + unsigned int count = ptr->size(); if (mono_array_length(array) < (array_index + count)) { MonoException *exc = mono_get_exception_argument("", "Destination array was not long enough. Check destIndex and length, and the array's lower bounds."); @@ -94,7 +94,7 @@ void godot_icall_Array_CopyTo(Array *ptr, MonoArray *array, int array_index) { return; } - for (int i = 0; i < count; i++) { + for (unsigned int i = 0; i < count; i++) { MonoObject *boxed = GDMonoMarshal::variant_to_mono_object(ptr->operator[](i)); mono_array_setref(array, array_index, boxed); array_index++; diff --git a/modules/mono/mono_gd/gd_mono.cpp b/modules/mono/mono_gd/gd_mono.cpp index bba8b1050f..dfabfddd64 100644 --- a/modules/mono/mono_gd/gd_mono.cpp +++ b/modules/mono/mono_gd/gd_mono.cpp @@ -91,7 +91,7 @@ static bool _wait_for_debugger_msecs(uint32_t p_msecs) { OS::get_singleton()->delay_usec((p_msecs < 25 ? p_msecs : 25) * 1000); - int tdiff = OS::get_singleton()->get_ticks_msec() - last_tick; + uint32_t tdiff = OS::get_singleton()->get_ticks_msec() - last_tick; if (tdiff > p_msecs) { p_msecs = 0; @@ -864,7 +864,7 @@ Error GDMono::reload_scripts_domain() { metadata_set_api_assembly_invalidated(APIAssembly::API_EDITOR, true); } - Error err = _unload_scripts_domain(); + err = _unload_scripts_domain(); if (err != OK) { WARN_PRINT("Mono: Failed to unload scripts domain"); } diff --git a/modules/pvr/texture_loader_pvr.cpp b/modules/pvr/texture_loader_pvr.cpp index 01e011e64c..82f323e8cf 100644 --- a/modules/pvr/texture_loader_pvr.cpp +++ b/modules/pvr/texture_loader_pvr.cpp @@ -216,7 +216,7 @@ static void _compress_pvrtc4(Image *p_img) { int ofs, size, w, h; img->get_mipmap_offset_size_and_dimensions(i, ofs, size, w, h); Javelin::RgbaBitmap bm(w, h); - for (unsigned j = 0; j < size / 4; j++) { + for (int j = 0; j < size / 4; j++) { Javelin::ColorRgba<unsigned char> *dp = bm.GetData(); /* red and Green colors are swapped. */ new (dp) Javelin::ColorRgba<unsigned char>(r[ofs + 4 * j + 2], r[ofs + 4 * j + 1], r[ofs + 4 * j], r[ofs + 4 * j + 3]); diff --git a/modules/stb_vorbis/resource_importer_ogg_vorbis.cpp b/modules/stb_vorbis/resource_importer_ogg_vorbis.cpp index 6e12bc9bf0..7254f57672 100644 --- a/modules/stb_vorbis/resource_importer_ogg_vorbis.cpp +++ b/modules/stb_vorbis/resource_importer_ogg_vorbis.cpp @@ -76,7 +76,7 @@ void ResourceImporterOGGVorbis::get_import_options(List<ImportOption> *r_options r_options->push_back(ImportOption(PropertyInfo(Variant::REAL, "loop_offset"), 0)); } -Error ResourceImporterOGGVorbis::import(const String &p_source_file, const String &p_save_path, const Map<StringName, Variant> &p_options, List<String> *r_platform_variants, List<String> *r_gen_files) { +Error ResourceImporterOGGVorbis::import(const String &p_source_file, const String &p_save_path, const Map<StringName, Variant> &p_options, List<String> *r_platform_variants, List<String> *r_gen_files, Variant *r_metadata) { bool loop = p_options["loop"]; float loop_offset = p_options["loop_offset"]; diff --git a/modules/stb_vorbis/resource_importer_ogg_vorbis.h b/modules/stb_vorbis/resource_importer_ogg_vorbis.h index f61fc91cda..d3d0574d56 100644 --- a/modules/stb_vorbis/resource_importer_ogg_vorbis.h +++ b/modules/stb_vorbis/resource_importer_ogg_vorbis.h @@ -49,7 +49,7 @@ public: virtual void get_import_options(List<ImportOption> *r_options, int p_preset = 0) const; virtual bool get_option_visibility(const String &p_option, const Map<StringName, Variant> &p_options) const; - virtual Error import(const String &p_source_file, const String &p_save_path, const Map<StringName, Variant> &p_options, List<String> *r_platform_variants, List<String> *r_gen_files = NULL); + virtual Error import(const String &p_source_file, const String &p_save_path, const Map<StringName, Variant> &p_options, List<String> *r_platform_variants, List<String> *r_gen_files = NULL, Variant *r_metadata = NULL); ResourceImporterOGGVorbis(); }; diff --git a/modules/visual_script/visual_script_property_selector.cpp b/modules/visual_script/visual_script_property_selector.cpp index fa7b13bf5b..ac5f73d113 100644 --- a/modules/visual_script/visual_script_property_selector.cpp +++ b/modules/visual_script/visual_script_property_selector.cpp @@ -421,7 +421,7 @@ void VisualScriptPropertySelector::get_visual_node_names(const String &root_filt } Vector<String> desc = path[path.size() - 1].replace("(", "( ").replace(")", " )").replace(",", ", ").split(" "); - for (size_t i = 0; i < desc.size(); i++) { + for (int i = 0; i < desc.size(); i++) { desc.write[i] = desc[i].capitalize(); if (desc[i].ends_with(",")) { desc.write[i] = desc[i].replace(",", ", "); diff --git a/modules/websocket/packet_buffer.h b/modules/websocket/packet_buffer.h index 5794288c2b..47786a87a6 100644 --- a/modules/websocket/packet_buffer.h +++ b/modules/websocket/packet_buffer.h @@ -50,7 +50,7 @@ public: Error write_packet(const uint8_t *p_payload, uint32_t p_size, const T *p_info) { #ifdef TOOLS_ENABLED // Verbose buffer warnings - if (p_payload && _payload.space_left() < p_size) { + if (p_payload && _payload.space_left() < (int32_t)p_size) { ERR_PRINT("Buffer payload full! Dropping data."); ERR_FAIL_V(ERR_OUT_OF_MEMORY); } @@ -83,8 +83,8 @@ public: ERR_FAIL_COND_V(_packets.data_left() < 1, ERR_UNAVAILABLE); _Packet p; _packets.read(&p, 1); - ERR_FAIL_COND_V(_payload.data_left() < p.size, ERR_BUG); - ERR_FAIL_COND_V(p_bytes < p.size, ERR_OUT_OF_MEMORY); + ERR_FAIL_COND_V(_payload.data_left() < (int)p.size, ERR_BUG); + ERR_FAIL_COND_V(p_bytes < (int)p.size, ERR_OUT_OF_MEMORY); r_read = p.size; copymem(r_info, &p.info, sizeof(T)); diff --git a/modules/websocket/websocket_multiplayer_peer.cpp b/modules/websocket/websocket_multiplayer_peer.cpp index a48738b6a4..6aab8a7e81 100644 --- a/modules/websocket/websocket_multiplayer_peer.cpp +++ b/modules/websocket/websocket_multiplayer_peer.cpp @@ -213,7 +213,7 @@ void WebSocketMultiplayerPeer::_send_add(int32_t p_peer_id) { _send_sys(get_peer(p_peer_id), SYS_ADD, 1); for (Map<int, Ref<WebSocketPeer> >::Element *E = _peer_map.front(); E; E = E->next()) { - uint32_t id = E->key(); + int32_t id = E->key(); if (p_peer_id == id) continue; // Skip the newwly added peer (already confirmed) @@ -226,7 +226,7 @@ void WebSocketMultiplayerPeer::_send_add(int32_t p_peer_id) { void WebSocketMultiplayerPeer::_send_del(int32_t p_peer_id) { for (Map<int, Ref<WebSocketPeer> >::Element *E = _peer_map.front(); E; E = E->next()) { - uint32_t id = E->key(); + int32_t id = E->key(); if (p_peer_id != id) _send_sys(get_peer(id), SYS_DEL, p_peer_id); } @@ -288,7 +288,7 @@ void WebSocketMultiplayerPeer::_process_multiplayer(Ref<WebSocketPeer> p_peer, u data_size = size - PROTO_SIZE; uint8_t type = 0; - int32_t from = 0; + uint32_t from = 0; int32_t to = 0; copymem(&type, in_buffer, 1); copymem(&from, &in_buffer[1], 4); diff --git a/modules/xatlas_unwrap/register_types.cpp b/modules/xatlas_unwrap/register_types.cpp index 840dd371ac..903b57f017 100644 --- a/modules/xatlas_unwrap/register_types.cpp +++ b/modules/xatlas_unwrap/register_types.cpp @@ -108,7 +108,7 @@ bool xatlas_mesh_lightmap_unwrap_callback(float p_texel_size, const float *p_ver float max_x = 0; float max_y = 0; - for (int i = 0; i < output->vertexCount; i++) { + for (uint32_t i = 0; i < output->vertexCount; i++) { (*r_vertex)[i] = output->vertexArray[i].xref; (*r_uv)[i * 2 + 0] = output->vertexArray[i].uv[0] / w; (*r_uv)[i * 2 + 1] = output->vertexArray[i].uv[1] / h; @@ -119,7 +119,7 @@ bool xatlas_mesh_lightmap_unwrap_callback(float p_texel_size, const float *p_ver printf("final texsize: %f,%f - max %f,%f\n", w, h, max_x, max_y); *r_vertex_count = output->vertexCount; - for (int i = 0; i < output->indexCount; i++) { + for (uint32_t i = 0; i < output->indexCount; i++) { (*r_index)[i] = output->indexArray[i]; } diff --git a/platform/android/dir_access_jandroid.cpp b/platform/android/dir_access_jandroid.cpp index 4b3d93aaa7..8c464465ca 100644 --- a/platform/android/dir_access_jandroid.cpp +++ b/platform/android/dir_access_jandroid.cpp @@ -31,6 +31,7 @@ #include "dir_access_jandroid.h" #include "core/print_string.h" #include "file_access_jandroid.h" +#include "string_android.h" #include "thread_jandroid.h" jobject DirAccessJAndroid::io = NULL; @@ -69,7 +70,7 @@ String DirAccessJAndroid::get_next() { if (!str) return ""; - String ret = String::utf8(env->GetStringUTFChars((jstring)str, NULL)); + String ret = jstring_to_string((jstring)str, env); env->DeleteLocalRef((jobject)str); return ret; } diff --git a/platform/android/export/export.cpp b/platform/android/export/export.cpp index 9d9270bdac..8d9d9c697e 100644 --- a/platform/android/export/export.cpp +++ b/platform/android/export/export.cpp @@ -1453,6 +1453,12 @@ public: err += TTR("Invalid package name:") + " " + pn_err + "\n"; } + String etc_error = test_etc2(); + if (etc_error != String()) { + valid = false; + err += etc_error; + } + r_error = err; return valid; } diff --git a/platform/android/java_class_wrapper.cpp b/platform/android/java_class_wrapper.cpp index 4be1106967..2bed1f0892 100644 --- a/platform/android/java_class_wrapper.cpp +++ b/platform/android/java_class_wrapper.cpp @@ -29,6 +29,7 @@ /*************************************************************************/ #include "java_class_wrapper.h" +#include "string_android.h" #include "thread_jandroid.h" bool JavaClass::_call_method(JavaObject *p_instance, const StringName &p_method, const Variant **p_args, int p_argcount, Variant::CallError &r_error, Variant &ret) { @@ -553,7 +554,7 @@ void JavaClassWrapper::_bind_methods() { bool JavaClassWrapper::_get_type_sig(JNIEnv *env, jobject obj, uint32_t &sig, String &strsig) { jstring name2 = (jstring)env->CallObjectMethod(obj, Class_getName); - String str_type = env->GetStringUTFChars(name2, NULL); + String str_type = jstring_to_string(name2, env); env->DeleteLocalRef(name2); uint32_t t = 0; @@ -697,7 +698,7 @@ bool JavaClass::_convert_object_to_variant(JNIEnv *env, jobject obj, Variant &va } break; case ARG_TYPE_STRING: { - var = String::utf8(env->GetStringUTFChars((jstring)obj, NULL)); + var = jstring_to_string((jstring)obj, env); return true; } break; case ARG_TYPE_CLASS: { @@ -1030,7 +1031,7 @@ bool JavaClass::_convert_object_to_variant(JNIEnv *env, jobject obj, Variant &va if (!o) ret.push_back(Variant()); else { - String val = String::utf8(env->GetStringUTFChars((jstring)o, NULL)); + String val = jstring_to_string((jstring)o, env); ret.push_back(val); } env->DeleteLocalRef(o); @@ -1075,7 +1076,7 @@ Ref<JavaClass> JavaClassWrapper::wrap(const String &p_class) { ERR_CONTINUE(!obj); jstring name = (jstring)env->CallObjectMethod(obj, getName); - String str_method = env->GetStringUTFChars(name, NULL); + String str_method = jstring_to_string(name, env); env->DeleteLocalRef(name); Vector<String> params; @@ -1204,7 +1205,7 @@ Ref<JavaClass> JavaClassWrapper::wrap(const String &p_class) { ERR_CONTINUE(!obj); jstring name = (jstring)env->CallObjectMethod(obj, Field_getName); - String str_field = env->GetStringUTFChars(name, NULL); + String str_field = jstring_to_string(name, env); env->DeleteLocalRef(name); int mods = env->CallIntMethod(obj, Field_getModifiers); if ((mods & 0x8) && (mods & 0x10) && (mods & 0x1)) { //static final public! diff --git a/platform/android/java_glue.cpp b/platform/android/java_glue.cpp index 885fb185a7..53c909da88 100644 --- a/platform/android/java_glue.cpp +++ b/platform/android/java_glue.cpp @@ -41,6 +41,7 @@ #include "main/input_default.h" #include "main/main.h" #include "os_android.h" +#include "string_android.h" #include "thread_jandroid.h" #include <unistd.h> @@ -223,7 +224,7 @@ String _get_class_name(JNIEnv *env, jclass cls, bool *array) { jboolean isarr = env->CallBooleanMethod(cls, isArray); (*array) = isarr ? true : false; } - String name = env->GetStringUTFChars(clsName, NULL); + String name = jstring_to_string(clsName, env); env->DeleteLocalRef(clsName); return name; @@ -241,7 +242,7 @@ Variant _jobject_to_variant(JNIEnv *env, jobject obj) { if (name == "java.lang.String") { - return String::utf8(env->GetStringUTFChars((jstring)obj, NULL)); + return jstring_to_string((jstring)obj, env); }; if (name == "[Ljava.lang.String;") { @@ -252,7 +253,7 @@ Variant _jobject_to_variant(JNIEnv *env, jobject obj) { for (int i = 0; i < stringCount; i++) { jstring string = (jstring)env->GetObjectArrayElement(arr, i); - sarr.push_back(String::utf8(env->GetStringUTFChars(string, NULL))); + sarr.push_back(jstring_to_string(string, env)); env->DeleteLocalRef(string); } @@ -487,7 +488,7 @@ public: case Variant::STRING: { jobject o = env->CallObjectMethodA(instance, E->get().method, v); - ret = String::utf8(env->GetStringUTFChars((jstring)o, NULL)); + ret = jstring_to_string((jstring)o, env); env->DeleteLocalRef(o); } break; case Variant::POOL_STRING_ARRAY: { @@ -634,20 +635,20 @@ static String _get_user_data_dir() { JNIEnv *env = ThreadAndroid::get_env(); jstring s = (jstring)env->CallObjectMethod(godot_io, _getDataDir); - return String(env->GetStringUTFChars(s, NULL)); + return jstring_to_string(s, env); } static String _get_locale() { JNIEnv *env = ThreadAndroid::get_env(); jstring s = (jstring)env->CallObjectMethod(godot_io, _getLocale); - return String(env->GetStringUTFChars(s, NULL)); + return jstring_to_string(s, env); } static String _get_clipboard() { JNIEnv *env = ThreadAndroid::get_env(); jstring s = (jstring)env->CallObjectMethod(_godot_instance, _getClipboard); - return String(env->GetStringUTFChars(s, NULL)); + return jstring_to_string(s, env); } static void _set_clipboard(const String &p_text) { @@ -661,7 +662,7 @@ static String _get_model() { JNIEnv *env = ThreadAndroid::get_env(); jstring s = (jstring)env->CallObjectMethod(godot_io, _getModel); - return String(env->GetStringUTFChars(s, NULL)); + return jstring_to_string(s, env); } static int _get_screen_dpi() { @@ -674,7 +675,7 @@ static String _get_unique_id() { JNIEnv *env = ThreadAndroid::get_env(); jstring s = (jstring)env->CallObjectMethod(godot_io, _getUniqueID); - return String(env->GetStringUTFChars(s, NULL)); + return jstring_to_string(s, env); } static void _show_vk(const String &p_existing) { @@ -694,7 +695,7 @@ static String _get_system_dir(int p_dir) { JNIEnv *env = ThreadAndroid::get_env(); jstring s = (jstring)env->CallObjectMethod(godot_io, _getSystemDir, p_dir); - return String(env->GetStringUTFChars(s, NULL)); + return jstring_to_string(s, env); } static int _get_gles_version_code() { @@ -891,12 +892,14 @@ JNIEXPORT void JNICALL Java_org_godotengine_godot_GodotLib_setup(JNIEnv *env, jo ThreadAndroid::setup_thread(); const char **cmdline = NULL; + jstring *j_cmdline = NULL; int cmdlen = 0; if (p_cmdline) { cmdlen = env->GetArrayLength(p_cmdline); if (cmdlen) { - cmdline = (const char **)malloc((env->GetArrayLength(p_cmdline) + 1) * sizeof(const char *)); + cmdline = (const char **)malloc((cmdlen + 1) * sizeof(const char *)); cmdline[cmdlen] = NULL; + j_cmdline = (jstring *)malloc(cmdlen * sizeof(jstring)); for (int i = 0; i < cmdlen; i++) { @@ -904,12 +907,19 @@ JNIEXPORT void JNICALL Java_org_godotengine_godot_GodotLib_setup(JNIEnv *env, jo const char *rawString = env->GetStringUTFChars(string, 0); cmdline[i] = rawString; + j_cmdline[i] = string; } } } Error err = Main::setup("apk", cmdlen, (char **)cmdline, false); if (cmdline) { + if (j_cmdline) { + for (int i = 0; i < cmdlen; ++i) { + env->ReleaseStringUTFChars(j_cmdline[i], cmdline[i]); + } + free(j_cmdline); + } free(cmdline); } @@ -1313,7 +1323,7 @@ JNIEXPORT void JNICALL Java_org_godotengine_godot_GodotLib_joyhat(JNIEnv *env, j JNIEXPORT void JNICALL Java_org_godotengine_godot_GodotLib_joyconnectionchanged(JNIEnv *env, jobject obj, jint p_device, jboolean p_connected, jstring p_name) { if (os_android) { - String name = env->GetStringUTFChars(p_name, NULL); + String name = jstring_to_string(p_name, env); os_android->joy_connection_changed(p_device, p_connected, name); } } @@ -1386,7 +1396,7 @@ JNIEXPORT void JNICALL Java_org_godotengine_godot_GodotLib_audio(JNIEnv *env, jo JNIEXPORT void JNICALL Java_org_godotengine_godot_GodotLib_singleton(JNIEnv *env, jobject obj, jstring name, jobject p_object) { - String singname = env->GetStringUTFChars(name, NULL); + String singname = jstring_to_string(name, env); JNISingleton *s = memnew(JNISingleton); s->set_instance(env->NewGlobalRef(p_object)); jni_singletons[singname] = s; @@ -1463,21 +1473,21 @@ static const char *get_jni_sig(const String &p_type) { JNIEXPORT jstring JNICALL Java_org_godotengine_godot_GodotLib_getGlobal(JNIEnv *env, jobject obj, jstring path) { - String js = env->GetStringUTFChars(path, NULL); + String js = jstring_to_string(path, env); return env->NewStringUTF(ProjectSettings::get_singleton()->get(js).operator String().utf8().get_data()); } JNIEXPORT void JNICALL Java_org_godotengine_godot_GodotLib_method(JNIEnv *env, jobject obj, jstring sname, jstring name, jstring ret, jobjectArray args) { - String singname = env->GetStringUTFChars(sname, NULL); + String singname = jstring_to_string(sname, env); ERR_FAIL_COND(!jni_singletons.has(singname)); JNISingleton *s = jni_singletons.get(singname); - String mname = env->GetStringUTFChars(name, NULL); - String retval = env->GetStringUTFChars(ret, NULL); + String mname = jstring_to_string(name, env); + String retval = jstring_to_string(ret, env); Vector<Variant::Type> types; String cs = "("; @@ -1486,9 +1496,9 @@ JNIEXPORT void JNICALL Java_org_godotengine_godot_GodotLib_method(JNIEnv *env, j for (int i = 0; i < stringCount; i++) { jstring string = (jstring)env->GetObjectArrayElement(args, i); - const char *rawString = env->GetStringUTFChars(string, 0); - types.push_back(get_jni_type(String(rawString))); - cs += get_jni_sig(String(rawString)); + const String rawString = jstring_to_string(string, env); + types.push_back(get_jni_type(rawString)); + cs += get_jni_sig(rawString); } cs += ")"; @@ -1511,7 +1521,7 @@ JNIEXPORT void JNICALL Java_org_godotengine_godot_GodotLib_callobject(JNIEnv *en int res = env->PushLocalFrame(16); ERR_FAIL_COND(res != 0); - String str_method = env->GetStringUTFChars(method, NULL); + String str_method = jstring_to_string(method, env); int count = env->GetArrayLength(params); Variant *vlist = (Variant *)alloca(sizeof(Variant) * count); @@ -1543,7 +1553,7 @@ JNIEXPORT void JNICALL Java_org_godotengine_godot_GodotLib_calldeferred(JNIEnv * int res = env->PushLocalFrame(16); ERR_FAIL_COND(res != 0); - String str_method = env->GetStringUTFChars(method, NULL); + String str_method = jstring_to_string(method, env); int count = env->GetArrayLength(params); Variant args[VARIANT_ARG_MAX]; diff --git a/platform/android/os_android.cpp b/platform/android/os_android.cpp index 3ba8468e0b..b86976843c 100644 --- a/platform/android/os_android.cpp +++ b/platform/android/os_android.cpp @@ -706,7 +706,7 @@ String OS_Android::get_joy_guid(int p_device) const { } bool OS_Android::_check_internal_feature_support(const String &p_feature) { - if (p_feature == "mobile" || p_feature == "etc" || p_feature == "etc2") { + if (p_feature == "mobile") { //TODO support etc2 only if GLES3 driver is selected return true; } diff --git a/platform/android/string_android.h b/platform/android/string_android.h new file mode 100644 index 0000000000..fe627a3e0c --- /dev/null +++ b/platform/android/string_android.h @@ -0,0 +1,58 @@ +/*************************************************************************/ +/* string_android.h */ +/*************************************************************************/ +/* This file is part of: */ +/* GODOT ENGINE */ +/* https://godotengine.org */ +/*************************************************************************/ +/* Copyright (c) 2007-2019 Juan Linietsky, Ariel Manzur. */ +/* Copyright (c) 2014-2019 Godot Engine contributors (cf. AUTHORS.md) */ +/* */ +/* Permission is hereby granted, free of charge, to any person obtaining */ +/* a copy of this software and associated documentation files (the */ +/* "Software"), to deal in the Software without restriction, including */ +/* without limitation the rights to use, copy, modify, merge, publish, */ +/* distribute, sublicense, and/or sell copies of the Software, and to */ +/* permit persons to whom the Software is furnished to do so, subject to */ +/* the following conditions: */ +/* */ +/* The above copyright notice and this permission notice shall be */ +/* included in all copies or substantial portions of the Software. */ +/* */ +/* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, */ +/* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF */ +/* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.*/ +/* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY */ +/* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, */ +/* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE */ +/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ +/*************************************************************************/ + +#ifndef STRING_ANDROID_H +#define STRING_ANDROID_H +#include "core/ustring.h" +#include "thread_jandroid.h" +#include <jni.h> + +/** + * Converts JNI jstring to Godot String. + * @param source Source JNI string. If null an empty string is returned. + * @param env JNI environment instance. If null obtained by ThreadAndroid::get_env(). + * @return Godot string instance. + */ +static inline String jstring_to_string(jstring source, JNIEnv *env = NULL) { + String result; + if (source) { + if (!env) { + env = ThreadAndroid::get_env(); + } + const char *const source_utf8 = env->GetStringUTFChars(source, NULL); + if (source_utf8) { + result.parse_utf8(source_utf8); + env->ReleaseStringUTFChars(source, source_utf8); + } + } + return result; +} + +#endif // STRING_ANDROID_H diff --git a/platform/haiku/os_haiku.cpp b/platform/haiku/os_haiku.cpp index a5b2e66a22..a6d5a00852 100644 --- a/platform/haiku/os_haiku.cpp +++ b/platform/haiku/os_haiku.cpp @@ -322,7 +322,7 @@ String OS_Haiku::get_executable_path() const { bool OS_Haiku::_check_internal_feature_support(const String &p_feature) { - return p_feature == "pc" || p_feature == "s3tc"; + return p_feature == "pc"; } String OS_Haiku::get_config_path() const { diff --git a/platform/iphone/app_delegate.mm b/platform/iphone/app_delegate.mm index bb0c11c767..d160553050 100644 --- a/platform/iphone/app_delegate.mm +++ b/platform/iphone/app_delegate.mm @@ -598,8 +598,10 @@ static int frame_count = 0; }; - (void)applicationDidReceiveMemoryWarning:(UIApplication *)application { - OS::get_singleton()->get_main_loop()->notification( - MainLoop::NOTIFICATION_OS_MEMORY_WARNING); + if (OS::get_singleton()->get_main_loop()) { + OS::get_singleton()->get_main_loop()->notification( + MainLoop::NOTIFICATION_OS_MEMORY_WARNING); + } }; - (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions { diff --git a/platform/iphone/export/export.cpp b/platform/iphone/export/export.cpp index d234ddac27..09ded63e96 100644 --- a/platform/iphone/export/export.cpp +++ b/platform/iphone/export/export.cpp @@ -1150,6 +1150,12 @@ bool EditorExportPlatformIOS::can_export(const Ref<EditorExportPreset> &p_preset } } + String etc_error = test_etc2(); + if (etc_error != String()) { + valid = false; + err += etc_error; + } + if (!err.empty()) r_error = err; diff --git a/platform/iphone/os_iphone.cpp b/platform/iphone/os_iphone.cpp index c939e234b9..b44b3127c7 100644 --- a/platform/iphone/os_iphone.cpp +++ b/platform/iphone/os_iphone.cpp @@ -587,7 +587,7 @@ void OSIPhone::native_video_stop() { bool OSIPhone::_check_internal_feature_support(const String &p_feature) { - return p_feature == "mobile" || p_feature == "etc" || p_feature == "pvrtc" || p_feature == "etc2"; + return p_feature == "mobile"; } // Initialization order between compilation units is not guaranteed, diff --git a/platform/javascript/export/export.cpp b/platform/javascript/export/export.cpp index 123c6ae645..2da6ea6670 100644 --- a/platform/javascript/export/export.cpp +++ b/platform/javascript/export/export.cpp @@ -167,6 +167,12 @@ bool EditorExportPlatformJavaScript::can_export(const Ref<EditorExportPreset> &p } } + String etc_error = test_etc2(); + if (etc_error != String()) { + valid = false; + err += etc_error; + } + if (!err.empty()) r_error = err; diff --git a/platform/javascript/os_javascript.cpp b/platform/javascript/os_javascript.cpp index 594c0a46cc..57ae1b6e26 100644 --- a/platform/javascript/os_javascript.cpp +++ b/platform/javascript/os_javascript.cpp @@ -1071,16 +1071,6 @@ bool OS_JavaScript::_check_internal_feature_support(const String &p_feature) { return true; #endif - EMSCRIPTEN_WEBGL_CONTEXT_HANDLE ctx = emscripten_webgl_get_current_context(); - // All extensions are already automatically enabled, this function allows - // checking WebGL extension support without inline JavaScript - if (p_feature == "s3tc") - return emscripten_webgl_enable_extension(ctx, "WEBGL_compressed_texture_s3tc_srgb"); - if (p_feature == "etc") - return emscripten_webgl_enable_extension(ctx, "WEBGL_compressed_texture_etc1"); - if (p_feature == "etc2") - return emscripten_webgl_enable_extension(ctx, "WEBGL_compressed_texture_etc"); - return false; } diff --git a/platform/osx/os_osx.mm b/platform/osx/os_osx.mm index 4e4d9c9eea..5206dc13b6 100644 --- a/platform/osx/os_osx.mm +++ b/platform/osx/os_osx.mm @@ -2812,7 +2812,7 @@ OS_OSX::OS_OSX() { } bool OS_OSX::_check_internal_feature_support(const String &p_feature) { - return p_feature == "pc" || p_feature == "s3tc"; + return p_feature == "pc"; } void OS_OSX::disable_crash_handler() { diff --git a/platform/uwp/os_uwp.cpp b/platform/uwp/os_uwp.cpp index 520e179611..637ef5aaef 100644 --- a/platform/uwp/os_uwp.cpp +++ b/platform/uwp/os_uwp.cpp @@ -889,7 +889,7 @@ String OS_UWP::get_user_data_dir() const { } bool OS_UWP::_check_internal_feature_support(const String &p_feature) { - return p_feature == "pc" || p_feature == "s3tc"; + return p_feature == "pc"; } OS::PowerState OS_UWP::get_power_state() { diff --git a/platform/windows/os_windows.cpp b/platform/windows/os_windows.cpp index 6e31f5b21d..61aeb3ec93 100644 --- a/platform/windows/os_windows.cpp +++ b/platform/windows/os_windows.cpp @@ -2976,7 +2976,7 @@ int OS_Windows::get_power_percent_left() { bool OS_Windows::_check_internal_feature_support(const String &p_feature) { - return p_feature == "pc" || p_feature == "s3tc" || p_feature == "bptc"; + return p_feature == "pc"; } void OS_Windows::disable_crash_handler() { diff --git a/platform/x11/detect_prime.cpp b/platform/x11/detect_prime.cpp index 04a825fac9..0fde2a0c04 100644 --- a/platform/x11/detect_prime.cpp +++ b/platform/x11/detect_prime.cpp @@ -180,8 +180,8 @@ int detect_prime() { const char *vendor = (const char *)glGetString(GL_VENDOR); const char *renderer = (const char *)glGetString(GL_RENDERER); - int vendor_len = strlen(vendor) + 1; - int renderer_len = strlen(renderer) + 1; + unsigned int vendor_len = strlen(vendor) + 1; + unsigned int renderer_len = strlen(renderer) + 1; if (vendor_len + renderer_len >= sizeof(string)) { renderer_len = 200 - vendor_len; diff --git a/platform/x11/os_x11.cpp b/platform/x11/os_x11.cpp index 879642d8f9..6a09c507c6 100644 --- a/platform/x11/os_x11.cpp +++ b/platform/x11/os_x11.cpp @@ -2593,7 +2593,7 @@ Error OS_X11::shell_open(String p_uri) { bool OS_X11::_check_internal_feature_support(const String &p_feature) { - return p_feature == "pc" || p_feature == "s3tc" || p_feature == "bptc"; + return p_feature == "pc"; } String OS_X11::get_config_path() const { diff --git a/scene/3d/audio_stream_player_3d.cpp b/scene/3d/audio_stream_player_3d.cpp index cf48a2503c..4b3934c4ea 100644 --- a/scene/3d/audio_stream_player_3d.cpp +++ b/scene/3d/audio_stream_player_3d.cpp @@ -860,7 +860,9 @@ void AudioStreamPlayer3D::set_doppler_tracking(DopplerTracking p_tracking) { if (doppler_tracking != DOPPLER_TRACKING_DISABLED) { set_notify_transform(true); velocity_tracker->set_track_physics_step(doppler_tracking == DOPPLER_TRACKING_PHYSICS_STEP); - velocity_tracker->reset(get_global_transform().origin); + if (is_inside_tree()) { + velocity_tracker->reset(get_global_transform().origin); + } } else { set_notify_transform(false); } diff --git a/scene/3d/camera.cpp b/scene/3d/camera.cpp index ed9374e422..368cebeeab 100644 --- a/scene/3d/camera.cpp +++ b/scene/3d/camera.cpp @@ -449,7 +449,9 @@ void Camera::set_doppler_tracking(DopplerTracking p_tracking) { doppler_tracking = p_tracking; if (p_tracking != DOPPLER_TRACKING_DISABLED) { velocity_tracker->set_track_physics_step(doppler_tracking == DOPPLER_TRACKING_PHYSICS_STEP); - velocity_tracker->reset(get_global_transform().origin); + if (is_inside_tree()) { + velocity_tracker->reset(get_global_transform().origin); + } } _update_camera_mode(); } diff --git a/scene/3d/voxel_light_baker.cpp b/scene/3d/voxel_light_baker.cpp index 9250ca7937..750ed97ae6 100644 --- a/scene/3d/voxel_light_baker.cpp +++ b/scene/3d/voxel_light_baker.cpp @@ -887,7 +887,7 @@ void VoxelLightBaker::plot_light_directional(const Vector3 &p_direction, const C distance -= distance_adv; } - if (result == idx) { + if (result == (uint32_t)idx) { //cell hit itself! hooray! Vector3 normal(cells[idx].normal[0], cells[idx].normal[1], cells[idx].normal[2]); @@ -1018,7 +1018,7 @@ void VoxelLightBaker::plot_light_omni(const Vector3 &p_pos, const Color &p_color distance -= distance_adv; } - if (result == idx) { + if (result == (uint32_t)idx) { //cell hit itself! hooray! if (normal == Vector3()) { @@ -1152,7 +1152,7 @@ void VoxelLightBaker::plot_light_spot(const Vector3 &p_pos, const Vector3 &p_axi distance -= distance_adv; } - if (result == idx) { + if (result == (uint32_t)idx) { //cell hit itself! hooray! if (normal == Vector3()) { @@ -2252,7 +2252,7 @@ void VoxelLightBaker::_debug_mesh(int p_idx, int p_level, const AABB &p_aabb, Re uint32_t child = bake_cells[p_idx].children[i]; - if (child == CHILD_EMPTY || child >= max_original_cells) + if (child == CHILD_EMPTY || child >= (uint32_t)max_original_cells) continue; AABB aabb = p_aabb; diff --git a/scene/resources/bit_map.cpp b/scene/resources/bit_map.cpp index 8263096c8f..d2e4d28b44 100644 --- a/scene/resources/bit_map.cpp +++ b/scene/resources/bit_map.cpp @@ -332,7 +332,7 @@ Vector<Vector2> BitMap::_march_square(const Rect2i &rect, const Point2i &start) prevx = stepx; prevy = stepy; - ERR_FAIL_COND_V(count > width * height, _points); + ERR_FAIL_COND_V((int)count > width * height, _points); } while (curx != startx || cury != starty); return _points; } diff --git a/scene/resources/resource_format_text.cpp b/scene/resources/resource_format_text.cpp index 44899bf9fc..210fbe9f20 100644 --- a/scene/resources/resource_format_text.cpp +++ b/scene/resources/resource_format_text.cpp @@ -1389,7 +1389,7 @@ void ResourceFormatSaverTextInstance::_find_resources(const Variant &p_variant, if (!p_main && (!bundle_resources) && res->get_path().length() && res->get_path().find("::") == -1) { if (res->get_path() == local_path) { - ERR_PRINTS("Circular reference to resource being saved found: '"+local_path+"' will be null next time it's loaded."); + ERR_PRINTS("Circular reference to resource being saved found: '" + local_path + "' will be null next time it's loaded."); return; } int index = external_resources.size(); diff --git a/scene/resources/texture.cpp b/scene/resources/texture.cpp index 430db59e44..08b2a05d43 100644 --- a/scene/resources/texture.cpp +++ b/scene/resources/texture.cpp @@ -426,6 +426,8 @@ ImageTexture::ImageTexture() { texture = VisualServer::get_singleton()->texture_create(); storage = STORAGE_RAW; lossy_storage_quality = 0.7; + image_stored = false; + format = Image::FORMAT_L8; } ImageTexture::~ImageTexture() { @@ -1514,6 +1516,7 @@ CubeMap::CubeMap() { cubemap = VisualServer::get_singleton()->texture_create(); storage = STORAGE_RAW; lossy_storage_quality = 0.7; + format = Image::FORMAT_BPTC_RGBA; } CubeMap::~CubeMap() { diff --git a/servers/audio/audio_stream.cpp b/servers/audio/audio_stream.cpp index bd98619e92..12ee98595d 100644 --- a/servers/audio/audio_stream.cpp +++ b/servers/audio/audio_stream.cpp @@ -138,7 +138,7 @@ void AudioStreamPlaybackMicrophone::_mix_internal(AudioFrame *p_buffer, int p_fr Vector<int32_t> buf = AudioDriver::get_singleton()->get_input_buffer(); unsigned int input_size = AudioDriver::get_singleton()->get_input_size(); int mix_rate = AudioDriver::get_singleton()->get_mix_rate(); - int playback_delay = MIN(((50 * mix_rate) / 1000) * 2, buf.size() >> 1); + unsigned int playback_delay = MIN(((50 * mix_rate) / 1000) * 2, buf.size() >> 1); #ifdef DEBUG_ENABLED unsigned int input_position = AudioDriver::get_singleton()->get_input_position(); #endif @@ -152,11 +152,11 @@ void AudioStreamPlaybackMicrophone::_mix_internal(AudioFrame *p_buffer, int p_fr for (int i = 0; i < p_frames; i++) { if (input_size > input_ofs) { float l = (buf[input_ofs++] >> 16) / 32768.f; - if (input_ofs >= buf.size()) { + if ((int)input_ofs >= buf.size()) { input_ofs = 0; } float r = (buf[input_ofs++] >> 16) / 32768.f; - if (input_ofs >= buf.size()) { + if ((int)input_ofs >= buf.size()) { input_ofs = 0; } @@ -168,7 +168,7 @@ void AudioStreamPlaybackMicrophone::_mix_internal(AudioFrame *p_buffer, int p_fr } #ifdef DEBUG_ENABLED - if (input_ofs > input_position && (input_ofs - input_position) < (p_frames * 2)) { + if (input_ofs > input_position && (int)(input_ofs - input_position) < (p_frames * 2)) { print_verbose(String(get_class_name()) + " buffer underrun: input_position=" + itos(input_position) + " input_ofs=" + itos(input_ofs) + " input_size=" + itos(input_size)); } #endif diff --git a/servers/audio_server.cpp b/servers/audio_server.cpp index a2e5813a4f..df6218ac79 100644 --- a/servers/audio_server.cpp +++ b/servers/audio_server.cpp @@ -91,10 +91,10 @@ void AudioDriver::input_buffer_init(int driver_buffer_frames) { void AudioDriver::input_buffer_write(int32_t sample) { input_buffer.write[input_position++] = sample; - if (input_position >= input_buffer.size()) { + if ((int)input_position >= input_buffer.size()) { input_position = 0; } - if (input_size < input_buffer.size()) { + if ((int)input_size < input_buffer.size()) { input_size++; } } diff --git a/servers/register_server_types.cpp b/servers/register_server_types.cpp index 4e167be300..922f017d0b 100644 --- a/servers/register_server_types.cpp +++ b/servers/register_server_types.cpp @@ -88,8 +88,21 @@ Physics2DServer *_createGodotPhysics2DCallback() { return Physics2DServerWrapMT::init_server<Physics2DServerSW>(); } +static bool has_server_feature_callback(const String &p_feature) { + + if (VisualServer::get_singleton()) { + if (VisualServer::get_singleton()->has_os_feature(p_feature)) { + return true; + } + } + + return false; +} + void register_server_types() { + OS::get_singleton()->set_has_server_feature_callback(has_server_feature_callback); + ClassDB::register_virtual_class<VisualServer>(); ClassDB::register_class<AudioServer>(); ClassDB::register_virtual_class<PhysicsServer>(); diff --git a/servers/visual/shader_language.cpp b/servers/visual/shader_language.cpp index 9a0218d5d0..1f9d263354 100644 --- a/servers/visual/shader_language.cpp +++ b/servers/visual/shader_language.cpp @@ -2074,7 +2074,9 @@ bool ShaderLanguage::_validate_function_call(BlockNode *p_block, OperatorNode *p bool fail = false; for (int i = 0; i < argcount; i++) { - if (args[i] != builtin_func_defs[idx].args[i]) { + if (get_scalar_type(args[i]) == args[i] && p_func->arguments[i + 1]->type == Node::TYPE_CONSTANT && convert_constant(static_cast<ConstantNode *>(p_func->arguments[i + 1]), builtin_func_defs[idx].args[i])) { + //all good, but needs implicit conversion later + } else if (args[i] != builtin_func_defs[idx].args[i]) { fail = true; break; } @@ -2119,6 +2121,24 @@ bool ShaderLanguage::_validate_function_call(BlockNode *p_block, OperatorNode *p outarg_idx++; } + //implicitly convert values if possible + for (int i = 0; i < argcount; i++) { + + if (get_scalar_type(args[i]) != args[i] || args[i] == builtin_func_defs[idx].args[i] || p_func->arguments[i + 1]->type != Node::TYPE_CONSTANT) { + //can't do implicit conversion here + continue; + } + + //this is an implicit conversion + ConstantNode *constant = static_cast<ConstantNode *>(p_func->arguments[i + 1]); + ConstantNode *conversion = alloc_node<ConstantNode>(); + + conversion->datatype = builtin_func_defs[idx].args[i]; + conversion->values.resize(1); + + convert_constant(constant, builtin_func_defs[idx].args[i], conversion->values.ptrw()); + p_func->arguments.write[i + 1] = conversion; + } if (r_ret_type) *r_ret_type = builtin_func_defs[idx].rettype; @@ -2184,13 +2204,35 @@ bool ShaderLanguage::_validate_function_call(BlockNode *p_block, OperatorNode *p for (int j = 0; j < args.size(); j++) { - if (args[j] != pfunc->arguments[j].type) { + if (get_scalar_type(args[j]) == args[j] && p_func->arguments[j + 1]->type == Node::TYPE_CONSTANT && convert_constant(static_cast<ConstantNode *>(p_func->arguments[j + 1]), pfunc->arguments[j].type)) { + //all good, but it needs implicit conversion later + } else if (args[j] != pfunc->arguments[j].type) { fail = true; break; } } if (!fail) { + + //implicitly convert values if possible + for (int k = 0; k < args.size(); k++) { + + if (get_scalar_type(args[k]) != args[k] || args[k] == pfunc->arguments[k].type || p_func->arguments[k + 1]->type != Node::TYPE_CONSTANT) { + //can't do implicit conversion here + continue; + } + + //this is an implicit conversion + ConstantNode *constant = static_cast<ConstantNode *>(p_func->arguments[k + 1]); + ConstantNode *conversion = alloc_node<ConstantNode>(); + + conversion->datatype = pfunc->arguments[k].type; + conversion->values.resize(1); + + convert_constant(constant, pfunc->arguments[k].type, conversion->values.ptrw()); + p_func->arguments.write[k + 1] = conversion; + } + if (r_ret_type) *r_ret_type = pfunc->return_type; return true; diff --git a/servers/visual_server.cpp b/servers/visual_server.cpp index c61e2b99e2..3dbe516f74 100644 --- a/servers/visual_server.cpp +++ b/servers/visual_server.cpp @@ -2368,11 +2368,11 @@ VisualServer::VisualServer() { //ERR_FAIL_COND(singleton); singleton = this; - GLOBAL_DEF("rendering/vram_compression/import_bptc", false); - GLOBAL_DEF("rendering/vram_compression/import_s3tc", true); - GLOBAL_DEF("rendering/vram_compression/import_etc", false); - GLOBAL_DEF("rendering/vram_compression/import_etc2", true); - GLOBAL_DEF("rendering/vram_compression/import_pvrtc", false); + GLOBAL_DEF_RST("rendering/vram_compression/import_bptc", false); + GLOBAL_DEF_RST("rendering/vram_compression/import_s3tc", true); + GLOBAL_DEF_RST("rendering/vram_compression/import_etc", false); + GLOBAL_DEF_RST("rendering/vram_compression/import_etc2", true); + GLOBAL_DEF_RST("rendering/vram_compression/import_pvrtc", false); GLOBAL_DEF("rendering/quality/directional_shadow/size", 4096); GLOBAL_DEF("rendering/quality/directional_shadow/size.mobile", 2048); |