diff options
58 files changed, 1977 insertions, 234 deletions
diff --git a/core/io/packet_peer.cpp b/core/io/packet_peer.cpp index a3d33593dd..40082cc481 100644 --- a/core/io/packet_peer.cpp +++ b/core/io/packet_peer.cpp @@ -139,6 +139,8 @@ void PacketPeerStream::_set_stream_peer(REF p_peer) { void PacketPeerStream::_bind_methods() { ClassDB::bind_method(D_METHOD("set_stream_peer", "peer:StreamPeer"), &PacketPeerStream::_set_stream_peer); + ClassDB::bind_method(D_METHOD("set_input_buffer_max_size", "max_size_bytes"), &PacketPeerStream::set_input_buffer_max_size); + ClassDB::bind_method(D_METHOD("set_output_buffer_max_size", "max_size_bytes"), &PacketPeerStream::set_output_buffer_max_size); } Error PacketPeerStream::_poll_buffer() const { @@ -146,13 +148,13 @@ Error PacketPeerStream::_poll_buffer() const { ERR_FAIL_COND_V(peer.is_null(), ERR_UNCONFIGURED); int read = 0; - Error err = peer->get_partial_data(&temp_buffer[0], ring_buffer.space_left(), read); + Error err = peer->get_partial_data(&input_buffer[0], ring_buffer.space_left(), read); if (err) return err; if (read == 0) return OK; - int w = ring_buffer.write(&temp_buffer[0], read); + int w = ring_buffer.write(&input_buffer[0], read); ERR_FAIL_COND_V(w != read, ERR_BUG); return OK; @@ -198,9 +200,9 @@ Error PacketPeerStream::get_packet(const uint8_t **r_buffer, int &r_buffer_size) ERR_FAIL_COND_V(remaining < (int)len, ERR_UNAVAILABLE); ring_buffer.read(lbuf, 4); //get rid of first 4 bytes - ring_buffer.read(&temp_buffer[0], len); // read packet + ring_buffer.read(&input_buffer[0], len); // read packet - *r_buffer = &temp_buffer[0]; + *r_buffer = &input_buffer[0]; r_buffer_size = len; return OK; } @@ -217,19 +219,19 @@ Error PacketPeerStream::put_packet(const uint8_t *p_buffer, int p_buffer_size) { return OK; ERR_FAIL_COND_V(p_buffer_size < 0, ERR_INVALID_PARAMETER); - ERR_FAIL_COND_V(p_buffer_size + 4 > temp_buffer.size(), ERR_INVALID_PARAMETER); + ERR_FAIL_COND_V(p_buffer_size + 4 > output_buffer.size(), ERR_INVALID_PARAMETER); - encode_uint32(p_buffer_size, &temp_buffer[0]); - uint8_t *dst = &temp_buffer[4]; + encode_uint32(p_buffer_size, &output_buffer[0]); + uint8_t *dst = &output_buffer[4]; for (int i = 0; i < p_buffer_size; i++) dst[i] = p_buffer[i]; - return peer->put_data(&temp_buffer[0], p_buffer_size + 4); + return peer->put_data(&output_buffer[0], p_buffer_size + 4); } int PacketPeerStream::get_max_packet_size() const { - return temp_buffer.size(); + return output_buffer.size(); } void PacketPeerStream::set_stream_peer(const Ref<StreamPeer> &p_peer) { @@ -249,7 +251,12 @@ void PacketPeerStream::set_input_buffer_max_size(int p_max_size) { ERR_EXPLAIN("Buffer in use, resizing would cause loss of data"); ERR_FAIL_COND(ring_buffer.data_left()); ring_buffer.resize(nearest_shift(p_max_size + 4)); - temp_buffer.resize(nearest_power_of_2(p_max_size + 4)); + input_buffer.resize(nearest_power_of_2(p_max_size + 4)); +} + +void PacketPeerStream::set_output_buffer_max_size(int p_max_size) { + + output_buffer.resize(nearest_power_of_2(p_max_size + 4)); } PacketPeerStream::PacketPeerStream() { @@ -257,5 +264,6 @@ PacketPeerStream::PacketPeerStream() { int rbsize = GLOBAL_GET("network/limits/packet_peer_stream/max_buffer_po2"); ring_buffer.resize(rbsize); - temp_buffer.resize(1 << rbsize); + input_buffer.resize(1 << rbsize); + output_buffer.resize(1 << rbsize); } diff --git a/core/io/packet_peer.h b/core/io/packet_peer.h index 95806aa511..ed6b252d80 100644 --- a/core/io/packet_peer.h +++ b/core/io/packet_peer.h @@ -75,7 +75,8 @@ class PacketPeerStream : public PacketPeer { mutable Ref<StreamPeer> peer; mutable RingBuffer<uint8_t> ring_buffer; - mutable Vector<uint8_t> temp_buffer; + mutable Vector<uint8_t> input_buffer; + mutable Vector<uint8_t> output_buffer; Error _poll_buffer() const; @@ -92,6 +93,7 @@ public: void set_stream_peer(const Ref<StreamPeer> &p_peer); void set_input_buffer_max_size(int p_max_size); + void set_output_buffer_max_size(int p_max_size); PacketPeerStream(); }; diff --git a/core/script_debugger_remote.cpp b/core/script_debugger_remote.cpp index fdde08bb32..6f12338f66 100644 --- a/core/script_debugger_remote.cpp +++ b/core/script_debugger_remote.cpp @@ -945,6 +945,7 @@ ScriptDebuggerRemote::ScriptDebuggerRemote() { tcp_client = StreamPeerTCP::create_ref(); packet_peer_stream = Ref<PacketPeerStream>(memnew(PacketPeerStream)); packet_peer_stream->set_stream_peer(tcp_client); + packet_peer_stream->set_output_buffer_max_size(1024 * 1024 * 8); //8mb should be way more than enough mutex = Mutex::create(); locking = false; diff --git a/drivers/gles3/rasterizer_canvas_gles3.cpp b/drivers/gles3/rasterizer_canvas_gles3.cpp index 56d9f2cc47..e6ffa39197 100644 --- a/drivers/gles3/rasterizer_canvas_gles3.cpp +++ b/drivers/gles3/rasterizer_canvas_gles3.cpp @@ -941,6 +941,8 @@ void RasterizerGLES2::_canvas_item_setup_shader_params(ShaderMaterial *material, void RasterizerCanvasGLES3::_copy_texscreen(const Rect2 &p_rect) { + glDisable(GL_BLEND); + state.canvas_texscreen_used = true; //blur diffuse into effect mipmaps using separatable convolution //storage->shaders.copy.set_conditional(CopyShaderGLES3::GAUSSIAN_HORIZONTAL,true); @@ -1003,12 +1005,16 @@ void RasterizerCanvasGLES3::_copy_texscreen(const Rect2 &p_rect) { glBindFramebuffer(GL_FRAMEBUFFER, storage->frame.current_rt->fbo); //back to front glViewport(0, 0, storage->frame.current_rt->width, storage->frame.current_rt->height); + state.canvas_shader.bind(); //back to canvas + _bind_canvas_texture(state.current_tex, state.current_normal); if (state.using_texture_rect) { state.using_texture_rect = false; _set_texture_rect_mode(state.using_texture_rect, state.using_ninepatch); } + + glEnable(GL_BLEND); } void RasterizerCanvasGLES3::canvas_render_items(Item *p_item_list, int p_z, const Color &p_modulate, Light *p_light) { @@ -1595,6 +1601,67 @@ void RasterizerCanvasGLES3::draw_generic_textured_rect(const Rect2 &p_rect, cons glDrawArrays(GL_TRIANGLE_FAN, 0, 4); } +void RasterizerCanvasGLES3::draw_window_margins(int *black_margin, RID *black_image) { + + Vector2 window_size = OS::get_singleton()->get_window_size(); + int window_h = window_size.height; + int window_w = window_size.width; + + glBindFramebuffer(GL_FRAMEBUFFER, storage->system_fbo); + glViewport(0, 0, window_size.width, window_size.height); + canvas_begin(); + + if (black_image[MARGIN_LEFT].is_valid()) { + _bind_canvas_texture(black_image[MARGIN_LEFT], RID()); + Size2 sz(storage->texture_get_width(black_image[MARGIN_LEFT]), storage->texture_get_height(black_image[MARGIN_LEFT])); + draw_generic_textured_rect(Rect2(0, 0, black_margin[MARGIN_LEFT], window_h), Rect2(0, 0, sz.x, sz.y)); + } else if (black_margin[MARGIN_LEFT]) { + glActiveTexture(GL_TEXTURE0); + glBindTexture(GL_TEXTURE_2D, storage->resources.black_tex); + + draw_generic_textured_rect(Rect2(0, 0, black_margin[MARGIN_LEFT], window_h), Rect2(0, 0, 1, 1)); + } + + if (black_image[MARGIN_RIGHT].is_valid()) { + _bind_canvas_texture(black_image[MARGIN_RIGHT], RID()); + Size2 sz(storage->texture_get_width(black_image[MARGIN_RIGHT]), storage->texture_get_height(black_image[MARGIN_RIGHT])); + draw_generic_textured_rect(Rect2(window_w - black_margin[MARGIN_RIGHT], 0, black_margin[MARGIN_RIGHT], window_h), Rect2(0, 0, sz.x, sz.y)); + } else if (black_margin[MARGIN_RIGHT]) { + glActiveTexture(GL_TEXTURE0); + glBindTexture(GL_TEXTURE_2D, storage->resources.black_tex); + + draw_generic_textured_rect(Rect2(window_w - black_margin[MARGIN_RIGHT], 0, black_margin[MARGIN_RIGHT], window_h), Rect2(0, 0, 1, 1)); + } + + if (black_image[MARGIN_TOP].is_valid()) { + _bind_canvas_texture(black_image[MARGIN_TOP], RID()); + + Size2 sz(storage->texture_get_width(black_image[MARGIN_TOP]), storage->texture_get_height(black_image[MARGIN_TOP])); + draw_generic_textured_rect(Rect2(0, 0, window_w, black_margin[MARGIN_TOP]), Rect2(0, 0, sz.x, sz.y)); + + } else if (black_margin[MARGIN_TOP]) { + glActiveTexture(GL_TEXTURE0); + glBindTexture(GL_TEXTURE_2D, storage->resources.black_tex); + + draw_generic_textured_rect(Rect2(0, 0, window_w, black_margin[MARGIN_TOP]), Rect2(0, 0, 1, 1)); + } + + if (black_image[MARGIN_BOTTOM].is_valid()) { + + _bind_canvas_texture(black_image[MARGIN_BOTTOM], RID()); + + Size2 sz(storage->texture_get_width(black_image[MARGIN_BOTTOM]), storage->texture_get_height(black_image[MARGIN_BOTTOM])); + draw_generic_textured_rect(Rect2(0, window_h - black_margin[MARGIN_BOTTOM], window_w, black_margin[MARGIN_BOTTOM]), Rect2(0, 0, sz.x, sz.y)); + + } else if (black_margin[MARGIN_BOTTOM]) { + + glActiveTexture(GL_TEXTURE0); + glBindTexture(GL_TEXTURE_2D, storage->resources.black_tex); + + draw_generic_textured_rect(Rect2(0, window_h - black_margin[MARGIN_BOTTOM], window_w, black_margin[MARGIN_BOTTOM]), Rect2(0, 0, 1, 1)); + } +} + void RasterizerCanvasGLES3::initialize() { { diff --git a/drivers/gles3/rasterizer_canvas_gles3.h b/drivers/gles3/rasterizer_canvas_gles3.h index c0af22b5e8..26003f543f 100644 --- a/drivers/gles3/rasterizer_canvas_gles3.h +++ b/drivers/gles3/rasterizer_canvas_gles3.h @@ -138,6 +138,8 @@ public: void initialize(); void finalize(); + virtual void draw_window_margins(int *black_margin, RID *black_image); + RasterizerCanvasGLES3(); }; diff --git a/drivers/gles3/rasterizer_gles3.cpp b/drivers/gles3/rasterizer_gles3.cpp index 3fc5bed80b..e025992c0b 100644 --- a/drivers/gles3/rasterizer_gles3.cpp +++ b/drivers/gles3/rasterizer_gles3.cpp @@ -197,18 +197,28 @@ void RasterizerGLES3::begin_frame() { uint64_t tick = OS::get_singleton()->get_ticks_usec(); - double time_total = double(tick) / 1000000.0; + double delta = double(tick - prev_ticks) / 1000000.0; + delta *= Engine::get_singleton()->get_time_scale(); + + time_total += delta; + + if (delta == 0) { + //to avoid hiccups + delta = 0.001; + } + + prev_ticks = tick; + + double time_roll_over = GLOBAL_GET("rendering/limits/time/time_rollover_secs"); + if (time_total > time_roll_over) + time_total = 0; //roll over every day (should be customz storage->frame.time[0] = time_total; storage->frame.time[1] = Math::fmod(time_total, 3600); storage->frame.time[2] = Math::fmod(time_total, 900); storage->frame.time[3] = Math::fmod(time_total, 60); storage->frame.count++; - storage->frame.delta = double(tick - storage->frame.prev_tick) / 1000000.0; - if (storage->frame.prev_tick == 0) { - //to avoid hiccups - storage->frame.delta = 0.001; - } + storage->frame.delta = delta; storage->frame.prev_tick = tick; @@ -408,6 +418,7 @@ void RasterizerGLES3::register_config() { GLOBAL_DEF("rendering/quality/filters/use_nearest_mipmap_filter", false); GLOBAL_DEF("rendering/quality/filters/anisotropic_filter_level", 4.0); + GLOBAL_DEF("rendering/limits/time/time_rollover_secs", 3600); } RasterizerGLES3::RasterizerGLES3() { @@ -420,6 +431,9 @@ RasterizerGLES3::RasterizerGLES3() { storage->canvas = canvas; scene->storage = storage; storage->scene = scene; + + prev_ticks = 0; + time_total = 0; } RasterizerGLES3::~RasterizerGLES3() { diff --git a/drivers/gles3/rasterizer_gles3.h b/drivers/gles3/rasterizer_gles3.h index ce18d6b6c1..4bc267ec7e 100644 --- a/drivers/gles3/rasterizer_gles3.h +++ b/drivers/gles3/rasterizer_gles3.h @@ -43,6 +43,9 @@ class RasterizerGLES3 : public Rasterizer { RasterizerCanvasGLES3 *canvas; RasterizerSceneGLES3 *scene; + uint64_t prev_ticks; + double time_total; + public: virtual RasterizerStorage *get_storage(); virtual RasterizerCanvas *get_canvas(); diff --git a/drivers/gles3/rasterizer_scene_gles3.cpp b/drivers/gles3/rasterizer_scene_gles3.cpp index cd74c450f5..30a77c4b39 100644 --- a/drivers/gles3/rasterizer_scene_gles3.cpp +++ b/drivers/gles3/rasterizer_scene_gles3.cpp @@ -1561,7 +1561,7 @@ void RasterizerSceneGLES3::_render_geometry(RenderList::Element *e) { if (!c.normals.empty()) { glEnableVertexAttribArray(VS::ARRAY_NORMAL); - glBufferSubData(GL_ARRAY_BUFFER, 0, sizeof(Vector3) * vertices, c.normals.ptr()); + glBufferSubData(GL_ARRAY_BUFFER, buf_ofs, sizeof(Vector3) * vertices, c.normals.ptr()); glVertexAttribPointer(VS::ARRAY_NORMAL, 3, GL_FLOAT, false, sizeof(Vector3) * vertices, ((uint8_t *)NULL) + buf_ofs); buf_ofs += sizeof(Vector3) * vertices; @@ -1573,7 +1573,7 @@ void RasterizerSceneGLES3::_render_geometry(RenderList::Element *e) { if (!c.tangents.empty()) { glEnableVertexAttribArray(VS::ARRAY_TANGENT); - glBufferSubData(GL_ARRAY_BUFFER, 0, sizeof(Plane) * vertices, c.tangents.ptr()); + glBufferSubData(GL_ARRAY_BUFFER, buf_ofs, sizeof(Plane) * vertices, c.tangents.ptr()); glVertexAttribPointer(VS::ARRAY_TANGENT, 4, GL_FLOAT, false, sizeof(Plane) * vertices, ((uint8_t *)NULL) + buf_ofs); buf_ofs += sizeof(Plane) * vertices; @@ -1585,7 +1585,7 @@ void RasterizerSceneGLES3::_render_geometry(RenderList::Element *e) { if (!c.colors.empty()) { glEnableVertexAttribArray(VS::ARRAY_COLOR); - glBufferSubData(GL_ARRAY_BUFFER, 0, sizeof(Color) * vertices, c.colors.ptr()); + glBufferSubData(GL_ARRAY_BUFFER, buf_ofs, sizeof(Color) * vertices, c.colors.ptr()); glVertexAttribPointer(VS::ARRAY_COLOR, 4, GL_FLOAT, false, sizeof(Color), ((uint8_t *)NULL) + buf_ofs); buf_ofs += sizeof(Color) * vertices; @@ -1598,7 +1598,7 @@ void RasterizerSceneGLES3::_render_geometry(RenderList::Element *e) { if (!c.uvs.empty()) { glEnableVertexAttribArray(VS::ARRAY_TEX_UV); - glBufferSubData(GL_ARRAY_BUFFER, 0, sizeof(Vector2) * vertices, c.uvs.ptr()); + glBufferSubData(GL_ARRAY_BUFFER, buf_ofs, sizeof(Vector2) * vertices, c.uvs.ptr()); glVertexAttribPointer(VS::ARRAY_TEX_UV, 2, GL_FLOAT, false, sizeof(Vector2), ((uint8_t *)NULL) + buf_ofs); buf_ofs += sizeof(Vector2) * vertices; @@ -1610,7 +1610,7 @@ void RasterizerSceneGLES3::_render_geometry(RenderList::Element *e) { if (!c.uvs2.empty()) { glEnableVertexAttribArray(VS::ARRAY_TEX_UV2); - glBufferSubData(GL_ARRAY_BUFFER, 0, sizeof(Vector2) * vertices, c.uvs2.ptr()); + glBufferSubData(GL_ARRAY_BUFFER, buf_ofs, sizeof(Vector2) * vertices, c.uvs2.ptr()); glVertexAttribPointer(VS::ARRAY_TEX_UV2, 2, GL_FLOAT, false, sizeof(Vector2), ((uint8_t *)NULL) + buf_ofs); buf_ofs += sizeof(Vector2) * vertices; @@ -1620,7 +1620,7 @@ void RasterizerSceneGLES3::_render_geometry(RenderList::Element *e) { } glEnableVertexAttribArray(VS::ARRAY_VERTEX); - glBufferSubData(GL_ARRAY_BUFFER, 0, sizeof(Vector3) * vertices, c.vertices.ptr()); + glBufferSubData(GL_ARRAY_BUFFER, buf_ofs, sizeof(Vector3) * vertices, c.vertices.ptr()); glVertexAttribPointer(VS::ARRAY_VERTEX, 3, GL_FLOAT, false, sizeof(Vector3), ((uint8_t *)NULL) + buf_ofs); glDrawArrays(gl_primitive[c.primitive], 0, c.vertices.size()); } @@ -2182,7 +2182,7 @@ void RasterizerSceneGLES3::_add_geometry(RasterizerStorageGLES3::Geometry *p_geo void RasterizerSceneGLES3::_add_geometry_with_material(RasterizerStorageGLES3::Geometry *p_geometry, InstanceBase *p_instance, RasterizerStorageGLES3::GeometryOwner *p_owner, RasterizerStorageGLES3::Material *m, bool p_shadow) { - bool has_base_alpha = (m->shader->spatial.uses_alpha || m->shader->spatial.uses_screen_texture || m->shader->spatial.unshaded); + bool has_base_alpha = (m->shader->spatial.uses_alpha && !m->shader->spatial.uses_alpha_scissor) || m->shader->spatial.uses_screen_texture || m->shader->spatial.unshaded; bool has_blend_alpha = m->shader->spatial.blend_mode != RasterizerStorageGLES3::Shader::Spatial::BLEND_MODE_MIX || m->shader->spatial.ontop; bool has_alpha = has_base_alpha || has_blend_alpha; bool shadow = false; @@ -2206,7 +2206,7 @@ void RasterizerSceneGLES3::_add_geometry_with_material(RasterizerStorageGLES3::G if (has_blend_alpha || (has_base_alpha && m->shader->spatial.depth_draw_mode != RasterizerStorageGLES3::Shader::Spatial::DEPTH_DRAW_ALPHA_PREPASS)) return; //bye - if (!m->shader->spatial.writes_modelview_or_projection && !m->shader->spatial.uses_vertex && !m->shader->spatial.uses_discard && m->shader->spatial.depth_draw_mode != RasterizerStorageGLES3::Shader::Spatial::DEPTH_DRAW_ALPHA_PREPASS) { + if (!m->shader->spatial.uses_alpha_scissor && !m->shader->spatial.writes_modelview_or_projection && !m->shader->spatial.uses_vertex && !m->shader->spatial.uses_discard && m->shader->spatial.depth_draw_mode != RasterizerStorageGLES3::Shader::Spatial::DEPTH_DRAW_ALPHA_PREPASS) { //shader does not use discard and does not write a vertex position, use generic material if (p_instance->cast_shadows == VS::SHADOW_CASTING_SETTING_DOUBLE_SIDED) m = storage->material_owner.getptr(default_material_twosided); @@ -3051,6 +3051,11 @@ void RasterizerSceneGLES3::_fill_render_list(InstanceBase **p_cull_result, int p } break; case VS::INSTANCE_IMMEDIATE: { + RasterizerStorageGLES3::Immediate *immediate = storage->immediate_owner.getptr(inst->base); + ERR_CONTINUE(!immediate); + + _add_geometry(immediate, inst, NULL, -1, p_shadow); + } break; case VS::INSTANCE_PARTICLES: { diff --git a/drivers/gles3/rasterizer_storage_gles3.cpp b/drivers/gles3/rasterizer_storage_gles3.cpp index f7ecc3b158..a8e4bc0d4b 100644 --- a/drivers/gles3/rasterizer_storage_gles3.cpp +++ b/drivers/gles3/rasterizer_storage_gles3.cpp @@ -1596,6 +1596,7 @@ void RasterizerStorageGLES3::_update_shader(Shader *p_shader) const { p_shader->spatial.depth_draw_mode = Shader::Spatial::DEPTH_DRAW_OPAQUE; p_shader->spatial.cull_mode = Shader::Spatial::CULL_MODE_BACK; p_shader->spatial.uses_alpha = false; + p_shader->spatial.uses_alpha_scissor = false; p_shader->spatial.uses_discard = false; p_shader->spatial.unshaded = false; p_shader->spatial.ontop = false; @@ -1625,6 +1626,7 @@ void RasterizerStorageGLES3::_update_shader(Shader *p_shader) const { shaders.actions_scene.render_mode_flags["vertex_lighting"] = &p_shader->spatial.uses_vertex_lighting; shaders.actions_scene.usage_flag_pointers["ALPHA"] = &p_shader->spatial.uses_alpha; + shaders.actions_scene.usage_flag_pointers["ALPHA_SCISSOR"] = &p_shader->spatial.uses_alpha_scissor; shaders.actions_scene.usage_flag_pointers["VERTEX"] = &p_shader->spatial.uses_vertex; shaders.actions_scene.usage_flag_pointers["SSS_STRENGTH"] = &p_shader->spatial.uses_sss; diff --git a/drivers/gles3/rasterizer_storage_gles3.h b/drivers/gles3/rasterizer_storage_gles3.h index b536c9841c..5a272f43fb 100644 --- a/drivers/gles3/rasterizer_storage_gles3.h +++ b/drivers/gles3/rasterizer_storage_gles3.h @@ -442,6 +442,7 @@ public: int cull_mode; bool uses_alpha; + bool uses_alpha_scissor; bool unshaded; bool ontop; bool uses_vertex; diff --git a/drivers/gles3/shader_compiler_gles3.cpp b/drivers/gles3/shader_compiler_gles3.cpp index 206f270f68..c014caee8d 100644 --- a/drivers/gles3/shader_compiler_gles3.cpp +++ b/drivers/gles3/shader_compiler_gles3.cpp @@ -762,6 +762,7 @@ ShaderCompilerGLES3::ShaderCompilerGLES3() { actions[VS::SHADER_SPATIAL].renames["SCREEN_TEXTURE"] = "screen_texture"; actions[VS::SHADER_SPATIAL].renames["DEPTH_TEXTURE"] = "depth_buffer"; actions[VS::SHADER_SPATIAL].renames["SIDE"] = "side"; + actions[VS::SHADER_SPATIAL].renames["ALPHA_SCISSOR"] = "alpha_scissor"; actions[VS::SHADER_SPATIAL].usage_defines["TANGENT"] = "#define ENABLE_TANGENT_INTERP\n"; actions[VS::SHADER_SPATIAL].usage_defines["BINORMAL"] = "@TANGENT"; @@ -778,6 +779,7 @@ ShaderCompilerGLES3::ShaderCompilerGLES3() { actions[VS::SHADER_SPATIAL].usage_defines["NORMALMAP_DEPTH"] = "@NORMALMAP"; actions[VS::SHADER_SPATIAL].usage_defines["COLOR"] = "#define ENABLE_COLOR_INTERP\n"; actions[VS::SHADER_SPATIAL].usage_defines["INSTANCE_CUSTOM"] = "#define ENABLE_INSTANCE_CUSTOM\n"; + actions[VS::SHADER_SPATIAL].usage_defines["ALPHA_SCISSOR"] = "#define ALPHA_SCISSOR_USED\n"; actions[VS::SHADER_SPATIAL].usage_defines["SSS_STRENGTH"] = "#define ENABLE_SSS\n"; actions[VS::SHADER_SPATIAL].usage_defines["SCREEN_TEXTURE"] = "#define SCREEN_TEXTURE_USED\n"; diff --git a/drivers/gles3/shaders/scene.glsl b/drivers/gles3/shaders/scene.glsl index efb82441f4..3f0498746b 100644 --- a/drivers/gles3/shaders/scene.glsl +++ b/drivers/gles3/shaders/scene.glsl @@ -1523,6 +1523,10 @@ void main() { #endif +#if defined(ALPHA_SCISSOR_USED) + float alpha_scissor = 0.5; +#endif + #if defined(ENABLE_TANGENT_INTERP) || defined(ENABLE_NORMALMAP) || defined(LIGHT_USE_ANISOTROPY) vec3 binormal = normalize(binormal_interp)*side; vec3 tangent = normalize(tangent_interp)*side; @@ -1571,6 +1575,12 @@ FRAGMENT_SHADER_CODE } +#if defined(ALPHA_SCISSOR_USED) + if (alpha<alpha_scissor) { + discard; + } +#endif + #if defined(ENABLE_NORMALMAP) diff --git a/editor/collada/collada.cpp b/editor/collada/collada.cpp index ab1e397ccc..169c34782d 100644 --- a/editor/collada/collada.cpp +++ b/editor/collada/collada.cpp @@ -2220,6 +2220,7 @@ void Collada::_merge_skeletons(VisualScene *p_vscene, Node *p_node) { ERR_CONTINUE(!state.scene_map.has(nodeid)); //weird, it should have it... NodeJoint *nj = SAFE_CAST<NodeJoint *>(state.scene_map[nodeid]); + ERR_CONTINUE(!nj); //broken collada if (!nj->owner) { print_line("no owner for: " + String(nodeid)); } diff --git a/editor/editor_log.cpp b/editor/editor_log.cpp index 5ada5f9095..c5e15b97b0 100644 --- a/editor/editor_log.cpp +++ b/editor/editor_log.cpp @@ -52,31 +52,6 @@ void EditorLog::_error_handler(void *p_self, const char *p_func, const char *p_f */ err_str = " " + err_str; - self->log->add_newline(); - - Ref<Texture> icon; - - switch (p_type) { - case ERR_HANDLER_ERROR: { - - icon = self->get_icon("Error", "EditorIcons"); - return; // these are confusing - } break; - case ERR_HANDLER_WARNING: { - - icon = self->get_icon("Error", "EditorIcons"); - - } break; - case ERR_HANDLER_SCRIPT: { - - icon = self->get_icon("ScriptError", "EditorIcons"); - } break; - case ERR_HANDLER_SHADER: { - - icon = self->get_icon("Shader", "EditorIcons"); - } break; - } - self->add_message(err_str, true); } @@ -114,16 +89,16 @@ void EditorLog::clear() { void EditorLog::add_message(const String &p_msg, bool p_error) { + log->add_newline(); if (p_error) { + log->push_color(get_color("fg_error", "Editor")); Ref<Texture> icon = get_icon("Error", "EditorIcons"); log->add_image(icon); //button->set_icon(icon); - log->push_color(get_color("fg_error", "Editor")); } else { //button->set_icon(Ref<Texture>()); } - log->add_newline(); log->add_text(p_msg); //button->set_text(p_msg); diff --git a/editor/filesystem_dock.cpp b/editor/filesystem_dock.cpp index 7e90098044..8e40850a0c 100644 --- a/editor/filesystem_dock.cpp +++ b/editor/filesystem_dock.cpp @@ -102,7 +102,7 @@ void FileSystemDock::_notification(int p_what) { case NOTIFICATION_RESIZED: { - bool new_mode = get_size().height < get_viewport_rect().size.height * 3 / 4; + bool new_mode = get_size().height < get_viewport_rect().size.height / 2; if (new_mode != split_mode) { @@ -589,7 +589,7 @@ void FileSystemDock::_go_to_dir(const String &p_dir) { void FileSystemDock::_preview_invalidated(const String &p_path) { - if (p_path.get_base_dir() == path && search_box->get_text() == String() && file_list_vb->is_visible_in_tree()) { + if (display_mode == DISPLAY_THUMBNAILS && p_path.get_base_dir() == path && search_box->get_text() == String() && file_list_vb->is_visible_in_tree()) { for (int i = 0; i < files->get_item_count(); i++) { diff --git a/editor/import/resource_importer_wav.cpp b/editor/import/resource_importer_wav.cpp index 8cb712cb78..07f1f4dd9f 100644 --- a/editor/import/resource_importer_wav.cpp +++ b/editor/import/resource_importer_wav.cpp @@ -123,6 +123,7 @@ Error ResourceImporterWAV::import(const String &p_source_file, const String &p_s int format_channels = 0; AudioStreamSample::LoopMode loop = AudioStreamSample::LOOP_DISABLED; + uint16_t compression_code = 1; bool format_found = false; bool data_found = false; int format_freq = 0; @@ -151,11 +152,10 @@ Error ResourceImporterWAV::import(const String &p_source_file, const String &p_s if (chunkID[0] == 'f' && chunkID[1] == 'm' && chunkID[2] == 't' && chunkID[3] == ' ' && !format_found) { /* IS FORMAT CHUNK */ - uint16_t compression_code = file->get_16(); - //Issue: #7755 : Not a bug - usage of other formats (format codes) are unsupported in current importer version. //Consider revision for engine version 3.0 - if (compression_code != 1) { + compression_code = file->get_16(); + if (compression_code != 1 && compression_code != 3) { ERR_PRINT("Format not supported for WAVE file (not PCM). Save WAVE files as uncompressed PCM instead."); break; } @@ -210,33 +210,37 @@ Error ResourceImporterWAV::import(const String &p_source_file, const String &p_s data.resize(frames * format_channels); - for (int i = 0; i < frames; i++) { - - for (int c = 0; c < format_channels; c++) { - - if (format_bits == 8) { - // 8 bit samples are UNSIGNED - - uint8_t s = file->get_8(); - s -= 128; - int8_t *sp = (int8_t *)&s; + if (format_bits == 8) { + for (int i = 0; i < frames * format_channels; i++) { + // 8 bit samples are UNSIGNED - data[i * format_channels + c] = float(*sp) / 128.0; + data[i] = int8_t(file->get_8() - 128) / 128.f; + } + } else if (format_bits == 32 && compression_code == 3) { + for (int i = 0; i < frames * format_channels; i++) { + //32 bit IEEE Float - } else { - //16+ bits samples are SIGNED - // if sample is > 16 bits, just read extra bytes + data[i] = file->get_float(); + } + } else if (format_bits == 16) { + for (int i = 0; i < frames * format_channels; i++) { + //16 bit SIGNED - uint32_t s = 0; - for (int b = 0; b < (format_bits >> 3); b++) { + data[i] = int16_t(file->get_16()) / 32768.f; + } + } else { + for (int i = 0; i < frames * format_channels; i++) { + //16+ bits samples are SIGNED + // if sample is > 16 bits, just read extra bytes - s |= ((uint32_t)file->get_8()) << (b * 8); - } - s <<= (32 - format_bits); - int32_t ss = s; + uint32_t s = 0; + for (int b = 0; b < (format_bits >> 3); b++) { - data[i * format_channels + c] = (ss >> 16) / 32768.0; + s |= ((uint32_t)file->get_8()) << (b * 8); } + s <<= (32 - format_bits); + + data[i] = (int32_t(s) >> 16) / 32768.f; } } diff --git a/editor/plugins/canvas_item_editor_plugin.cpp b/editor/plugins/canvas_item_editor_plugin.cpp index f5d9da195a..ac6d78adc2 100644 --- a/editor/plugins/canvas_item_editor_plugin.cpp +++ b/editor/plugins/canvas_item_editor_plugin.cpp @@ -375,6 +375,8 @@ void CanvasItemEditor::set_state(const Dictionary &p_state) { int idx = skeleton_menu->get_item_index(SKELETON_SHOW_BONES); skeleton_menu->set_item_checked(idx, skeleton_show_bones); } + + viewport->update(); } void CanvasItemEditor::_add_canvas_item(CanvasItem *p_canvas_item) { @@ -1390,7 +1392,12 @@ void CanvasItemEditor::_viewport_gui_input(const Ref<InputEvent> &p_event) { while ((n && n != scene && n->get_owner() != scene) || (n && !n->is_class("CanvasItem"))) { n = n->get_parent(); }; - c = n->cast_to<CanvasItem>(); + + if (n) { + c = n->cast_to<CanvasItem>(); + } else { + c = NULL; + } // Select the item additive_selection = b->get_shift(); diff --git a/editor/plugins/spatial_editor_plugin.cpp b/editor/plugins/spatial_editor_plugin.cpp index 50d2f193ed..0dba1f12a2 100644 --- a/editor/plugins/spatial_editor_plugin.cpp +++ b/editor/plugins/spatial_editor_plugin.cpp @@ -1190,17 +1190,47 @@ void SpatialEditorViewport::_sinput(const Ref<InputEvent> &p_event) { motion = motion_mask.dot(motion) * motion_mask; } + //set_message("Translating: "+motion); + + List<Node *> &selection = editor_selection->get_selected_node_list(); + float snap = 0; if (_edit.snap || spatial_editor->is_snap_enabled()) { snap = spatial_editor->get_translate_snap(); - motion.snap(Vector3(snap, snap, snap)); - } + bool local_coords = spatial_editor->are_local_coords_enabled(); + + if (local_coords) { + bool multiple = false; + Spatial *node = NULL; + for (List<Node *>::Element *E = selection.front(); E; E = E->next()) { + + Spatial *sp = E->get()->cast_to<Spatial>(); + if (!sp) { + continue; + } + if (node) { + multiple = true; + break; + } else { + node = sp; + } + } - //set_message("Translating: "+motion); + if (multiple) { + motion.snap(Vector3(snap, snap, snap)); + } else { + Basis b = node->get_global_transform().basis.orthonormalized(); + Vector3 local_motion = b.inverse().xform(motion); + local_motion.snap(Vector3(snap, snap, snap)); + motion = b.xform(local_motion); + } - List<Node *> &selection = editor_selection->get_selected_node_list(); + } else { + motion.snap(Vector3(snap, snap, snap)); + } + } for (List<Node *>::Element *E = selection.front(); E; E = E->next()) { diff --git a/editor/plugins/spatial_editor_plugin.h b/editor/plugins/spatial_editor_plugin.h index 9b626054c0..e9857f8b0c 100644 --- a/editor/plugins/spatial_editor_plugin.h +++ b/editor/plugins/spatial_editor_plugin.h @@ -514,6 +514,8 @@ public: float get_rotate_snap() const { return snap_rotate->get_text().to_double(); } float get_scale_snap() const { return snap_scale->get_text().to_double(); } + bool are_local_coords_enabled() const { return transform_menu->get_popup()->is_item_checked(transform_menu->get_popup()->get_item_index(SpatialEditor::MENU_TRANSFORM_LOCAL_COORDS)); } + Ref<ArrayMesh> get_move_gizmo(int idx) const { return move_gizmo[idx]; } Ref<ArrayMesh> get_rotate_gizmo(int idx) const { return rotate_gizmo[idx]; } diff --git a/editor/plugins/tile_map_editor_plugin.cpp b/editor/plugins/tile_map_editor_plugin.cpp index e7bc8a4dab..a52a875338 100644 --- a/editor/plugins/tile_map_editor_plugin.cpp +++ b/editor/plugins/tile_map_editor_plugin.cpp @@ -1451,6 +1451,11 @@ TileMapEditor::TileMapEditor(EditorNode *p_editor) { ED_SHORTCUT("tile_map_editor/mirror_x", TTR("Mirror X"), KEY_A); ED_SHORTCUT("tile_map_editor/mirror_y", TTR("Mirror Y"), KEY_S); + HBoxContainer *tool_hb1 = memnew(HBoxContainer); + add_child(tool_hb1); + HBoxContainer *tool_hb2 = memnew(HBoxContainer); + add_child(tool_hb2); + search_box = memnew(LineEdit); search_box->set_h_size_flags(SIZE_EXPAND_FILL); search_box->connect("text_entered", this, "_text_entered"); @@ -1514,47 +1519,44 @@ TileMapEditor::TileMapEditor(EditorNode *p_editor) { transp->set_tooltip(TTR("Transpose") + " (" + ED_GET_SHORTCUT("tile_map_editor/transpose")->get_as_text() + ")"); transp->set_focus_mode(FOCUS_NONE); transp->connect("pressed", this, "_update_transform_buttons", make_binds(transp)); - toolbar->add_child(transp); + tool_hb1->add_child(transp); mirror_x = memnew(ToolButton); mirror_x->set_toggle_mode(true); mirror_x->set_tooltip(TTR("Mirror X") + " (" + ED_GET_SHORTCUT("tile_map_editor/mirror_x")->get_as_text() + ")"); mirror_x->set_focus_mode(FOCUS_NONE); mirror_x->connect("pressed", this, "_update_transform_buttons", make_binds(mirror_x)); - toolbar->add_child(mirror_x); + tool_hb1->add_child(mirror_x); mirror_y = memnew(ToolButton); mirror_y->set_toggle_mode(true); mirror_y->set_tooltip(TTR("Mirror Y") + " (" + ED_GET_SHORTCUT("tile_map_editor/mirror_y")->get_as_text() + ")"); mirror_y->set_focus_mode(FOCUS_NONE); mirror_y->connect("pressed", this, "_update_transform_buttons", make_binds(mirror_y)); - toolbar->add_child(mirror_y); - - toolbar->add_child(memnew(VSeparator)); + tool_hb1->add_child(mirror_y); rotate_0 = memnew(ToolButton); rotate_0->set_toggle_mode(true); rotate_0->set_tooltip(TTR("Rotate 0 degrees")); rotate_0->set_focus_mode(FOCUS_NONE); rotate_0->connect("pressed", this, "_update_transform_buttons", make_binds(rotate_0)); - toolbar->add_child(rotate_0); + tool_hb2->add_child(rotate_0); rotate_90 = memnew(ToolButton); rotate_90->set_toggle_mode(true); rotate_90->set_tooltip(TTR("Rotate 90 degrees")); rotate_90->set_focus_mode(FOCUS_NONE); rotate_90->connect("pressed", this, "_update_transform_buttons", make_binds(rotate_90)); - toolbar->add_child(rotate_90); + tool_hb2->add_child(rotate_90); rotate_180 = memnew(ToolButton); rotate_180->set_toggle_mode(true); rotate_180->set_tooltip(TTR("Rotate 180 degrees")); rotate_180->set_focus_mode(FOCUS_NONE); rotate_180->connect("pressed", this, "_update_transform_buttons", make_binds(rotate_180)); - toolbar->add_child(rotate_180); + tool_hb2->add_child(rotate_180); rotate_270 = memnew(ToolButton); rotate_270->set_toggle_mode(true); rotate_270->set_tooltip(TTR("Rotate 270 degrees")); rotate_270->set_focus_mode(FOCUS_NONE); rotate_270->connect("pressed", this, "_update_transform_buttons", make_binds(rotate_270)); - toolbar->add_child(rotate_270); - toolbar->hide(); + tool_hb2->add_child(rotate_270); rotate_0->set_pressed(true); } diff --git a/editor/project_manager.cpp b/editor/project_manager.cpp index d5a56f644f..b77544befa 100644 --- a/editor/project_manager.cpp +++ b/editor/project_manager.cpp @@ -491,17 +491,8 @@ void ProjectManager::_update_project_buttons() { item->update(); } - bool has_runnable_scene = false; - for (Map<String, String>::Element *E = selected_list.front(); E; E = E->next()) { - const String &selected_main = E->get(); - if (selected_main == "") continue; - has_runnable_scene = true; - break; - } - erase_btn->set_disabled(selected_list.size() < 1); open_btn->set_disabled(selected_list.size() < 1); - run_btn->set_disabled(!has_runnable_scene); } void ProjectManager::_panel_input(const Ref<InputEvent> &p_ev, Node *p_hb) { @@ -969,10 +960,22 @@ void ProjectManager::_run_project_confirm() { for (Map<String, String>::Element *E = selected_list.front(); E; E = E->next()) { const String &selected_main = E->get(); - if (selected_main == "") continue; + if (selected_main == "") { + run_error_diag->set_text(TTR("Can't run project: no main scene defined.\nPlease edit the project and set the main scene in \"Project Settings\" under the \"Application\" category.")); + run_error_diag->popup_centered(); + return; + } + const String &selected = E->key(); String path = EditorSettings::get_singleton()->get("projects/" + selected); + + if (!DirAccess::exists(path + "/.import")) { + run_error_diag->set_text(TTR("Can't run project: Assets need to be imported.\nPlease edit the project to trigger the initial import.")); + run_error_diag->popup_centered(); + return; + } + print_line("OPENING: " + path + " (" + selected + ")"); List<String> args; @@ -1390,6 +1393,10 @@ ProjectManager::ProjectManager() { last_clicked = ""; SceneTree::get_singleton()->connect("files_dropped", this, "_files_dropped"); + + run_error_diag = memnew(AcceptDialog); + gui_base->add_child(run_error_diag); + run_error_diag->set_title(TTR("Can't run project")); } ProjectManager::~ProjectManager() { diff --git a/editor/project_manager.h b/editor/project_manager.h index 27886132c5..181d3cc5d9 100644 --- a/editor/project_manager.h +++ b/editor/project_manager.h @@ -57,6 +57,7 @@ class ProjectManager : public Control { ConfirmationDialog *multi_open_ask; ConfirmationDialog *multi_run_ask; ConfirmationDialog *multi_scan_ask; + AcceptDialog *run_error_diag; NewProjectDialog *npdialog; ScrollContainer *scroll; VBoxContainer *scroll_childs; diff --git a/editor/script_editor_debugger.cpp b/editor/script_editor_debugger.cpp index b8c531bbce..01cfdc1b57 100644 --- a/editor/script_editor_debugger.cpp +++ b/editor/script_editor_debugger.cpp @@ -1597,6 +1597,7 @@ void ScriptEditorDebugger::_bind_methods() { ScriptEditorDebugger::ScriptEditorDebugger(EditorNode *p_editor) { ppeer = Ref<PacketPeerStream>(memnew(PacketPeerStream)); + ppeer->set_input_buffer_max_size(1024 * 1024 * 8); //8mb should be enough editor = p_editor; tabs = memnew(TabContainer); diff --git a/main/input_default.cpp b/main/input_default.cpp index 3361aa0678..4e2fd6f9d4 100644 --- a/main/input_default.cpp +++ b/main/input_default.cpp @@ -453,7 +453,8 @@ void InputDefault::set_mouse_position(const Point2 &p_posf) { mouse_speed_track.update(p_posf - mouse_pos); mouse_pos = p_posf; if (custom_cursor.is_valid()) { - VisualServer::get_singleton()->cursor_set_pos(get_mouse_position()); + //removed, please insist that we implement hardware cursors + // VisualServer::get_singleton()->cursor_set_pos(get_mouse_position()); } } @@ -538,6 +539,7 @@ bool InputDefault::is_emulating_touchscreen() const { } void InputDefault::set_custom_mouse_cursor(const RES &p_cursor, const Vector2 &p_hotspot) { + /* no longer supported, leaving this for reference to anyone who might want to implement hardware cursors if (custom_cursor == p_cursor) return; @@ -545,7 +547,8 @@ void InputDefault::set_custom_mouse_cursor(const RES &p_cursor, const Vector2 &p if (p_cursor.is_null()) { set_mouse_mode(MOUSE_MODE_VISIBLE); - VisualServer::get_singleton()->cursor_set_visible(false); + //removed, please insist us to implement hardare cursors + //VisualServer::get_singleton()->cursor_set_visible(false); } else { Ref<AtlasTexture> atex = custom_cursor; Rect2 region = atex.is_valid() ? atex->get_region() : Rect2(); @@ -554,10 +557,11 @@ void InputDefault::set_custom_mouse_cursor(const RES &p_cursor, const Vector2 &p VisualServer::get_singleton()->cursor_set_texture(custom_cursor->get_rid(), p_hotspot, 0, region); VisualServer::get_singleton()->cursor_set_pos(get_mouse_position()); } + */ } void InputDefault::set_mouse_in_window(bool p_in_window) { - + /* no longer supported, leaving this for reference to anyone who might want to implement hardware cursors if (custom_cursor.is_valid()) { if (p_in_window) { @@ -568,6 +572,7 @@ void InputDefault::set_mouse_in_window(bool p_in_window) { VisualServer::get_singleton()->cursor_set_visible(false); } } + */ } // from github.com/gabomdq/SDL_GameControllerDB diff --git a/modules/gdnative/godot/string.cpp b/modules/gdnative/godot/string.cpp index 3573f266ac..76cf1fba12 100644 --- a/modules/gdnative/godot/string.cpp +++ b/modules/gdnative/godot/string.cpp @@ -29,6 +29,7 @@ /*************************************************************************/ #include <godot/string.h> +#include "core/variant.h" #include "string_db.h" #include "ustring.h" @@ -112,6 +113,1155 @@ void GDAPI godot_string_destroy(godot_string *p_self) { self->~String(); } +/* Standard size stuff */ + +godot_int GDAPI godot_string_length(const godot_string *p_self) { + const String *self = (const String *)p_self; + + return self->length(); +} + +/* Helpers */ + +godot_bool GDAPI godot_string_begins_with(const godot_string *p_self, const godot_string *p_string) { + const String *self = (const String *)p_self; + const String *string = (const String *)p_string; + + return self->begins_with(*string); +} + +godot_bool GDAPI godot_string_begins_with_char_array(const godot_string *p_self, const char *p_char_array) { + const String *self = (const String *)p_self; + + return self->begins_with(p_char_array); +} + +godot_array GDAPI godot_string_bigrams(const godot_string *p_self) { + const String *self = (const String *)p_self; + Vector<String> return_value = self->bigrams(); + + godot_array result; + memnew_placement(&result, Array); + Array *proxy = (Array *)&result; + proxy->resize(return_value.size()); + for (int i = 0; i < return_value.size(); i++) { + (*proxy)[i] = return_value[i]; + } + + return result; +}; + +godot_string GDAPI godot_string_chr(wchar_t p_character) { + godot_string result; + memnew_placement(&result, String(String::chr(p_character))); + + return result; +} + +godot_bool GDAPI godot_string_ends_with(const godot_string *p_self, const godot_string *p_string) { + const String *self = (const String *)p_self; + const String *string = (const String *)p_string; + + return self->ends_with(*string); +} + +godot_int GDAPI godot_string_find(const godot_string *p_self, godot_string p_what) { + const String *self = (const String *)p_self; + String *what = (String *)&p_what; + + return self->find(*what); +} + +godot_int GDAPI godot_string_find_from(const godot_string *p_self, godot_string p_what, godot_int p_from) { + const String *self = (const String *)p_self; + String *what = (String *)&p_what; + + return self->find(*what, p_from); +} + +godot_int GDAPI godot_string_findmk(const godot_string *p_self, const godot_array *p_keys) { + const String *self = (const String *)p_self; + + Vector<String> keys; + Array *keys_proxy = (Array *)p_keys; + keys.resize(keys_proxy->size()); + for (int i = 0; i < keys_proxy->size(); i++) { + keys[i] = (*keys_proxy)[i]; + } + + return self->findmk(keys); +} + +godot_int GDAPI godot_string_findmk_from(const godot_string *p_self, const godot_array *p_keys, godot_int p_from) { + const String *self = (const String *)p_self; + + Vector<String> keys; + Array *keys_proxy = (Array *)p_keys; + keys.resize(keys_proxy->size()); + for (int i = 0; i < keys_proxy->size(); i++) { + keys[i] = (*keys_proxy)[i]; + } + + return self->findmk(keys, p_from); +} + +godot_int GDAPI godot_string_findmk_from_in_place(const godot_string *p_self, const godot_array *p_keys, godot_int p_from, godot_int *r_key) { + const String *self = (const String *)p_self; + + Vector<String> keys; + Array *keys_proxy = (Array *)p_keys; + keys.resize(keys_proxy->size()); + for (int i = 0; i < keys_proxy->size(); i++) { + keys[i] = (*keys_proxy)[i]; + } + + return self->findmk(keys, p_from, r_key); +} + +godot_int GDAPI godot_string_findn(const godot_string *p_self, godot_string p_what) { + const String *self = (const String *)p_self; + String *what = (String *)&p_what; + + return self->findn(*what); +} + +godot_int GDAPI godot_string_findn_from(const godot_string *p_self, godot_string p_what, godot_int p_from) { + const String *self = (const String *)p_self; + String *what = (String *)&p_what; + + return self->findn(*what, p_from); +} + +godot_int GDAPI find_last(const godot_string *p_self, godot_string p_what) { + const String *self = (const String *)p_self; + String *what = (String *)&p_what; + + return self->find_last(*what); +} + +godot_string GDAPI godot_string_format(const godot_string *p_self, const godot_variant *p_values) { + const String *self = (const String *)p_self; + const Variant *values = (const Variant *)p_values; + godot_string result; + memnew_placement(&result, String(self->format(*values))); + + return result; +} + +godot_string GDAPI godot_string_format_with_custom_placeholder(const godot_string *p_self, const godot_variant *p_values, const char *p_placeholder) { + const String *self = (const String *)p_self; + const Variant *values = (const Variant *)p_values; + String placeholder = String(p_placeholder); + godot_string result; + memnew_placement(&result, String(self->format(*values, placeholder))); + + return result; +} + +godot_string GDAPI godot_string_hex_encode_buffer(const uint8_t *p_buffer, godot_int p_len) { + godot_string result; + memnew_placement(&result, String(String::hex_encode_buffer(p_buffer, p_len))); + + return result; +} + +godot_int GDAPI godot_string_hex_to_int(const godot_string *p_self) { + const String *self = (const String *)p_self; + + return self->hex_to_int(); +} + +godot_int GDAPI godot_string_hex_to_int_without_prefix(const godot_string *p_self) { + const String *self = (const String *)p_self; + + return self->hex_to_int(true); +} + +godot_string GDAPI godot_string_insert(const godot_string *p_self, godot_int at_pos, godot_string p_content) { + const String *self = (const String *)p_self; + String *content = (String *)&p_content; + godot_string result; + memnew_placement(&result, String(self->insert(at_pos, *content))); + + return result; +} + +godot_bool GDAPI godot_string_is_numeric(const godot_string *p_self) { + const String *self = (const String *)p_self; + + return self->is_numeric(); +} + +godot_bool GDAPI godot_string_is_subsequence_of(const godot_string *p_self, const godot_string *p_string) { + const String *self = (const String *)p_self; + const String *string = (const String *)p_string; + + return self->is_subsequence_of(*string); +} + +godot_bool GDAPI godot_string_is_subsequence_ofi(const godot_string *p_self, const godot_string *p_string) { + const String *self = (const String *)p_self; + const String *string = (const String *)p_string; + + return self->is_subsequence_ofi(*string); +} + +godot_string GDAPI godot_string_lpad(const godot_string *p_self, godot_int p_min_length) { + const String *self = (const String *)p_self; + godot_string result; + memnew_placement(&result, String(self->lpad(p_min_length))); + + return result; +} + +godot_string GDAPI godot_string_lpad_with_custom_character(const godot_string *p_self, godot_int p_min_length, const godot_string *p_character) { + const String *self = (const String *)p_self; + const String *character = (const String *)p_character; + godot_string result; + memnew_placement(&result, String(self->lpad(p_min_length, *character))); + + return result; +} + +godot_bool GDAPI godot_string_match(const godot_string *p_self, const godot_string *p_wildcard) { + const String *self = (const String *)p_self; + const String *wildcard = (const String *)p_wildcard; + + return self->match(*wildcard); +} + +godot_bool GDAPI godot_string_matchn(const godot_string *p_self, const godot_string *p_wildcard) { + const String *self = (const String *)p_self; + const String *wildcard = (const String *)p_wildcard; + + return self->matchn(*wildcard); +} + +godot_string GDAPI godot_string_md5(const uint8_t *p_md5) { + godot_string result; + memnew_placement(&result, String(String::md5(p_md5))); + + return result; +} + +godot_string GDAPI godot_string_num(double p_num) { + godot_string result; + memnew_placement(&result, String(String::num(p_num))); + + return result; +} + +godot_string GDAPI godot_string_num_int64(int64_t p_num, godot_int p_base) { + godot_string result; + memnew_placement(&result, String(String::num_int64(p_num, p_base))); + + return result; +} + +godot_string GDAPI godot_string_num_int64_capitalized(int64_t p_num, godot_int p_base, godot_bool p_capitalize_hex) { + godot_string result; + memnew_placement(&result, String(String::num_int64(p_num, p_base, true))); + + return result; +} + +godot_string GDAPI godot_string_num_real(double p_num) { + godot_string result; + memnew_placement(&result, String(String::num_real(p_num))); + + return result; +} + +godot_string GDAPI godot_string_num_scientific(double p_num) { + godot_string result; + memnew_placement(&result, String(String::num_scientific(p_num))); + + return result; +} + +godot_string GDAPI godot_string_num_with_decimals(double p_num, godot_int p_decimals) { + godot_string result; + memnew_placement(&result, String(String::num(p_num, p_decimals))); + + return result; +} + +godot_string GDAPI godot_string_pad_decimals(const godot_string *p_self, godot_int p_digits) { + const String *self = (const String *)p_self; + godot_string result; + memnew_placement(&result, String(self->pad_decimals(p_digits))); + + return result; +} + +godot_string GDAPI godot_string_pad_zeros(const godot_string *p_self, godot_int p_digits) { + const String *self = (const String *)p_self; + godot_string result; + memnew_placement(&result, String(self->pad_zeros(p_digits))); + + return result; +} + +godot_string GDAPI godot_string_replace(const godot_string *p_self, godot_string p_key, godot_string p_with) { + const String *self = (const String *)p_self; + String *key = (String *)&p_key; + String *with = (String *)&p_with; + godot_string result; + memnew_placement(&result, String(self->replace(*key, *with))); + + return result; +} + +godot_string GDAPI godot_string_replacen(const godot_string *p_self, godot_string p_key, godot_string p_with) { + const String *self = (const String *)p_self; + String *key = (String *)&p_key; + String *with = (String *)&p_with; + godot_string result; + memnew_placement(&result, String(self->replacen(*key, *with))); + + return result; +} + +godot_int GDAPI godot_string_rfind(const godot_string *p_self, godot_string p_what) { + const String *self = (const String *)p_self; + String *what = (String *)&p_what; + + return self->rfind(*what); +} + +godot_int GDAPI godot_string_rfindn(const godot_string *p_self, godot_string p_what) { + const String *self = (const String *)p_self; + String *what = (String *)&p_what; + + return self->rfindn(*what); +} + +godot_int GDAPI godot_string_rfind_from(const godot_string *p_self, godot_string p_what, godot_int p_from) { + const String *self = (const String *)p_self; + String *what = (String *)&p_what; + + return self->rfind(*what, p_from); +} + +godot_int GDAPI godot_string_rfindn_from(const godot_string *p_self, godot_string p_what, godot_int p_from) { + const String *self = (const String *)p_self; + String *what = (String *)&p_what; + + return self->rfindn(*what, p_from); +} + +godot_string GDAPI godot_string_replace_first(const godot_string *p_self, godot_string p_key, godot_string p_with) { + const String *self = (const String *)p_self; + String *key = (String *)&p_key; + String *with = (String *)&p_with; + godot_string result; + memnew_placement(&result, String(self->replace_first(*key, *with))); + + return result; +} + +godot_string GDAPI godot_string_rpad(const godot_string *p_self, godot_int p_min_length) { + const String *self = (const String *)p_self; + godot_string result; + memnew_placement(&result, String(self->rpad(p_min_length))); + + return result; +} + +godot_string GDAPI godot_string_rpad_with_custom_character(const godot_string *p_self, godot_int p_min_length, const godot_string *p_character) { + const String *self = (const String *)p_self; + const String *character = (const String *)p_character; + godot_string result; + memnew_placement(&result, String(self->rpad(p_min_length, *character))); + + return result; +} + +godot_real GDAPI godot_string_similarity(const godot_string *p_self, const godot_string *p_string) { + const String *self = (const String *)p_self; + const String *string = (const String *)p_string; + + return self->similarity(*string); +} + +godot_string GDAPI godot_string_sprintf(const godot_string *p_self, const godot_array *p_values, godot_bool *p_error) { + const String *self = (const String *)p_self; + const Array *values = (const Array *)p_values; + + godot_string result; + String return_value = self->sprintf(*values, p_error); + memnew_placement(&result, String(return_value)); + + return result; +} + +godot_string GDAPI godot_string_substr(const godot_string *p_self, godot_int p_from, godot_int p_chars) { + const String *self = (const String *)p_self; + godot_string result; + memnew_placement(&result, String(self->substr(p_from, p_chars))); + + return result; +} + +double GDAPI godot_string_to_double(const godot_string *p_self) { + const String *self = (const String *)p_self; + + return self->to_double(); +} + +godot_real GDAPI godot_string_to_float(const godot_string *p_self) { + const String *self = (const String *)p_self; + + return self->to_float(); +} + +godot_int GDAPI godot_string_to_int(const godot_string *p_self) { + const String *self = (const String *)p_self; + + return self->to_int(); +} + +godot_string GDAPI godot_string_capitalize(const godot_string *p_self) { + const String *self = (const String *)p_self; + godot_string result; + memnew_placement(&result, String(self->capitalize())); + + return result; +}; + +godot_string GDAPI godot_string_camelcase_to_underscore(const godot_string *p_self) { + const String *self = (const String *)p_self; + godot_string result; + memnew_placement(&result, String(self->camelcase_to_underscore(false))); + + return result; +}; + +godot_string GDAPI godot_string_camelcase_to_underscore_lowercased(const godot_string *p_self) { + const String *self = (const String *)p_self; + godot_string result; + memnew_placement(&result, String(self->camelcase_to_underscore())); + + return result; +}; + +double GDAPI godot_string_char_to_double(const char *p_what) { + return String::to_double(p_what); +}; + +godot_int GDAPI godot_string_char_to_int(const char *p_what) { + return String::to_int(p_what); +}; + +int64_t GDAPI godot_string_wchar_to_int(const wchar_t *p_str) { + return String::to_int(p_str); +}; + +godot_int GDAPI godot_string_char_to_int_with_len(const char *p_what, godot_int p_len) { + return String::to_int(p_what, p_len); +}; + +int64_t GDAPI godot_string_char_to_int64_with_len(const wchar_t *p_str, int p_len) { + return String::to_int(p_str, p_len); +}; + +int64_t GDAPI godot_string_hex_to_int64(const godot_string *p_self) { + const String *self = (const String *)p_self; + + return self->hex_to_int64(false); +}; + +int64_t GDAPI godot_string_hex_to_int64_with_prefix(const godot_string *p_self) { + const String *self = (const String *)p_self; + + return self->hex_to_int64(); +}; + +int64_t GDAPI godot_string_to_int64(const godot_string *p_self) { + const String *self = (const String *)p_self; + + return self->to_int64(); +}; + +double GDAPI godot_string_unicode_char_to_double(const wchar_t *p_str, const wchar_t **r_end) { + return String::to_double(p_str, r_end); +} + +godot_string GDAPI godot_string_get_slice(const godot_string *p_self, godot_string p_splitter, godot_int p_slice) { + const String *self = (const String *)p_self; + String *splitter = (String *)&p_splitter; + godot_string result; + memnew_placement(&result, String(self->get_slice(*splitter, p_slice))); + + return result; +}; + +godot_string GDAPI godot_string_get_slicec(const godot_string *p_self, wchar_t p_splitter, godot_int p_slice) { + const String *self = (const String *)p_self; + godot_string result; + memnew_placement(&result, String(self->get_slicec(p_splitter, p_slice))); + + return result; +}; + +godot_array GDAPI godot_string_split(const godot_string *p_self, const godot_string *p_splitter) { + const String *self = (const String *)p_self; + const String *splitter = (const String *)p_splitter; + godot_array result; + memnew_placement(&result, Array); + Array *proxy = (Array *)&result; + Vector<String> return_value = self->split(*splitter, false); + + proxy->resize(return_value.size()); + for (int i = 0; i < return_value.size(); i++) { + (*proxy)[i] = return_value[i]; + } + + return result; +}; + +godot_array GDAPI godot_string_split_allow_empty(const godot_string *p_self, const godot_string *p_splitter) { + const String *self = (const String *)p_self; + const String *splitter = (const String *)p_splitter; + godot_array result; + memnew_placement(&result, Array); + Array *proxy = (Array *)&result; + Vector<String> return_value = self->split(*splitter); + + proxy->resize(return_value.size()); + for (int i = 0; i < return_value.size(); i++) { + (*proxy)[i] = return_value[i]; + } + + return result; +}; + +godot_array GDAPI godot_string_split_floats(const godot_string *p_self, const godot_string *p_splitter) { + const String *self = (const String *)p_self; + const String *splitter = (const String *)p_splitter; + godot_array result; + memnew_placement(&result, Array); + Array *proxy = (Array *)&result; + Vector<float> return_value = self->split_floats(*splitter, false); + + proxy->resize(return_value.size()); + for (int i = 0; i < return_value.size(); i++) { + (*proxy)[i] = return_value[i]; + } + + return result; +}; + +godot_array GDAPI godot_string_split_floats_allows_empty(const godot_string *p_self, const godot_string *p_splitter) { + const String *self = (const String *)p_self; + const String *splitter = (const String *)p_splitter; + godot_array result; + memnew_placement(&result, Array); + Array *proxy = (Array *)&result; + Vector<float> return_value = self->split_floats(*splitter); + + proxy->resize(return_value.size()); + for (int i = 0; i < return_value.size(); i++) { + (*proxy)[i] = return_value[i]; + } + + return result; +}; + +godot_array GDAPI godot_string_split_floats_mk(const godot_string *p_self, const godot_array *p_splitters) { + const String *self = (const String *)p_self; + + Vector<String> splitters; + Array *splitter_proxy = (Array *)p_splitters; + splitters.resize(splitter_proxy->size()); + for (int i = 0; i < splitter_proxy->size(); i++) { + splitters[i] = (*splitter_proxy)[i]; + } + + godot_array result; + memnew_placement(&result, Array); + Array *proxy = (Array *)&result; + Vector<float> return_value = self->split_floats_mk(splitters, false); + + proxy->resize(return_value.size()); + for (int i = 0; i < return_value.size(); i++) { + (*proxy)[i] = return_value[i]; + } + + return result; +}; + +godot_array GDAPI godot_string_split_floats_mk_allows_empty(const godot_string *p_self, const godot_array *p_splitters) { + const String *self = (const String *)p_self; + + Vector<String> splitters; + Array *splitter_proxy = (Array *)p_splitters; + splitters.resize(splitter_proxy->size()); + for (int i = 0; i < splitter_proxy->size(); i++) { + splitters[i] = (*splitter_proxy)[i]; + } + + godot_array result; + memnew_placement(&result, Array); + Array *proxy = (Array *)&result; + Vector<float> return_value = self->split_floats_mk(splitters); + + proxy->resize(return_value.size()); + for (int i = 0; i < return_value.size(); i++) { + (*proxy)[i] = return_value[i]; + } + + return result; +}; + +godot_array GDAPI godot_string_split_ints(const godot_string *p_self, const godot_string *p_splitter) { + const String *self = (const String *)p_self; + const String *splitter = (const String *)p_splitter; + godot_array result; + memnew_placement(&result, Array); + Array *proxy = (Array *)&result; + Vector<int> return_value = self->split_ints(*splitter, false); + + proxy->resize(return_value.size()); + for (int i = 0; i < return_value.size(); i++) { + (*proxy)[i] = return_value[i]; + } + + return result; +}; + +godot_array GDAPI godot_string_split_ints_allows_empty(const godot_string *p_self, const godot_string *p_splitter) { + const String *self = (const String *)p_self; + const String *splitter = (const String *)p_splitter; + godot_array result; + memnew_placement(&result, Array); + Array *proxy = (Array *)&result; + Vector<int> return_value = self->split_ints(*splitter); + + proxy->resize(return_value.size()); + for (int i = 0; i < return_value.size(); i++) { + (*proxy)[i] = return_value[i]; + } + + return result; +}; + +godot_array GDAPI godot_string_split_ints_mk(const godot_string *p_self, const godot_array *p_splitters) { + const String *self = (const String *)p_self; + + Vector<String> splitters; + Array *splitter_proxy = (Array *)p_splitters; + splitters.resize(splitter_proxy->size()); + for (int i = 0; i < splitter_proxy->size(); i++) { + splitters[i] = (*splitter_proxy)[i]; + } + + godot_array result; + memnew_placement(&result, Array); + Array *proxy = (Array *)&result; + Vector<int> return_value = self->split_ints_mk(splitters, false); + + proxy->resize(return_value.size()); + for (int i = 0; i < return_value.size(); i++) { + (*proxy)[i] = return_value[i]; + } + + return result; +}; + +godot_array GDAPI godot_string_split_ints_mk_allows_empty(const godot_string *p_self, const godot_array *p_splitters) { + const String *self = (const String *)p_self; + + Vector<String> splitters; + Array *splitter_proxy = (Array *)p_splitters; + splitters.resize(splitter_proxy->size()); + for (int i = 0; i < splitter_proxy->size(); i++) { + splitters[i] = (*splitter_proxy)[i]; + } + + godot_array result; + memnew_placement(&result, Array); + Array *proxy = (Array *)&result; + Vector<int> return_value = self->split_ints_mk(splitters); + + proxy->resize(return_value.size()); + for (int i = 0; i < return_value.size(); i++) { + (*proxy)[i] = return_value[i]; + } + + return result; +}; + +godot_array GDAPI godot_string_split_spaces(const godot_string *p_self) { + const String *self = (const String *)p_self; + godot_array result; + memnew_placement(&result, Array); + Array *proxy = (Array *)&result; + Vector<String> return_value = self->split_spaces(); + + proxy->resize(return_value.size()); + for (int i = 0; i < return_value.size(); i++) { + (*proxy)[i] = return_value[i]; + } + + return result; +}; + +godot_int GDAPI godot_string_get_slice_count(const godot_string *p_self, godot_string p_splitter) { + const String *self = (const String *)p_self; + String *splitter = (String *)&p_splitter; + + return self->get_slice_count(*splitter); +}; + +wchar_t GDAPI godot_string_char_lowercase(wchar_t p_char) { + return String::char_lowercase(p_char); +}; + +wchar_t GDAPI godot_string_char_uppercase(wchar_t p_char) { + return String::char_uppercase(p_char); +}; + +godot_string GDAPI godot_string_to_lower(const godot_string *p_self) { + const String *self = (const String *)p_self; + godot_string result; + memnew_placement(&result, String(self->to_lower())); + + return result; +}; + +godot_string GDAPI godot_string_to_upper(const godot_string *p_self) { + const String *self = (const String *)p_self; + godot_string result; + memnew_placement(&result, String(self->to_upper())); + + return result; +}; + +godot_string GDAPI godot_string_get_basename(const godot_string *p_self) { + const String *self = (const String *)p_self; + godot_string result; + memnew_placement(&result, String(self->get_basename())); + + return result; +}; + +godot_string GDAPI godot_string_get_extension(const godot_string *p_self) { + const String *self = (const String *)p_self; + godot_string result; + memnew_placement(&result, String(self->get_extension())); + + return result; +}; + +godot_string GDAPI godot_string_left(const godot_string *p_self, godot_int p_pos) { + const String *self = (const String *)p_self; + godot_string result; + memnew_placement(&result, String(self->left(p_pos))); + + return result; +}; + +wchar_t GDAPI godot_string_ord_at(const godot_string *p_self, godot_int p_idx) { + const String *self = (const String *)p_self; + + return self->ord_at(p_idx); +}; + +godot_string GDAPI godot_string_plus_file(const godot_string *p_self, const godot_string *p_file) { + const String *self = (const String *)p_self; + const String *file = (const String *)p_file; + godot_string result; + memnew_placement(&result, String(self->plus_file(*file))); + + return result; +}; + +godot_string GDAPI godot_string_right(const godot_string *p_self, godot_int p_pos) { + const String *self = (const String *)p_self; + godot_string result; + memnew_placement(&result, String(self->right(p_pos))); + + return result; +}; + +godot_string GDAPI godot_string_strip_edges(const godot_string *p_self, godot_bool p_left, godot_bool p_right) { + const String *self = (const String *)p_self; + godot_string result; + memnew_placement(&result, String(self->strip_edges(p_left, p_right))); + + return result; +}; + +godot_string GDAPI godot_string_strip_escapes(const godot_string *p_self) { + const String *self = (const String *)p_self; + godot_string result; + memnew_placement(&result, String(self->strip_escapes())); + + return result; +}; + +void GDAPI godot_string_erase(godot_string *p_self, godot_int p_pos, godot_int p_chars) { + String *self = (String *)p_self; + + return self->erase(p_pos, p_chars); +}; + +void GDAPI godot_string_ascii(godot_string *p_self, char *result) { + String *self = (String *)p_self; + Vector<char> return_value = self->ascii(); + + for (int i = 0; i < return_value.size(); i++) { + result[i] = return_value[i]; + } +} + +void GDAPI godot_string_ascii_extended(godot_string *p_self, char *result) { + String *self = (String *)p_self; + Vector<char> return_value = self->ascii(true); + + for (int i = 0; i < return_value.size(); i++) { + result[i] = return_value[i]; + } +} + +void GDAPI godot_string_utf8(godot_string *p_self, char *result) { + String *self = (String *)p_self; + Vector<char> return_value = self->utf8(); + + for (int i = 0; i < return_value.size(); i++) { + result[i] = return_value[i]; + } +} + +godot_bool GDAPI godot_string_parse_utf8(godot_string *p_self, const char *p_utf8) { + String *self = (String *)p_self; + + return self->parse_utf8(p_utf8); +}; + +godot_bool GDAPI godot_string_parse_utf8_with_len(godot_string *p_self, const char *p_utf8, godot_int p_len) { + String *self = (String *)p_self; + + return self->parse_utf8(p_utf8, p_len); +}; + +godot_string GDAPI godot_string_chars_to_utf8(const char *p_utf8) { + godot_string result; + memnew_placement(&result, String(String::utf8(p_utf8))); + + return result; +}; + +godot_string GDAPI godot_string_chars_to_utf8_with_len(const char *p_utf8, godot_int p_len) { + godot_string result; + memnew_placement(&result, String(String::utf8(p_utf8, p_len))); + + return result; +}; + +uint32_t GDAPI godot_string_hash(const godot_string *p_self) { + const String *self = (const String *)p_self; + + return self->hash(); +}; + +uint64_t GDAPI godot_string_hash64(const godot_string *p_self) { + const String *self = (const String *)p_self; + + return self->hash64(); +}; + +uint32_t GDAPI godot_string_hash_chars(const char *p_cstr) { + return String::hash(p_cstr); +}; + +uint32_t GDAPI godot_string_hash_chars_with_len(const char *p_cstr, godot_int p_len) { + return String::hash(p_cstr, p_len); +}; + +uint32_t GDAPI godot_string_hash_utf8_chars(const wchar_t *p_str) { + return String::hash(p_str); +}; + +uint32_t GDAPI godot_string_hash_utf8_chars_with_len(const wchar_t *p_str, godot_int p_len) { + return String::hash(p_str, p_len); +}; + +godot_pool_byte_array GDAPI godot_string_md5_buffer(const godot_string *p_self) { + const String *self = (const String *)p_self; + Vector<uint8_t> tmp_result = self->md5_buffer(); + + godot_pool_byte_array result; + memnew_placement(&result, PoolByteArray); + PoolByteArray *proxy = (PoolByteArray *)&result; + PoolByteArray::Write proxy_writer = proxy->write(); + proxy->resize(tmp_result.size()); + + for (int i = 0; i < tmp_result.size(); i++) { + proxy_writer[i] = tmp_result[i]; + } + + return result; +}; + +godot_string GDAPI godot_string_md5_text(const godot_string *p_self) { + const String *self = (const String *)p_self; + godot_string result; + memnew_placement(&result, String(self->md5_text())); + + return result; +}; + +godot_pool_byte_array GDAPI godot_string_sha256_buffer(const godot_string *p_self) { + const String *self = (const String *)p_self; + Vector<uint8_t> tmp_result = self->sha256_buffer(); + + godot_pool_byte_array result; + memnew_placement(&result, PoolByteArray); + PoolByteArray *proxy = (PoolByteArray *)&result; + PoolByteArray::Write proxy_writer = proxy->write(); + proxy->resize(tmp_result.size()); + + for (int i = 0; i < tmp_result.size(); i++) { + proxy_writer[i] = tmp_result[i]; + } + + return result; +}; + +godot_string GDAPI godot_string_sha256_text(const godot_string *p_self) { + const String *self = (const String *)p_self; + godot_string result; + memnew_placement(&result, String(self->sha256_text())); + + return result; +}; + +godot_bool godot_string_empty(const godot_string *p_self) { + const String *self = (const String *)p_self; + + return self->empty(); +}; + +// path functions +godot_string GDAPI godot_string_get_base_dir(const godot_string *p_self) { + const String *self = (const String *)p_self; + godot_string result; + String return_value = self->get_base_dir(); + memnew_placement(&result, String(return_value)); + + return result; +}; + +godot_string GDAPI godot_string_get_file(const godot_string *p_self) { + const String *self = (const String *)p_self; + godot_string result; + String return_value = self->get_file(); + memnew_placement(&result, String(return_value)); + + return result; +}; + +godot_string GDAPI godot_string_humanize_size(size_t p_size) { + godot_string result; + String return_value = String::humanize_size(p_size); + memnew_placement(&result, String(return_value)); + + return result; +}; + +godot_bool GDAPI godot_string_is_abs_path(const godot_string *p_self) { + const String *self = (const String *)p_self; + + return self->is_abs_path(); +}; + +godot_bool GDAPI godot_string_is_rel_path(const godot_string *p_self) { + const String *self = (const String *)p_self; + + return self->is_rel_path(); +}; + +godot_bool GDAPI godot_string_is_resource_file(const godot_string *p_self) { + const String *self = (const String *)p_self; + + return self->is_resource_file(); +}; + +godot_string GDAPI godot_string_path_to(const godot_string *p_self, const godot_string *p_path) { + const String *self = (const String *)p_self; + String *path = (String *)p_path; + godot_string result; + String return_value = self->path_to(*path); + memnew_placement(&result, String(return_value)); + + return result; +}; + +godot_string GDAPI godot_string_path_to_file(const godot_string *p_self, const godot_string *p_path) { + const String *self = (const String *)p_self; + String *path = (String *)p_path; + godot_string result; + String return_value = self->path_to_file(*path); + memnew_placement(&result, String(return_value)); + + return result; +}; + +godot_string GDAPI godot_string_simplify_path(const godot_string *p_self) { + const String *self = (const String *)p_self; + godot_string result; + String return_value = self->simplify_path(); + memnew_placement(&result, String(return_value)); + + return result; +}; + +godot_string GDAPI godot_string_c_escape(const godot_string *p_self) { + const String *self = (const String *)p_self; + godot_string result; + String return_value = self->c_escape(); + memnew_placement(&result, String(return_value)); + + return result; +}; + +godot_string GDAPI godot_string_c_escape_multiline(const godot_string *p_self) { + const String *self = (const String *)p_self; + godot_string result; + String return_value = self->c_escape_multiline(); + memnew_placement(&result, String(return_value)); + + return result; +}; + +godot_string GDAPI godot_string_c_unescape(const godot_string *p_self) { + const String *self = (const String *)p_self; + godot_string result; + String return_value = self->c_unescape(); + memnew_placement(&result, String(return_value)); + + return result; +}; + +godot_string GDAPI godot_string_http_escape(const godot_string *p_self) { + const String *self = (const String *)p_self; + godot_string result; + String return_value = self->http_escape(); + memnew_placement(&result, String(return_value)); + + return result; +}; + +godot_string GDAPI godot_string_http_unescape(const godot_string *p_self) { + const String *self = (const String *)p_self; + godot_string result; + String return_value = self->http_unescape(); + memnew_placement(&result, String(return_value)); + + return result; +}; + +godot_string GDAPI godot_string_json_escape(const godot_string *p_self) { + const String *self = (const String *)p_self; + godot_string result; + String return_value = self->json_escape(); + memnew_placement(&result, String(return_value)); + + return result; +}; + +godot_string GDAPI godot_string_word_wrap(const godot_string *p_self, godot_int p_chars_per_line) { + const String *self = (const String *)p_self; + godot_string result; + String return_value = self->word_wrap(p_chars_per_line); + memnew_placement(&result, String(return_value)); + + return result; +}; + +godot_string GDAPI godot_string_xml_escape(const godot_string *p_self) { + const String *self = (const String *)p_self; + godot_string result; + String return_value = self->xml_escape(); + memnew_placement(&result, String(return_value)); + + return result; +}; + +godot_string GDAPI godot_string_xml_escape_with_quotes(const godot_string *p_self) { + const String *self = (const String *)p_self; + godot_string result; + String return_value = self->xml_escape(true); + memnew_placement(&result, String(return_value)); + + return result; +}; + +godot_string GDAPI godot_string_xml_unescape(const godot_string *p_self) { + const String *self = (const String *)p_self; + godot_string result; + String return_value = self->xml_unescape(); + memnew_placement(&result, String(return_value)); + + return result; +}; + +godot_string GDAPI godot_string_percent_decode(const godot_string *p_self) { + const String *self = (const String *)p_self; + godot_string result; + String return_value = self->percent_decode(); + memnew_placement(&result, String(return_value)); + + return result; +}; + +godot_string GDAPI godot_string_percent_encode(const godot_string *p_self) { + const String *self = (const String *)p_self; + godot_string result; + String return_value = self->percent_encode(); + memnew_placement(&result, String(return_value)); + + return result; +}; + +godot_bool GDAPI godot_string_is_valid_float(const godot_string *p_self) { + const String *self = (const String *)p_self; + + return self->is_valid_float(); +}; + +godot_bool GDAPI godot_string_is_valid_hex_number(const godot_string *p_self, godot_bool p_with_prefix) { + const String *self = (const String *)p_self; + + return self->is_valid_hex_number(p_with_prefix); +}; + +godot_bool GDAPI godot_string_is_valid_html_color(const godot_string *p_self) { + const String *self = (const String *)p_self; + + return self->is_valid_html_color(); +}; + +godot_bool GDAPI godot_string_is_valid_identifier(const godot_string *p_self) { + const String *self = (const String *)p_self; + + return self->is_valid_identifier(); +}; + +godot_bool GDAPI godot_string_is_valid_integer(const godot_string *p_self) { + const String *self = (const String *)p_self; + + return self->is_valid_integer(); +}; + +godot_bool GDAPI godot_string_is_valid_ip_address(const godot_string *p_self) { + const String *self = (const String *)p_self; + + return self->is_valid_ip_address(); +}; + #ifdef __cplusplus } #endif diff --git a/modules/gdnative/godot/string.h b/modules/gdnative/godot/string.h index 9013326454..bfe66aa5ec 100644 --- a/modules/gdnative/godot/string.h +++ b/modules/gdnative/godot/string.h @@ -47,6 +47,7 @@ typedef struct { #endif #include <godot/gdnative.h> +#include <godot/variant.h> void GDAPI godot_string_new(godot_string *r_dest); void GDAPI godot_string_new_copy(godot_string *r_dest, const godot_string *p_src); @@ -63,9 +64,160 @@ godot_bool GDAPI godot_string_operator_equal(const godot_string *p_self, const g godot_bool GDAPI godot_string_operator_less(const godot_string *p_self, const godot_string *p_b); godot_string GDAPI godot_string_operator_plus(const godot_string *p_self, const godot_string *p_b); -// @Incomplete -// hmm, I guess exposing the whole API doesn't make much sense -// since the language used in the library has its own string funcs +/* Standard size stuff */ + +godot_int GDAPI godot_string_length(const godot_string *p_self); + +/* Helpers */ + +godot_bool GDAPI godot_string_begins_with(const godot_string *p_self, const godot_string *p_string); +godot_bool GDAPI godot_string_begins_with_char_array(const godot_string *p_self, const char *p_char_array); +godot_array GDAPI godot_string_bigrams(const godot_string *p_self); +godot_string GDAPI godot_string_chr(wchar_t p_character); +godot_bool GDAPI godot_string_ends_with(const godot_string *p_self, const godot_string *p_string); +godot_int GDAPI godot_string_find(const godot_string *p_self, godot_string p_what); +godot_int GDAPI godot_string_find_from(const godot_string *p_self, godot_string p_what, godot_int p_from); +godot_int GDAPI godot_string_findmk(const godot_string *p_self, const godot_array *p_keys); +godot_int GDAPI godot_string_findmk_from(const godot_string *p_self, const godot_array *p_keys, godot_int p_from); +godot_int GDAPI godot_string_findmk_from_in_place(const godot_string *p_self, const godot_array *p_keys, godot_int p_from, godot_int *r_key); +godot_int GDAPI godot_string_findn(const godot_string *p_self, godot_string p_what); +godot_int GDAPI godot_string_findn_from(const godot_string *p_self, godot_string p_what, godot_int p_from); +godot_int GDAPI find_last(const godot_string *p_self, godot_string p_what); +godot_string GDAPI godot_string_format(const godot_string *p_self, const godot_variant *values); +godot_string GDAPI godot_string_format_with_custom_placeholder(const godot_string *p_self, const godot_variant *values, const char *placeholder); +godot_string GDAPI godot_string_hex_encode_buffer(const uint8_t *p_buffer, godot_int p_len); +godot_int GDAPI godot_string_hex_to_int(const godot_string *p_self); +godot_int GDAPI godot_string_hex_to_int_without_prefix(const godot_string *p_self); +godot_string GDAPI godot_string_insert(const godot_string *p_self, godot_int p_at_pos, godot_string p_string); +godot_bool GDAPI godot_string_is_numeric(const godot_string *p_self); +godot_bool GDAPI godot_string_is_subsequence_of(const godot_string *p_self, const godot_string *p_string); +godot_bool GDAPI godot_string_is_subsequence_ofi(const godot_string *p_self, const godot_string *p_string); +godot_string GDAPI godot_string_lpad(const godot_string *p_self, godot_int p_min_length); +godot_string GDAPI godot_string_lpad_with_custom_character(const godot_string *p_self, godot_int p_min_length, const godot_string *p_character); +godot_bool GDAPI godot_string_match(const godot_string *p_self, const godot_string *p_wildcard); +godot_bool GDAPI godot_string_matchn(const godot_string *p_self, const godot_string *p_wildcard); +godot_string GDAPI godot_string_md5(const uint8_t *p_md5); +godot_string GDAPI godot_string_num(double p_num); +godot_string GDAPI godot_string_num_int64(int64_t p_num, godot_int p_base); +godot_string GDAPI godot_string_num_int64_capitalized(int64_t p_num, godot_int p_base, godot_bool p_capitalize_hex); +godot_string GDAPI godot_string_num_real(double p_num); +godot_string GDAPI godot_string_num_scientific(double p_num); +godot_string GDAPI godot_string_num_with_decimals(double p_num, godot_int p_decimals); +godot_string GDAPI godot_string_pad_decimals(const godot_string *p_self, godot_int p_digits); +godot_string GDAPI godot_string_pad_zeros(const godot_string *p_self, godot_int p_digits); +godot_string GDAPI godot_string_replace_first(const godot_string *p_self, godot_string p_key, godot_string p_with); +godot_string GDAPI godot_string_replace(const godot_string *p_self, godot_string p_key, godot_string p_with); +godot_string GDAPI godot_string_replacen(const godot_string *p_self, godot_string p_key, godot_string p_with); +godot_int GDAPI godot_string_rfind(const godot_string *p_self, godot_string p_what); +godot_int GDAPI godot_string_rfindn(const godot_string *p_self, godot_string p_what); +godot_int GDAPI godot_string_rfind_from(const godot_string *p_self, godot_string p_what, godot_int p_from); +godot_int GDAPI godot_string_rfindn_from(const godot_string *p_self, godot_string p_what, godot_int p_from); +godot_string GDAPI godot_string_rpad(const godot_string *p_self, godot_int p_min_length); +godot_string GDAPI godot_string_rpad_with_custom_character(const godot_string *p_self, godot_int p_min_length, const godot_string *p_character); +godot_real GDAPI godot_string_similarity(const godot_string *p_self, const godot_string *p_string); +godot_string GDAPI godot_string_sprintf(const godot_string *p_self, const godot_array *p_values, godot_bool *p_error); +godot_string GDAPI godot_string_substr(const godot_string *p_self, godot_int p_from, godot_int p_chars); +double GDAPI godot_string_to_double(const godot_string *p_self); +godot_real GDAPI godot_string_to_float(const godot_string *p_self); +godot_int GDAPI godot_string_to_int(const godot_string *p_self); + +godot_string GDAPI godot_string_camelcase_to_underscore(const godot_string *p_self); +godot_string GDAPI godot_string_camelcase_to_underscore_lowercased(const godot_string *p_self); +godot_string GDAPI godot_string_capitalize(const godot_string *p_self); +double GDAPI godot_string_char_to_double(const char *p_what); +godot_int GDAPI godot_string_char_to_int(const char *p_what); +int64_t GDAPI godot_string_wchar_to_int(const wchar_t *p_str); +godot_int GDAPI godot_string_char_to_int_with_len(const char *p_what, godot_int p_len); +int64_t GDAPI godot_string_char_to_int64_with_len(const wchar_t *p_str, int p_len); +int64_t GDAPI godot_string_hex_to_int64(const godot_string *p_self); +int64_t GDAPI godot_string_hex_to_int64_with_prefix(const godot_string *p_self); +int64_t GDAPI godot_string_to_int64(const godot_string *p_self); +double GDAPI godot_string_unicode_char_to_double(const wchar_t *p_str, const wchar_t **r_end); + +godot_int GDAPI godot_string_get_slice_count(const godot_string *p_self, godot_string p_splitter); +godot_string GDAPI godot_string_get_slice(const godot_string *p_self, godot_string p_splitter, godot_int p_slice); +godot_string GDAPI godot_string_get_slicec(const godot_string *p_self, wchar_t p_splitter, godot_int p_slice); + +godot_array GDAPI godot_string_split(const godot_string *p_self, const godot_string *p_splitter); +godot_array GDAPI godot_string_split_allow_empty(const godot_string *p_self, const godot_string *p_splitter); +godot_array GDAPI godot_string_split_floats(const godot_string *p_self, const godot_string *p_splitter); +godot_array GDAPI godot_string_split_floats_allows_empty(const godot_string *p_self, const godot_string *p_splitter); +godot_array GDAPI godot_string_split_floats_mk(const godot_string *p_self, const godot_array *p_splitters); +godot_array GDAPI godot_string_split_floats_mk_allows_empty(const godot_string *p_self, const godot_array *p_splitters); +godot_array GDAPI godot_string_split_ints(const godot_string *p_self, const godot_string *p_splitter); +godot_array GDAPI godot_string_split_ints_allows_empty(const godot_string *p_self, const godot_string *p_splitter); +godot_array GDAPI godot_string_split_ints_mk(const godot_string *p_self, const godot_array *p_splitters); +godot_array GDAPI godot_string_split_ints_mk_allows_empty(const godot_string *p_self, const godot_array *p_splitters); +godot_array GDAPI godot_string_split_spaces(const godot_string *p_self); + +wchar_t GDAPI godot_string_char_lowercase(wchar_t p_char); +wchar_t GDAPI godot_string_char_uppercase(wchar_t p_char); +godot_string GDAPI godot_string_to_lower(const godot_string *p_self); +godot_string GDAPI godot_string_to_upper(const godot_string *p_self); + +godot_string GDAPI godot_string_get_basename(const godot_string *p_self); +godot_string GDAPI godot_string_get_extension(const godot_string *p_self); +godot_string GDAPI godot_string_left(const godot_string *p_self, godot_int p_pos); +wchar_t GDAPI godot_string_ord_at(const godot_string *p_self, godot_int p_idx); +godot_string GDAPI godot_string_plus_file(const godot_string *p_self, const godot_string *p_file); +godot_string GDAPI godot_string_right(const godot_string *p_self, godot_int p_pos); +godot_string GDAPI godot_string_strip_edges(const godot_string *p_self, godot_bool p_left, godot_bool p_right); +godot_string GDAPI godot_string_strip_escapes(const godot_string *p_self); + +void GDAPI godot_string_erase(godot_string *p_self, godot_int p_pos, godot_int p_chars); + +void GDAPI godot_string_ascii(godot_string *p_self, char *result); +void GDAPI godot_string_ascii_extended(godot_string *p_self, char *result); +void GDAPI godot_string_utf8(godot_string *p_self, char *result); +godot_bool GDAPI godot_string_parse_utf8(godot_string *p_self, const char *p_utf8); +godot_bool GDAPI godot_string_parse_utf8_with_len(godot_string *p_self, const char *p_utf8, godot_int p_len); +godot_string GDAPI godot_string_chars_to_utf8(const char *p_utf8); +godot_string GDAPI godot_string_chars_utf8_with_len(const char *p_utf8, godot_int p_len); + +uint32_t GDAPI godot_string_hash(const godot_string *p_self); +uint64_t GDAPI godot_string_hash64(const godot_string *p_self); +uint32_t GDAPI godot_string_hash_chars(const char *p_cstr); +uint32_t GDAPI godot_string_hash_chars_with_len(const char *p_cstr, godot_int p_len); +uint32_t GDAPI godot_string_hash_utf8_chars(const wchar_t *p_str); +uint32_t GDAPI godot_string_hash_utf8_chars_with_len(const wchar_t *p_str, godot_int p_len); +godot_pool_byte_array GDAPI godot_string_md5_buffer(const godot_string *p_self); +godot_string GDAPI godot_string_md5_text(const godot_string *p_self); +godot_pool_byte_array GDAPI godot_string_sha256_buffer(const godot_string *p_self); +godot_string GDAPI godot_string_sha256_text(const godot_string *p_self); + +godot_bool godot_string_empty(const godot_string *p_self); + +// path functions +godot_string GDAPI godot_string_get_base_dir(const godot_string *p_self); +godot_string GDAPI godot_string_get_file(const godot_string *p_self); +godot_string GDAPI godot_string_humanize_size(size_t p_size); +godot_bool GDAPI godot_string_is_abs_path(const godot_string *p_self); +godot_bool GDAPI godot_string_is_rel_path(const godot_string *p_self); +godot_bool GDAPI godot_string_is_resource_file(const godot_string *p_self); +godot_string GDAPI godot_string_path_to(const godot_string *p_self, const godot_string *p_path); +godot_string GDAPI godot_string_path_to_file(const godot_string *p_self, const godot_string *p_path); +godot_string GDAPI godot_string_simplify_path(const godot_string *p_self); + +godot_string GDAPI godot_string_c_escape(const godot_string *p_self); +godot_string GDAPI godot_string_c_escape_multiline(const godot_string *p_self); +godot_string GDAPI godot_string_c_unescape(const godot_string *p_self); +godot_string GDAPI godot_string_http_escape(const godot_string *p_self); +godot_string GDAPI godot_string_http_unescape(const godot_string *p_self); +godot_string GDAPI godot_string_json_escape(const godot_string *p_self); +godot_string GDAPI godot_string_word_wrap(const godot_string *p_self, godot_int p_chars_per_line); +godot_string GDAPI godot_string_xml_escape(const godot_string *p_self); +godot_string GDAPI godot_string_xml_escape_with_quotes(const godot_string *p_self); +godot_string GDAPI godot_string_xml_unescape(const godot_string *p_self); + +godot_string GDAPI godot_string_percent_decode(const godot_string *p_self); +godot_string GDAPI godot_string_percent_encode(const godot_string *p_self); + +godot_bool GDAPI godot_string_is_valid_float(const godot_string *p_self); +godot_bool GDAPI godot_string_is_valid_hex_number(const godot_string *p_self, godot_bool p_with_prefix); +godot_bool GDAPI godot_string_is_valid_html_color(const godot_string *p_self); +godot_bool GDAPI godot_string_is_valid_identifier(const godot_string *p_self); +godot_bool GDAPI godot_string_is_valid_integer(const godot_string *p_self); +godot_bool GDAPI godot_string_is_valid_ip_address(const godot_string *p_self); void GDAPI godot_string_destroy(godot_string *p_self); diff --git a/modules/gdscript/gd_functions.cpp b/modules/gdscript/gd_functions.cpp index 8bc3b24a5e..209bdadd67 100644 --- a/modules/gdscript/gd_functions.cpp +++ b/modules/gdscript/gd_functions.cpp @@ -113,6 +113,7 @@ const char *GDFunctions::get_func_name(Function p_func) { "ColorN", "print_stack", "instance_from_id", + "len", }; return _names[p_func]; @@ -1154,6 +1155,62 @@ void GDFunctions::call(Function p_func, const Variant **p_args, int p_arg_count, r_ret = ObjectDB::get_instance(id); } break; + case LEN: { + + VALIDATE_ARG_COUNT(1); + switch (p_args[0]->get_type()) { + case Variant::DICTIONARY: { + Dictionary d = *p_args[0]; + r_ret = d.size(); + } break; + case Variant::ARRAY: { + Array d = *p_args[0]; + r_ret = d.size(); + } break; + case Variant::POOL_BYTE_ARRAY: { + PoolVector<uint8_t> d = *p_args[0]; + r_ret = d.size(); + + } break; + case Variant::POOL_INT_ARRAY: { + PoolVector<int> d = *p_args[0]; + r_ret = d.size(); + } break; + case Variant::POOL_REAL_ARRAY: { + + PoolVector<real_t> d = *p_args[0]; + r_ret = d.size(); + } break; + case Variant::POOL_STRING_ARRAY: { + PoolVector<String> d = *p_args[0]; + r_ret = d.size(); + + } break; + case Variant::POOL_VECTOR2_ARRAY: { + PoolVector<Vector2> d = *p_args[0]; + r_ret = d.size(); + + } break; + case Variant::POOL_VECTOR3_ARRAY: { + + PoolVector<Vector3> d = *p_args[0]; + r_ret = d.size(); + } break; + case Variant::POOL_COLOR_ARRAY: { + + PoolVector<Color> d = *p_args[0]; + r_ret = d.size(); + } break; + default: { + r_error.error = Variant::CallError::CALL_ERROR_INVALID_ARGUMENT; + r_error.argument = 0; + r_error.expected = Variant::OBJECT; + r_ret = Variant(); + r_ret = RTR("Object can't provide a length."); + } + } + + } break; case FUNC_MAX: { ERR_FAIL(); @@ -1210,6 +1267,7 @@ bool GDFunctions::is_deterministic(Function p_func) { case TEXT_CHAR: case TEXT_STR: case COLOR8: + case LEN: // enable for debug only, otherwise not desirable - case GEN_RANGE: return true; default: @@ -1621,6 +1679,11 @@ MethodInfo GDFunctions::get_info(Function p_func) { mi.return_val.type = Variant::OBJECT; return mi; } break; + case LEN: { + MethodInfo mi("len", PropertyInfo(Variant::NIL, "var")); + mi.return_val.type = Variant::INT; + return mi; + } break; case FUNC_MAX: { diff --git a/modules/gdscript/gd_functions.h b/modules/gdscript/gd_functions.h index 4d52abaeab..93cb524118 100644 --- a/modules/gdscript/gd_functions.h +++ b/modules/gdscript/gd_functions.h @@ -105,6 +105,7 @@ public: COLORN, PRINT_STACK, INSTANCE_FROM_ID, + LEN, FUNC_MAX }; diff --git a/modules/gdscript/gd_parser.cpp b/modules/gdscript/gd_parser.cpp index 36aa249398..9023fd4bf4 100644 --- a/modules/gdscript/gd_parser.cpp +++ b/modules/gdscript/gd_parser.cpp @@ -2369,8 +2369,7 @@ void GDParser::_parse_block(BlockNode *p_block, bool p_static) { check_block = check_block->parent_block; } - p_block->variables.push_back(n); //line? - p_block->variable_lines.push_back(tokenizer->get_token_line()); + int var_line = tokenizer->get_token_line(); //must know when the local variable is declared LocalVarNode *lv = alloc_node<LocalVarNode>(); @@ -2400,6 +2399,10 @@ void GDParser::_parse_block(BlockNode *p_block, bool p_static) { c->value = Variant(); assigned = c; } + //must be added later, to avoid self-referencing. + p_block->variables.push_back(n); //line? + p_block->variable_lines.push_back(var_line); + IdentifierNode *id = alloc_node<IdentifierNode>(); id->name = n; diff --git a/modules/nativescript/nativescript.cpp b/modules/nativescript/nativescript.cpp index f00917bcea..e2717b8448 100644 --- a/modules/nativescript/nativescript.cpp +++ b/modules/nativescript/nativescript.cpp @@ -77,14 +77,12 @@ void NativeScript::_update_placeholder(PlaceHolderScriptInstance *p_placeholder) ERR_FAIL_COND(!script_data); List<PropertyInfo> info; + get_script_property_list(&info); Map<StringName, Variant> values; - - for (Map<StringName, NativeScriptDesc::Property>::Element *E = script_data->properties.front(); E; E = E->next()) { - PropertyInfo p = E->get().info; - p.name = String(E->key()); - - info.push_back(p); - values[p.name] = E->get().default_value; + for (List<PropertyInfo>::Element *E = info.front(); E; E = E->next()) { + Variant value; + get_property_default_value(E->get().name, value); + values[E->get().name] = value; } p_placeholder->update(info, values); @@ -317,11 +315,11 @@ void NativeScript::get_script_signal_list(List<MethodInfo> *r_signals) const { bool NativeScript::get_property_default_value(const StringName &p_property, Variant &r_value) const { NativeScriptDesc *script_data = get_script_desc(); - if (!script_data) - return false; - - Map<StringName, NativeScriptDesc::Property>::Element *P = script_data->properties.find(p_property); - + Map<StringName, NativeScriptDesc::Property>::Element *P = NULL; + while (!P && script_data) { + P = script_data->properties.find(p_property); + script_data = script_data->base_data; + } if (!P) return false; diff --git a/modules/visual_script/visual_script.cpp b/modules/visual_script/visual_script.cpp index 376329715b..7a368fbace 100644 --- a/modules/visual_script/visual_script.cpp +++ b/modules/visual_script/visual_script.cpp @@ -1058,6 +1058,10 @@ MethodInfo VisualScript::get_method_info(const StringName &p_method) const { arg.type = func->get_argument_type(i); mi.arguments.push_back(arg); } + + if (!func->is_sequenced()) { + mi.flags |= METHOD_FLAG_CONST; + } } } @@ -1401,6 +1405,10 @@ void VisualScriptInstance::get_method_list(List<MethodInfo> *p_list) const { mi.arguments.push_back(arg); } + if (!vsf->is_sequenced()) { //assumed constant if not sequenced + mi.flags |= METHOD_FLAG_CONST; + } + //vsf->Get_ for now at least it does not return.. } } diff --git a/modules/visual_script/visual_script_editor.cpp b/modules/visual_script/visual_script_editor.cpp index a71d38f7a0..8912227692 100644 --- a/modules/visual_script/visual_script_editor.cpp +++ b/modules/visual_script/visual_script_editor.cpp @@ -869,15 +869,27 @@ void VisualScriptEditor::_member_edited() { } selected = new_name; - _update_graph(); - + int node_id = script->get_function_node_id(name); + Ref<VisualScriptFunction> func; + if (script->has_node(name, node_id)) { + func = script->get_node(name, node_id); + } undo_redo->create_action(TTR("Rename Function")); undo_redo->add_do_method(script.ptr(), "rename_function", name, new_name); undo_redo->add_undo_method(script.ptr(), "rename_function", new_name, name); + if (func.is_valid()) { + + undo_redo->add_do_method(func.ptr(), "set_name", new_name); + undo_redo->add_undo_method(func.ptr(), "set_name", name); + } undo_redo->add_do_method(this, "_update_members"); undo_redo->add_undo_method(this, "_update_members"); + undo_redo->add_do_method(this, "_update_graph"); + undo_redo->add_undo_method(this, "_update_graph"); undo_redo->commit_action(); + // _update_graph(); + return; //or crash because it will become invalid } diff --git a/modules/visual_script/visual_script_nodes.cpp b/modules/visual_script/visual_script_nodes.cpp index d5d8b8fe6e..4fefa01584 100644 --- a/modules/visual_script/visual_script_nodes.cpp +++ b/modules/visual_script/visual_script_nodes.cpp @@ -95,6 +95,12 @@ bool VisualScriptFunction::_set(const StringName &p_name, const Variant &p_value return true; } + if (p_name == "sequenced/sequenced") { + sequenced = p_value; + ports_changed_notify(); + return true; + } + return false; } @@ -133,6 +139,11 @@ bool VisualScriptFunction::_get(const StringName &p_name, Variant &r_ret) const return true; } + if (p_name == "sequenced/sequenced") { + r_ret = sequenced; + return true; + } + return false; } void VisualScriptFunction::_get_property_list(List<PropertyInfo> *p_list) const { @@ -147,6 +158,9 @@ void VisualScriptFunction::_get_property_list(List<PropertyInfo> *p_list) const p_list->push_back(PropertyInfo(Variant::INT, "argument_" + itos(i + 1) + "/type", PROPERTY_HINT_ENUM, argt)); p_list->push_back(PropertyInfo(Variant::STRING, "argument_" + itos(i + 1) + "/name")); } + + p_list->push_back(PropertyInfo(Variant::BOOL, "sequenced/sequenced")); + if (!stack_less) { p_list->push_back(PropertyInfo(Variant::INT, "stack/size", PROPERTY_HINT_RANGE, "1,100000")); } @@ -302,6 +316,7 @@ VisualScriptFunction::VisualScriptFunction() { stack_size = 256; stack_less = false; + sequenced = true; rpc_mode = ScriptInstance::RPC_MODE_DISABLED; } @@ -314,6 +329,16 @@ bool VisualScriptFunction::is_stack_less() const { return stack_less; } +void VisualScriptFunction::set_sequenced(bool p_enable) { + + sequenced = p_enable; +} + +bool VisualScriptFunction::is_sequenced() const { + + return sequenced; +} + void VisualScriptFunction::set_stack_size(int p_size) { ERR_FAIL_COND(p_size < 1 || p_size > 100000); @@ -1467,7 +1492,7 @@ void VisualScriptGlobalConstant::_bind_methods() { cc += ","; cc += GlobalConstants::get_global_constant_name(i); } - ADD_PROPERTY(PropertyInfo(Variant::INT, "constant", PROPERTY_HINT_ENUM, cc), "set_global_constant", "get_global_constant"); + ADD_PROPERTY(PropertyInfo(Variant::INT, "constant/constant", PROPERTY_HINT_ENUM, cc), "set_global_constant", "get_global_constant"); } VisualScriptGlobalConstant::VisualScriptGlobalConstant() { @@ -1572,7 +1597,7 @@ VisualScriptNodeInstance *VisualScriptClassConstant::instance(VisualScriptInstan void VisualScriptClassConstant::_validate_property(PropertyInfo &property) const { - if (property.name == "constant") { + if (property.name == "constant/constant") { List<String> constants; ClassDB::get_integer_constant_list(base_type, &constants, true); @@ -1596,7 +1621,7 @@ void VisualScriptClassConstant::_bind_methods() { ClassDB::bind_method(D_METHOD("get_base_type"), &VisualScriptClassConstant::get_base_type); ADD_PROPERTY(PropertyInfo(Variant::STRING, "base_type", PROPERTY_HINT_TYPE_STRING, "Object"), "set_base_type", "get_base_type"); - ADD_PROPERTY(PropertyInfo(Variant::STRING, "constant", PROPERTY_HINT_ENUM, ""), "set_class_constant", "get_class_constant"); + ADD_PROPERTY(PropertyInfo(Variant::STRING, "constant/constant", PROPERTY_HINT_ENUM, ""), "set_class_constant", "get_class_constant"); } VisualScriptClassConstant::VisualScriptClassConstant() { @@ -1701,7 +1726,7 @@ VisualScriptNodeInstance *VisualScriptBasicTypeConstant::instance(VisualScriptIn void VisualScriptBasicTypeConstant::_validate_property(PropertyInfo &property) const { - if (property.name == "constant") { + if (property.name == "constant/constant") { List<StringName> constants; Variant::get_numeric_constants_for_type(type, &constants); @@ -1734,7 +1759,7 @@ void VisualScriptBasicTypeConstant::_bind_methods() { } ADD_PROPERTY(PropertyInfo(Variant::INT, "basic_type", PROPERTY_HINT_ENUM, argt), "set_basic_type", "get_basic_type"); - ADD_PROPERTY(PropertyInfo(Variant::STRING, "constant", PROPERTY_HINT_ENUM, ""), "set_basic_type_constant", "get_basic_type_constant"); + ADD_PROPERTY(PropertyInfo(Variant::STRING, "constant/constant", PROPERTY_HINT_ENUM, ""), "set_basic_type_constant", "get_basic_type_constant"); } VisualScriptBasicTypeConstant::VisualScriptBasicTypeConstant() { @@ -1855,7 +1880,7 @@ void VisualScriptMathConstant::_bind_methods() { cc += ","; cc += const_name[i]; } - ADD_PROPERTY(PropertyInfo(Variant::INT, "constant", PROPERTY_HINT_ENUM, cc), "set_math_constant", "get_math_constant"); + ADD_PROPERTY(PropertyInfo(Variant::INT, "constant/constant", PROPERTY_HINT_ENUM, cc), "set_math_constant", "get_math_constant"); } VisualScriptMathConstant::VisualScriptMathConstant() { @@ -1976,7 +2001,7 @@ void VisualScriptEngineSingleton::_bind_methods() { cc += E->get().name; } - ADD_PROPERTY(PropertyInfo(Variant::STRING, "constant", PROPERTY_HINT_ENUM, cc), "set_singleton", "get_singleton"); + ADD_PROPERTY(PropertyInfo(Variant::STRING, "constant/constant", PROPERTY_HINT_ENUM, cc), "set_singleton", "get_singleton"); } VisualScriptEngineSingleton::VisualScriptEngineSingleton() { @@ -3702,11 +3727,11 @@ void register_visual_script_nodes() { VisualScriptLanguage::singleton->add_register_func("data/preload", create_node_generic<VisualScriptPreload>); VisualScriptLanguage::singleton->add_register_func("data/action", create_node_generic<VisualScriptInputAction>); - VisualScriptLanguage::singleton->add_register_func("constants/constant", create_node_generic<VisualScriptConstant>); - VisualScriptLanguage::singleton->add_register_func("constants/math_constant", create_node_generic<VisualScriptMathConstant>); - VisualScriptLanguage::singleton->add_register_func("constants/class_constant", create_node_generic<VisualScriptClassConstant>); - VisualScriptLanguage::singleton->add_register_func("constants/global_constant", create_node_generic<VisualScriptGlobalConstant>); - VisualScriptLanguage::singleton->add_register_func("constants/basic_type_constant", create_node_generic<VisualScriptBasicTypeConstant>); + VisualScriptLanguage::singleton->add_register_func("constant/constants/constant", create_node_generic<VisualScriptConstant>); + VisualScriptLanguage::singleton->add_register_func("constant/constants/math_constant", create_node_generic<VisualScriptMathConstant>); + VisualScriptLanguage::singleton->add_register_func("constant/constants/class_constant", create_node_generic<VisualScriptClassConstant>); + VisualScriptLanguage::singleton->add_register_func("constant/constants/global_constant", create_node_generic<VisualScriptGlobalConstant>); + VisualScriptLanguage::singleton->add_register_func("constant/constants/basic_type_constant", create_node_generic<VisualScriptBasicTypeConstant>); VisualScriptLanguage::singleton->add_register_func("custom/custom_node", create_node_generic<VisualScriptCustomNode>); VisualScriptLanguage::singleton->add_register_func("custom/sub_call", create_node_generic<VisualScriptSubCall>); diff --git a/modules/visual_script/visual_script_nodes.h b/modules/visual_script/visual_script_nodes.h index 7a3b26fe55..ff49417114 100644 --- a/modules/visual_script/visual_script_nodes.h +++ b/modules/visual_script/visual_script_nodes.h @@ -46,6 +46,7 @@ class VisualScriptFunction : public VisualScriptNode { bool stack_less; int stack_size; ScriptInstance::RPCMode rpc_mode; + bool sequenced; protected: bool _set(const StringName &p_name, const Variant &p_value); @@ -79,9 +80,18 @@ public: void set_stack_less(bool p_enable); bool is_stack_less() const; + void set_sequenced(bool p_enable); + bool is_sequenced() const; + void set_stack_size(int p_size); int get_stack_size() const; + void set_return_type_enabled(bool p_returns); + bool is_return_type_enabled() const; + + void set_return_type(Variant::Type p_type); + Variant::Type get_return_type() const; + void set_rpc_mode(ScriptInstance::RPCMode p_mode); ScriptInstance::RPCMode get_rpc_mode() const; diff --git a/platform/android/os_android.cpp b/platform/android/os_android.cpp index e3f982ff94..a027e78de9 100644 --- a/platform/android/os_android.cpp +++ b/platform/android/os_android.cpp @@ -135,7 +135,7 @@ void OS_Android::initialize(const VideoMode &p_desired, int p_video_driver, int visual_server = memnew(VisualServerWrapMT(visual_server, false)); };*/ visual_server->init(); - visual_server->cursor_set_visible(false, 0); + // visual_server->cursor_set_visible(false, 0); AudioDriverManager::get_driver(p_audio_driver)->set_singleton(); diff --git a/platform/iphone/os_iphone.cpp b/platform/iphone/os_iphone.cpp index b202a993ff..df497349ae 100644 --- a/platform/iphone/os_iphone.cpp +++ b/platform/iphone/os_iphone.cpp @@ -119,7 +119,7 @@ void OSIPhone::initialize(const VideoMode &p_desired, int p_video_driver, int p_ */ visual_server->init(); - visual_server->cursor_set_visible(false, 0); + // visual_server->cursor_set_visible(false, 0); // reset this to what it should be, it will have been set to 0 after visual_server->init() is called RasterizerStorageGLES3::system_fbo = gl_view_base_fb; diff --git a/platform/javascript/os_javascript.cpp b/platform/javascript/os_javascript.cpp index 5513fca809..d339baf024 100644 --- a/platform/javascript/os_javascript.cpp +++ b/platform/javascript/os_javascript.cpp @@ -476,7 +476,7 @@ void OS_JavaScript::initialize(const VideoMode &p_desired, int p_video_driver, i print_line("Init VS"); visual_server = memnew(VisualServerRaster()); - visual_server->cursor_set_visible(false, 0); + // visual_server->cursor_set_visible(false, 0); print_line("Init Physicsserver"); diff --git a/platform/osx/os_osx.mm b/platform/osx/os_osx.mm index a34f6cc5dd..e884058052 100644 --- a/platform/osx/os_osx.mm +++ b/platform/osx/os_osx.mm @@ -956,7 +956,7 @@ void OS_OSX::initialize(const VideoMode &p_desired, int p_video_driver, int p_au visual_server = memnew(VisualServerWrapMT(visual_server, get_render_thread_mode() == RENDER_SEPARATE_THREAD)); } visual_server->init(); - visual_server->cursor_set_visible(false, 0); + // visual_server->cursor_set_visible(false, 0); AudioDriverManager::get_driver(p_audio_driver)->set_singleton(); diff --git a/scene/2d/particles_2d.cpp b/scene/2d/particles_2d.cpp index b56f4f9ad9..572195b570 100644 --- a/scene/2d/particles_2d.cpp +++ b/scene/2d/particles_2d.cpp @@ -300,6 +300,15 @@ void Particles2D::_notification(int p_what) { #endif } + if (p_what == NOTIFICATION_PAUSED || p_what == NOTIFICATION_UNPAUSED) { + if (can_process()) { + VS::get_singleton()->particles_set_speed_scale(particles, speed_scale); + } else { + + VS::get_singleton()->particles_set_speed_scale(particles, 0); + } + } + if (p_what == NOTIFICATION_TRANSFORM_CHANGED) { _update_particle_emission_transform(); } diff --git a/scene/3d/particles.cpp b/scene/3d/particles.cpp index c8f45a8d7e..bab23d013b 100644 --- a/scene/3d/particles.cpp +++ b/scene/3d/particles.cpp @@ -266,6 +266,18 @@ void Particles::_validate_property(PropertyInfo &property) const { } } +void Particles::_notification(int p_what) { + + if (p_what == NOTIFICATION_PAUSED || p_what == NOTIFICATION_UNPAUSED) { + if (can_process()) { + VS::get_singleton()->particles_set_speed_scale(particles, speed_scale); + } else { + + VS::get_singleton()->particles_set_speed_scale(particles, 0); + } + } +} + void Particles::_bind_methods() { ClassDB::bind_method(D_METHOD("set_emitting", "emitting"), &Particles::set_emitting); diff --git a/scene/3d/particles.h b/scene/3d/particles.h index 0549eb4c09..31ca85a59a 100644 --- a/scene/3d/particles.h +++ b/scene/3d/particles.h @@ -78,6 +78,7 @@ private: protected: static void _bind_methods(); + void _notification(int p_what); virtual void _validate_property(PropertyInfo &property) const; public: diff --git a/scene/3d/spatial.cpp b/scene/3d/spatial.cpp index 6106b0904a..2f2dd12a18 100644 --- a/scene/3d/spatial.cpp +++ b/scene/3d/spatial.cpp @@ -72,8 +72,12 @@ SpatialGizmo::SpatialGizmo() { void Spatial::_notify_dirty() { +#ifdef TOOLS_ENABLED + if ((data.gizmo.is_valid() || data.notify_transform) && !data.ignore_notification && !xform_change.in_list()) { +#else if (data.notify_transform && !data.ignore_notification && !xform_change.in_list()) { +#endif get_tree()->xform_change_list.add(&xform_change); } } @@ -104,9 +108,11 @@ void Spatial::_propagate_transform_changed(Spatial *p_origin) { continue; //don't propagate to a toplevel E->get()->_propagate_transform_changed(p_origin); } - +#ifdef TOOLS_ENABLED + if ((data.gizmo.is_valid() || data.notify_transform) && !data.ignore_notification && !xform_change.in_list()) { +#else if (data.notify_transform && !data.ignore_notification && !xform_change.in_list()) { - +#endif get_tree()->xform_change_list.add(&xform_change); } data.dirty |= DIRTY_GLOBAL; diff --git a/scene/3d/sprite_3d.cpp b/scene/3d/sprite_3d.cpp index 1b9b58ceb1..b4e045e43f 100644 --- a/scene/3d/sprite_3d.cpp +++ b/scene/3d/sprite_3d.cpp @@ -389,7 +389,7 @@ void Sprite3D::_draw() { int axis = get_axis(); normal[axis] = 1.0; - RID mat = VS::get_singleton()->material_2d_get(get_draw_flag(FLAG_SHADED), get_draw_flag(FLAG_TRANSPARENT), get_draw_flag(FLAG_DOUBLE_SIDED), get_alpha_cut_mode() == ALPHA_CUT_DISCARD, get_alpha_cut_mode() == ALPHA_CUT_OPAQUE_PREPASS); + RID mat = SpatialMaterial::get_material_rid_for_2d(get_draw_flag(FLAG_SHADED), get_draw_flag(FLAG_TRANSPARENT), get_draw_flag(FLAG_DOUBLE_SIDED), get_alpha_cut_mode() == ALPHA_CUT_DISCARD, get_alpha_cut_mode() == ALPHA_CUT_OPAQUE_PREPASS); VS::get_singleton()->immediate_set_material(immediate, mat); VS::get_singleton()->immediate_begin(immediate, VS::PRIMITIVE_TRIANGLE_FAN, texture->get_rid()); @@ -892,7 +892,8 @@ void AnimatedSprite3D::_draw() { int axis = get_axis(); normal[axis] = 1.0; - RID mat = VS::get_singleton()->material_2d_get(get_draw_flag(FLAG_SHADED), get_draw_flag(FLAG_TRANSPARENT), get_draw_flag(FLAG_DOUBLE_SIDED), get_alpha_cut_mode() == ALPHA_CUT_DISCARD, get_alpha_cut_mode() == ALPHA_CUT_OPAQUE_PREPASS); + RID mat = SpatialMaterial::get_material_rid_for_2d(get_draw_flag(FLAG_SHADED), get_draw_flag(FLAG_TRANSPARENT), get_draw_flag(FLAG_DOUBLE_SIDED), get_alpha_cut_mode() == ALPHA_CUT_DISCARD, get_alpha_cut_mode() == ALPHA_CUT_OPAQUE_PREPASS); + VS::get_singleton()->immediate_set_material(immediate, mat); VS::get_singleton()->immediate_begin(immediate, VS::PRIMITIVE_TRIANGLE_FAN, texture->get_rid()); diff --git a/scene/gui/graph_edit.cpp b/scene/gui/graph_edit.cpp index 11f750ea70..32725ebb8c 100644 --- a/scene/gui/graph_edit.cpp +++ b/scene/gui/graph_edit.cpp @@ -207,9 +207,10 @@ void GraphEdit::_graph_node_raised(Node *p_gn) { GraphNode *gn = p_gn->cast_to<GraphNode>(); ERR_FAIL_COND(!gn); - gn->raise(); if (gn->is_comment()) { move_child(gn, 0); + } else { + gn->raise(); } int first_not_comment = 0; for (int i = 0; i < get_child_count(); i++) { @@ -870,21 +871,19 @@ void GraphEdit::_gui_input(const Ref<InputEvent> &p_ev) { if (b->get_button_index() == BUTTON_LEFT && b->is_pressed()) { GraphNode *gn = NULL; - GraphNode *gn_selected = NULL; + for (int i = get_child_count() - 1; i >= 0; i--) { - gn_selected = get_child(i)->cast_to<GraphNode>(); + GraphNode *gn_selected = get_child(i)->cast_to<GraphNode>(); if (gn_selected) { - if (gn_selected->is_resizing()) continue; - Rect2 r = gn_selected->get_rect(); - r.size *= zoom; - if (r.has_point(get_local_mouse_pos())) + if (gn_selected->has_point(gn_selected->get_local_mouse_pos())) { gn = gn_selected; - break; + break; + } } } @@ -1225,6 +1224,7 @@ GraphEdit::GraphEdit() { connections_layer->connect("draw", this, "_connections_layer_draw"); connections_layer->set_name("CLAYER"); connections_layer->set_disable_visibility_clip(true); // so it can draw freely and be offseted + connections_layer->set_mouse_filter(MOUSE_FILTER_IGNORE); h_scroll = memnew(HScrollBar); h_scroll->set_name("_h_scroll"); diff --git a/scene/gui/graph_node.cpp b/scene/gui/graph_node.cpp index 538dd846e4..4f07d21f4d 100644 --- a/scene/gui/graph_node.cpp +++ b/scene/gui/graph_node.cpp @@ -176,6 +176,7 @@ bool GraphNode::has_point(const Point2 &p_point) const { if (Rect2(get_size() - resizer->get_size(), resizer->get_size()).has_point(p_point)) { return true; } + if (Rect2(0, 0, get_size().width, comment->get_margin(MARGIN_TOP)).has_point(p_point)) { return true; } @@ -719,7 +720,7 @@ GraphNode::GraphNode() { overlay = OVERLAY_DISABLED; show_close = false; connpos_dirty = true; - set_mouse_filter(MOUSE_FILTER_PASS); + set_mouse_filter(MOUSE_FILTER_STOP); comment = false; resizeable = false; resizing = false; diff --git a/scene/gui/graph_node.h b/scene/gui/graph_node.h index 056b699aa6..a7d9e8ddb0 100644 --- a/scene/gui/graph_node.h +++ b/scene/gui/graph_node.h @@ -99,8 +99,6 @@ private: Overlay overlay; - bool has_point(const Point2 &p_point) const; - protected: void _gui_input(const Ref<InputEvent> &p_ev); void _notification(int p_what); @@ -111,6 +109,8 @@ protected: void _get_property_list(List<PropertyInfo> *p_list) const; public: + bool has_point(const Point2 &p_point) const; + void set_slot(int p_idx, bool p_enable_left, int p_type_left, const Color &p_color_left, bool p_enable_right, int p_type_right, const Color &p_color_right, const Ref<Texture> &p_custom_left = Ref<Texture>(), const Ref<Texture> &p_custom_right = Ref<Texture>()); void clear_slot(int p_idx); void clear_all_slots(); diff --git a/scene/main/scene_tree.cpp b/scene/main/scene_tree.cpp index 6aa2c83941..d800c24e10 100644 --- a/scene/main/scene_tree.cpp +++ b/scene/main/scene_tree.cpp @@ -540,6 +540,7 @@ bool SceneTree::iteration(float p_time) { _notify_group_pause("fixed_process_internal", Node::NOTIFICATION_INTERNAL_FIXED_PROCESS); _notify_group_pause("fixed_process", Node::NOTIFICATION_FIXED_PROCESS); _flush_ugc(); + MessageQueue::get_singleton()->flush(); //small little hack _flush_transform_notifications(); call_group_flags(GROUP_CALL_REALTIME, "_viewports", "update_worlds"); root_lock--; @@ -566,6 +567,8 @@ bool SceneTree::idle(float p_time) { emit_signal("idle_frame"); + MessageQueue::get_singleton()->flush(); //small little hack + _flush_transform_notifications(); _notify_group_pause("idle_process_internal", Node::NOTIFICATION_INTERNAL_PROCESS); @@ -581,6 +584,7 @@ bool SceneTree::idle(float p_time) { } _flush_ugc(); + MessageQueue::get_singleton()->flush(); //small little hack _flush_transform_notifications(); //transforms after world update, to avoid unnecessary enter/exit notifications call_group_flags(GROUP_CALL_REALTIME, "_viewports", "update_worlds"); diff --git a/scene/main/viewport.cpp b/scene/main/viewport.cpp index e3c136a33f..ee9323ca1d 100644 --- a/scene/main/viewport.cpp +++ b/scene/main/viewport.cpp @@ -2028,6 +2028,89 @@ void Viewport::_gui_input_event(Ref<InputEvent> p_event) { } } + Ref<InputEventScreenTouch> touch_event = p_event; + if (touch_event.is_valid()) { + + Size2 pos = touch_event->get_position(); + if (touch_event->is_pressed()) { + + Control *over = _gui_find_control(pos); + if (over) { + + if (!gui.modal_stack.empty()) { + + Control *top = gui.modal_stack.back()->get(); + if (over != top && !top->is_a_parent_of(over)) { + + return; + } + } + if (over->can_process()) { + + touch_event = touch_event->xformed_by(Transform2D()); //make a copy + if (over == gui.mouse_focus) { + pos = gui.focus_inv_xform.xform(pos); + } else { + pos = over->get_global_transform_with_canvas().affine_inverse().xform(pos); + } + touch_event->set_position(pos); + _gui_call_input(over, touch_event); + } + get_tree()->set_input_as_handled(); + return; + } + } else if (gui.mouse_focus) { + + if (gui.mouse_focus->can_process()) { + + touch_event = touch_event->xformed_by(Transform2D()); //make a copy + touch_event->set_position(gui.focus_inv_xform.xform(pos)); + + _gui_call_input(gui.mouse_focus, touch_event); + } + get_tree()->set_input_as_handled(); + return; + } + } + + Ref<InputEventScreenDrag> drag_event = p_event; + if (drag_event.is_valid()) { + + Control *over = gui.mouse_focus; + if (!over) { + over = _gui_find_control(drag_event->get_position()); + } + if (over) { + + if (!gui.modal_stack.empty()) { + + Control *top = gui.modal_stack.back()->get(); + if (over != top && !top->is_a_parent_of(over)) { + + return; + } + } + if (over->can_process()) { + + Transform2D localizer = over->get_global_transform_with_canvas().affine_inverse(); + Size2 pos = localizer.xform(drag_event->get_position()); + Vector2 speed = localizer.basis_xform(drag_event->get_speed()); + Vector2 rel = localizer.basis_xform(drag_event->get_relative()); + + drag_event = drag_event->xformed_by(Transform2D()); //make a copy + + drag_event->set_speed(speed); + drag_event->set_relative(rel); + drag_event->set_position(pos); + + _gui_call_input(over, drag_event); + } + + get_tree()->set_input_as_handled(); + return; + } + } + if (mm.is_null() && mb.is_null() && p_event->is_action_type()) { if (gui.key_focus && !gui.key_focus->is_visible_in_tree()) { diff --git a/scene/resources/material.cpp b/scene/resources/material.cpp index 5a79e49240..d869e72f53 100644 --- a/scene/resources/material.cpp +++ b/scene/resources/material.cpp @@ -241,6 +241,7 @@ void SpatialMaterial::init_shaders() { shader_names->rim_texture_channel = "rim_texture_channel"; shader_names->depth_texture_channel = "depth_texture_channel"; shader_names->refraction_texture_channel = "refraction_texture_channel"; + shader_names->alpha_scissor_threshold = "alpha_scissor_threshold"; shader_names->texture_names[TEXTURE_ALBEDO] = "texture_albedo"; shader_names->texture_names[TEXTURE_METALLIC] = "texture_metallic"; @@ -259,8 +260,14 @@ void SpatialMaterial::init_shaders() { shader_names->texture_names[TEXTURE_DETAIL_NORMAL] = "texture_detail_normal"; } +Ref<SpatialMaterial> SpatialMaterial::materials_for_2d[SpatialMaterial::MAX_MATERIALS_FOR_2D]; + void SpatialMaterial::finish_shaders() { + for (int i = 0; i < MAX_MATERIALS_FOR_2D; i++) { + materials_for_2d[i].unref(); + } + #ifndef NO_THREADS memdelete(material_mutex); #endif @@ -359,6 +366,9 @@ void SpatialMaterial::_update_shader() { code += "uniform float grow;\n"; } + if (flags[FLAG_USE_ALPHA_SCISSOR]) { + code += "uniform float alpha_scissor_threshold;\n"; + } code += "uniform float roughness : hint_range(0,1);\n"; code += "uniform float point_size : hint_range(0,128);\n"; code += "uniform sampler2D texture_metallic : hint_white;\n"; @@ -674,7 +684,7 @@ void SpatialMaterial::_update_shader() { code += "\tALBEDO *= 1.0 - ref_amount;\n"; code += "\tALPHA = 1.0;\n"; - } else if (features[FEATURE_TRANSPARENT]) { + } else if (features[FEATURE_TRANSPARENT] || features[FLAG_USE_ALPHA_SCISSOR]) { code += "\tALPHA = albedo.a * albedo_tex.a;\n"; } @@ -774,6 +784,10 @@ void SpatialMaterial::_update_shader() { code += "\tvec3 detail_norm = mix(NORMALMAP,detail_norm_tex.rgb,detail_tex.a);\n"; code += "\tNORMALMAP = mix(NORMALMAP,detail_norm,detail_mask_tex.r);\n"; code += "\tALBEDO.rgb = mix(ALBEDO.rgb,detail,detail_mask_tex.r);\n"; + + if (flags[FLAG_USE_ALPHA_SCISSOR]) { + code += "\tALPHA_SCISSOR=alpha_scissor_threshold;\n"; + } } code += "}\n"; @@ -1086,6 +1100,9 @@ void SpatialMaterial::set_flag(Flags p_flag, bool p_enabled) { return; flags[p_flag] = p_enabled; + if (p_flag == FLAG_USE_ALPHA_SCISSOR) { + _change_notify(); + } _queue_shader_change(); } @@ -1130,9 +1147,6 @@ void SpatialMaterial::_validate_feature(const String &text, Feature feature, Pro if (property.name.begins_with(text) && property.name != text + "_enabled" && !features[feature]) { property.usage = 0; } - if ((property.name == "depth_min_layers" || property.name == "depth_max_layers") && !deep_parallax) { - property.usage = 0; - } } void SpatialMaterial::_validate_property(PropertyInfo &property) const { @@ -1154,6 +1168,14 @@ void SpatialMaterial::_validate_property(PropertyInfo &property) const { if (property.name == "params_grow_amount" && !grow_enabled) { property.usage = 0; } + + if (property.name == "params_alpha_scissor_threshold" && !flags[FLAG_USE_ALPHA_SCISSOR]) { + property.usage = 0; + } + + if ((property.name == "depth_min_layers" || property.name == "depth_max_layers") && !deep_parallax) { + property.usage = 0; + } } void SpatialMaterial::set_line_width(float p_line_width) { @@ -1329,6 +1351,16 @@ bool SpatialMaterial::is_grow_enabled() const { return grow_enabled; } +void SpatialMaterial::set_alpha_scissor_threshold(float p_treshold) { + alpha_scissor_threshold = p_treshold; + VS::get_singleton()->material_set_param(_get_material(), shader_names->alpha_scissor_threshold, p_treshold); +} + +float SpatialMaterial::get_alpha_scissor_threshold() const { + + return alpha_scissor_threshold; +} + void SpatialMaterial::set_grow(float p_grow) { grow = p_grow; VS::get_singleton()->material_set_param(_get_material(), shader_names->grow, p_grow); @@ -1391,6 +1423,40 @@ SpatialMaterial::TextureChannel SpatialMaterial::get_refraction_texture_channel( return refraction_texture_channel; } +RID SpatialMaterial::get_material_rid_for_2d(bool p_shaded, bool p_transparent, bool p_double_sided, bool p_cut_alpha, bool p_opaque_prepass) { + + int version = 0; + if (p_shaded) + version = 1; + if (p_transparent) + version |= 2; + if (p_cut_alpha) + version |= 4; + if (p_opaque_prepass) + version |= 8; + if (p_double_sided) + version |= 16; + + if (materials_for_2d[version].is_valid()) { + return materials_for_2d[version]->get_rid(); + } + + Ref<SpatialMaterial> material; + material.instance(); + + material->set_flag(FLAG_UNSHADED, !p_shaded); + material->set_feature(FEATURE_TRANSPARENT, p_transparent); + material->set_cull_mode(p_double_sided ? CULL_DISABLED : CULL_BACK); + material->set_depth_draw_mode(p_opaque_prepass ? DEPTH_DRAW_ALPHA_OPAQUE_PREPASS : DEPTH_DRAW_OPAQUE_ONLY); + material->set_flag(FLAG_SRGB_VERTEX_COLOR, true); + material->set_flag(FLAG_ALBEDO_FROM_VERTEX_COLOR, true); + material->set_flag(FLAG_USE_ALPHA_SCISSOR, p_cut_alpha); + + materials_for_2d[version] = material; + + return materials_for_2d[version]->get_rid(); +} + void SpatialMaterial::_bind_methods() { ClassDB::bind_method(D_METHOD("set_albedo", "albedo"), &SpatialMaterial::set_albedo); @@ -1516,6 +1582,9 @@ void SpatialMaterial::_bind_methods() { ClassDB::bind_method(D_METHOD("set_grow", "amount"), &SpatialMaterial::set_grow); ClassDB::bind_method(D_METHOD("get_grow"), &SpatialMaterial::get_grow); + ClassDB::bind_method(D_METHOD("set_alpha_scissor_threshold", "threshold"), &SpatialMaterial::set_alpha_scissor_threshold); + ClassDB::bind_method(D_METHOD("get_alpha_scissor_threshold"), &SpatialMaterial::get_alpha_scissor_threshold); + ClassDB::bind_method(D_METHOD("set_grow_enabled", "enable"), &SpatialMaterial::set_grow_enabled); ClassDB::bind_method(D_METHOD("is_grow_enabled"), &SpatialMaterial::is_grow_enabled); @@ -1553,6 +1622,8 @@ void SpatialMaterial::_bind_methods() { ADD_PROPERTY(PropertyInfo(Variant::INT, "params_billboard_mode", PROPERTY_HINT_ENUM, "Disabled,Enabled,Y-Billboard,Particle Billboard"), "set_billboard_mode", "get_billboard_mode"); ADD_PROPERTY(PropertyInfo(Variant::BOOL, "params_grow"), "set_grow_enabled", "is_grow_enabled"); ADD_PROPERTY(PropertyInfo(Variant::REAL, "params_grow_amount", PROPERTY_HINT_RANGE, "-16,10,0.01"), "set_grow", "get_grow"); + ADD_PROPERTYI(PropertyInfo(Variant::BOOL, "params_use_alpha_scissor"), "set_flag", "get_flag", FLAG_USE_ALPHA_SCISSOR); + ADD_PROPERTY(PropertyInfo(Variant::REAL, "params_alpha_scissor_threshold", PROPERTY_HINT_RANGE, "0,1,0.01"), "set_alpha_scissor_threshold", "get_alpha_scissor_threshold"); ADD_GROUP("Particles Anim", "particles_anim_"); ADD_PROPERTY(PropertyInfo(Variant::INT, "particles_anim_h_frames", PROPERTY_HINT_RANGE, "1,128,1"), "set_particles_anim_h_frames", "get_particles_anim_h_frames"); ADD_PROPERTY(PropertyInfo(Variant::INT, "particles_anim_v_frames", PROPERTY_HINT_RANGE, "1,128,1"), "set_particles_anim_v_frames", "get_particles_anim_v_frames"); @@ -1697,9 +1768,13 @@ void SpatialMaterial::_bind_methods() { BIND_CONSTANT(FLAG_USE_VERTEX_LIGHTING); BIND_CONSTANT(FLAG_ONTOP); BIND_CONSTANT(FLAG_ALBEDO_FROM_VERTEX_COLOR); - BIND_CONSTANT(FLAG_SRGB_VERTEX_COLOR) - BIND_CONSTANT(FLAG_USE_POINT_SIZE) - BIND_CONSTANT(FLAG_FIXED_SIZE) + BIND_CONSTANT(FLAG_SRGB_VERTEX_COLOR); + BIND_CONSTANT(FLAG_USE_POINT_SIZE); + BIND_CONSTANT(FLAG_FIXED_SIZE); + BIND_CONSTANT(FLAG_UV1_USE_TRIPLANAR); + BIND_CONSTANT(FLAG_UV2_USE_TRIPLANAR); + BIND_CONSTANT(FLAG_AO_ON_UV2); + BIND_CONSTANT(FLAG_USE_ALPHA_SCISSOR); BIND_CONSTANT(FLAG_MAX); BIND_CONSTANT(DIFFUSE_LAMBERT); @@ -1757,6 +1832,7 @@ SpatialMaterial::SpatialMaterial() set_particles_anim_h_frames(1); set_particles_anim_v_frames(1); set_particles_anim_loop(false); + set_alpha_scissor_threshold(0.98); set_metallic_texture_channel(TEXTURE_CHANNEL_RED); set_roughness_texture_channel(TEXTURE_CHANNEL_RED); diff --git a/scene/resources/material.h b/scene/resources/material.h index 1484b79fc6..25628e272a 100644 --- a/scene/resources/material.h +++ b/scene/resources/material.h @@ -164,6 +164,7 @@ public: FLAG_UV1_USE_TRIPLANAR, FLAG_UV2_USE_TRIPLANAR, FLAG_AO_ON_UV2, + FLAG_USE_ALPHA_SCISSOR, FLAG_MAX }; @@ -207,7 +208,7 @@ private: uint64_t blend_mode : 2; uint64_t depth_draw_mode : 2; uint64_t cull_mode : 2; - uint64_t flags : 9; + uint64_t flags : 11; uint64_t detail_blend_mode : 2; uint64_t diffuse_mode : 3; uint64_t specular_mode : 2; @@ -298,6 +299,7 @@ private: StringName rim_texture_channel; StringName depth_texture_channel; StringName refraction_texture_channel; + StringName alpha_scissor_threshold; StringName texture_names[TEXTURE_MAX]; }; @@ -329,6 +331,7 @@ private: float refraction; float line_width; float point_size; + float alpha_scissor_threshold; bool grow_enabled; float grow; int particles_anim_h_frames; @@ -369,6 +372,12 @@ private: _FORCE_INLINE_ void _validate_feature(const String &text, Feature feature, PropertyInfo &property) const; + enum { + MAX_MATERIALS_FOR_2D = 32 + }; + + static Ref<SpatialMaterial> materials_for_2d[MAX_MATERIALS_FOR_2D]; //used by Sprite3D and other stuff + protected: static void _bind_methods(); void _validate_property(PropertyInfo &property) const; @@ -499,6 +508,9 @@ public: void set_grow(float p_grow); float get_grow() const; + void set_alpha_scissor_threshold(float p_treshold); + float get_alpha_scissor_threshold() const; + void set_metallic_texture_channel(TextureChannel p_channel); TextureChannel get_metallic_texture_channel() const; void set_roughness_texture_channel(TextureChannel p_channel); @@ -512,6 +524,8 @@ public: static void finish_shaders(); static void flush_changes(); + static RID get_material_rid_for_2d(bool p_shaded, bool p_transparent, bool p_double_sided, bool p_cut_alpha, bool p_opaque_prepass); + SpatialMaterial(); virtual ~SpatialMaterial(); }; diff --git a/servers/visual/rasterizer.h b/servers/visual/rasterizer.h index 9c264ead49..9405f6e012 100644 --- a/servers/visual/rasterizer.h +++ b/servers/visual/rasterizer.h @@ -1014,6 +1014,8 @@ public: virtual void reset_canvas() = 0; + virtual void draw_window_margins(int *p_margins, RID *p_margin_textures) = 0; + virtual ~RasterizerCanvas() {} }; diff --git a/servers/visual/shader_types.cpp b/servers/visual/shader_types.cpp index 3de0841f2a..3f1403d532 100644 --- a/servers/visual/shader_types.cpp +++ b/servers/visual/shader_types.cpp @@ -109,6 +109,7 @@ ShaderTypes::ShaderTypes() { shader_modes[VS::SHADER_SPATIAL].functions["fragment"]["SCREEN_UV"] = ShaderLanguage::TYPE_VEC2; shader_modes[VS::SHADER_SPATIAL].functions["fragment"]["POINT_COORD"] = ShaderLanguage::TYPE_VEC2; shader_modes[VS::SHADER_SPATIAL].functions["fragment"]["SIDE"] = ShaderLanguage::TYPE_FLOAT; + shader_modes[VS::SHADER_SPATIAL].functions["fragment"]["ALPHA_SCISSOR"] = ShaderLanguage::TYPE_FLOAT; shader_modes[VS::SHADER_SPATIAL].functions["fragment"]["WORLD_MATRIX"] = ShaderLanguage::TYPE_MAT4; shader_modes[VS::SHADER_SPATIAL].functions["fragment"]["INV_CAMERA_MATRIX"] = ShaderLanguage::TYPE_MAT4; diff --git a/servers/visual/visual_server_raster.cpp b/servers/visual/visual_server_raster.cpp index b5f98dd94c..cc4fe0809d 100644 --- a/servers/visual/visual_server_raster.cpp +++ b/servers/visual/visual_server_raster.cpp @@ -41,23 +41,29 @@ int VisualServerRaster::changes = 0; -/* CURSOR */ -void VisualServerRaster::cursor_set_rotation(float p_rotation, int p_cursor) { -} -void VisualServerRaster::cursor_set_texture(RID p_texture, const Point2 &p_center_offset, int p_cursor, const Rect2 &p_region) { -} -void VisualServerRaster::cursor_set_visible(bool p_visible, int p_cursor) { -} -void VisualServerRaster::cursor_set_pos(const Point2 &p_pos, int p_cursor) { -} - /* BLACK BARS */ void VisualServerRaster::black_bars_set_margins(int p_left, int p_top, int p_right, int p_bottom) { + + black_margin[MARGIN_LEFT] = p_left; + black_margin[MARGIN_TOP] = p_top; + black_margin[MARGIN_RIGHT] = p_right; + black_margin[MARGIN_BOTTOM] = p_bottom; } + void VisualServerRaster::black_bars_set_images(RID p_left, RID p_top, RID p_right, RID p_bottom) { + + black_image[MARGIN_LEFT] = p_left; + black_image[MARGIN_TOP] = p_top; + black_image[MARGIN_RIGHT] = p_right; + black_image[MARGIN_BOTTOM] = p_bottom; } +void VisualServerRaster::_draw_margins() { + + VSG::canvas_render->draw_window_margins(black_margin, black_image); +}; + /* FREE */ void VisualServerRaster::free(RID p_rid) { @@ -121,6 +127,8 @@ void VisualServerRaster::draw() { frame_drawn_callbacks.pop_front(); } + + _draw_margins(); } void VisualServerRaster::sync() { } @@ -189,6 +197,9 @@ VisualServerRaster::VisualServerRaster() { VSG::storage = VSG::rasterizer->get_storage(); VSG::canvas_render = VSG::rasterizer->get_canvas(); VSG::scene_render = VSG::rasterizer->get_scene(); + + for (int i = 0; i < 4; i++) + black_margin[i] = 0; } VisualServerRaster::~VisualServerRaster() { diff --git a/servers/visual/visual_server_raster.h b/servers/visual/visual_server_raster.h index 56e4323f7c..596dd5c10e 100644 --- a/servers/visual/visual_server_raster.h +++ b/servers/visual/visual_server_raster.h @@ -61,6 +61,9 @@ class VisualServerRaster : public VisualServer { bool draw_extra_frame; RID test_cube; + int black_margin[4]; + RID black_image[4]; + struct FrameDrawnCallbacks { ObjectID object; @@ -584,6 +587,8 @@ class VisualServerRaster : public VisualServer { #endif + void _draw_margins(); + public: _FORCE_INLINE_ static void redraw_request() { changes++; } @@ -1110,12 +1115,6 @@ public: BIND2(canvas_occluder_polygon_set_cull_mode, RID, CanvasOccluderPolygonCullMode) - /* CURSOR */ - virtual void cursor_set_rotation(float p_rotation, int p_cursor = 0); // radians - virtual void cursor_set_texture(RID p_texture, const Point2 &p_center_offset = Point2(0, 0), int p_cursor = 0, const Rect2 &p_region = Rect2()); - virtual void cursor_set_visible(bool p_visible, int p_cursor = 0); - virtual void cursor_set_pos(const Point2 &p_pos, int p_cursor = 0); - /* BLACK BARS */ virtual void black_bars_set_margins(int p_left, int p_top, int p_right, int p_bottom); diff --git a/servers/visual/visual_server_scene.cpp b/servers/visual/visual_server_scene.cpp index 56a596de55..11a9c8c9c1 100644 --- a/servers/visual/visual_server_scene.cpp +++ b/servers/visual/visual_server_scene.cpp @@ -880,13 +880,13 @@ void VisualServerScene::instance_attach_skeleton(RID p_instance, RID p_skeleton) return; if (instance->skeleton.is_valid()) { - VSG::storage->instance_remove_skeleton(p_skeleton, instance); + VSG::storage->instance_remove_skeleton(instance->skeleton, instance); } instance->skeleton = p_skeleton; if (instance->skeleton.is_valid()) { - VSG::storage->instance_add_skeleton(p_skeleton, instance); + VSG::storage->instance_add_skeleton(instance->skeleton, instance); } _instance_queue_update(instance, true); diff --git a/servers/visual/visual_server_wrap_mt.h b/servers/visual/visual_server_wrap_mt.h index 6c98082b98..20223f9651 100644 --- a/servers/visual/visual_server_wrap_mt.h +++ b/servers/visual/visual_server_wrap_mt.h @@ -538,12 +538,6 @@ public: FUNC2(canvas_occluder_polygon_set_cull_mode, RID, CanvasOccluderPolygonCullMode) - /* CURSOR */ - FUNC2(cursor_set_rotation, float, int) // radians - FUNC4(cursor_set_texture, RID, const Point2 &, int, const Rect2 &) - FUNC2(cursor_set_visible, bool, int) - FUNC2(cursor_set_pos, const Point2 &, int) - /* BLACK BARS */ FUNC4(black_bars_set_margins, int, int, int, int) diff --git a/servers/visual_server.cpp b/servers/visual_server.cpp index 307f4107eb..aed2f243fd 100644 --- a/servers/visual_server.cpp +++ b/servers/visual_server.cpp @@ -136,11 +136,6 @@ void VisualServer::_free_internal_rids() { free(white_texture); if (test_material.is_valid()) free(test_material); - - for (int i = 0; i < 32; i++) { - if (material_2d[i].is_valid()) - free(material_2d[i]); - } } RID VisualServer::_make_test_cube() { @@ -284,37 +279,6 @@ RID VisualServer::make_sphere_mesh(int p_lats, int p_lons, float p_radius) { return mesh; } -RID VisualServer::material_2d_get(bool p_shaded, bool p_transparent, bool p_double_sided, bool p_cut_alpha, bool p_opaque_prepass) { - - int version = 0; - if (p_shaded) - version = 1; - if (p_transparent) - version |= 2; - if (p_cut_alpha) - version |= 4; - if (p_opaque_prepass) - version |= 8; - if (p_double_sided) - version |= 16; - if (material_2d[version].is_valid()) - return material_2d[version]; - - //not valid, make - - /* material_2d[version]=fixed_material_create(); - fixed_material_set_flag(material_2d[version],FIXED_MATERIAL_FLAG_USE_ALPHA,p_transparent); - fixed_material_set_flag(material_2d[version],FIXED_MATERIAL_FLAG_USE_COLOR_ARRAY,true); - fixed_material_set_flag(material_2d[version],FIXED_MATERIAL_FLAG_DISCARD_ALPHA,p_cut_alpha); - material_set_flag(material_2d[version],MATERIAL_FLAG_UNSHADED,!p_shaded); - material_set_flag(material_2d[version], MATERIAL_FLAG_DOUBLE_SIDED, p_double_sided); - material_set_depth_draw_mode(material_2d[version],p_opaque_prepass?MATERIAL_DEPTH_DRAW_OPAQUE_PRE_PASS_ALPHA:MATERIAL_DEPTH_DRAW_OPAQUE_ONLY); - fixed_material_set_texture(material_2d[version],FIXED_MATERIAL_PARAM_DIFFUSE,get_white_texture()); - //material cut alpha?*/ - - return material_2d[version]; -} - RID VisualServer::get_white_texture() { if (white_texture.is_valid()) diff --git a/servers/visual_server.h b/servers/visual_server.h index e017bd10fc..ddf32a9ea1 100644 --- a/servers/visual_server.h +++ b/servers/visual_server.h @@ -60,7 +60,6 @@ protected: RID test_texture; RID white_texture; RID test_material; - RID material_2d[32]; Error _surface_set_data(Array p_arrays, uint32_t p_format, uint32_t *p_offsets, uint32_t p_stride, PoolVector<uint8_t> &r_vertex_array, int p_vertex_array_len, PoolVector<uint8_t> &r_index_array, int p_index_array_len, Rect3 &r_aabb, Vector<Rect3> r_bone_aabb); @@ -875,12 +874,6 @@ public: }; virtual void canvas_occluder_polygon_set_cull_mode(RID p_occluder_polygon, CanvasOccluderPolygonCullMode p_mode) = 0; - /* CURSOR */ - virtual void cursor_set_rotation(float p_rotation, int p_cursor = 0) = 0; // radians - virtual void cursor_set_texture(RID p_texture, const Point2 &p_center_offset = Point2(0, 0), int p_cursor = 0, const Rect2 &p_region = Rect2()) = 0; - virtual void cursor_set_visible(bool p_visible, int p_cursor = 0) = 0; - virtual void cursor_set_pos(const Point2 &p_pos, int p_cursor = 0) = 0; - /* BLACK BARS */ virtual void black_bars_set_margins(int p_left, int p_top, int p_right, int p_bottom) = 0; @@ -920,8 +913,6 @@ public: /* Materials for 2D on 3D */ - RID material_2d_get(bool p_shaded, bool p_transparent, bool p_double_sided, bool p_cut_alpha, bool p_opaque_prepass); - /* TESTING */ virtual RID get_test_cube() = 0; |