summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--core/io/packet_peer.cpp30
-rw-r--r--core/io/packet_peer.h4
-rw-r--r--core/script_debugger_remote.cpp1
-rw-r--r--drivers/gles3/rasterizer_canvas_gles3.cpp67
-rw-r--r--drivers/gles3/rasterizer_canvas_gles3.h2
-rw-r--r--drivers/gles3/rasterizer_gles3.cpp26
-rw-r--r--drivers/gles3/rasterizer_gles3.h3
-rw-r--r--drivers/gles3/rasterizer_scene_gles3.cpp21
-rw-r--r--drivers/gles3/rasterizer_storage_gles3.cpp2
-rw-r--r--drivers/gles3/rasterizer_storage_gles3.h1
-rw-r--r--drivers/gles3/shader_compiler_gles3.cpp2
-rw-r--r--drivers/gles3/shaders/scene.glsl10
-rw-r--r--editor/collada/collada.cpp1
-rw-r--r--editor/editor_log.cpp29
-rw-r--r--editor/filesystem_dock.cpp4
-rw-r--r--editor/import/resource_importer_wav.cpp52
-rw-r--r--editor/plugins/canvas_item_editor_plugin.cpp9
-rw-r--r--editor/plugins/spatial_editor_plugin.cpp38
-rw-r--r--editor/plugins/spatial_editor_plugin.h2
-rw-r--r--editor/plugins/tile_map_editor_plugin.cpp22
-rw-r--r--editor/project_manager.cpp27
-rw-r--r--editor/project_manager.h1
-rw-r--r--editor/script_editor_debugger.cpp1
-rw-r--r--main/input_default.cpp11
-rw-r--r--modules/gdnative/godot/string.cpp1150
-rw-r--r--modules/gdnative/godot/string.h158
-rw-r--r--modules/gdscript/gd_functions.cpp63
-rw-r--r--modules/gdscript/gd_functions.h1
-rw-r--r--modules/gdscript/gd_parser.cpp7
-rw-r--r--modules/nativescript/nativescript.cpp22
-rw-r--r--modules/visual_script/visual_script.cpp8
-rw-r--r--modules/visual_script/visual_script_editor.cpp16
-rw-r--r--modules/visual_script/visual_script_nodes.cpp49
-rw-r--r--modules/visual_script/visual_script_nodes.h10
-rw-r--r--platform/android/os_android.cpp2
-rw-r--r--platform/iphone/os_iphone.cpp2
-rw-r--r--platform/javascript/os_javascript.cpp2
-rw-r--r--platform/osx/os_osx.mm2
-rw-r--r--scene/2d/particles_2d.cpp9
-rw-r--r--scene/3d/particles.cpp12
-rw-r--r--scene/3d/particles.h1
-rw-r--r--scene/3d/spatial.cpp10
-rw-r--r--scene/3d/sprite_3d.cpp5
-rw-r--r--scene/gui/graph_edit.cpp16
-rw-r--r--scene/gui/graph_node.cpp3
-rw-r--r--scene/gui/graph_node.h4
-rw-r--r--scene/main/scene_tree.cpp4
-rw-r--r--scene/main/viewport.cpp83
-rw-r--r--scene/resources/material.cpp90
-rw-r--r--scene/resources/material.h16
-rw-r--r--servers/visual/rasterizer.h2
-rw-r--r--servers/visual/shader_types.cpp1
-rw-r--r--servers/visual/visual_server_raster.cpp31
-rw-r--r--servers/visual/visual_server_raster.h11
-rw-r--r--servers/visual/visual_server_scene.cpp4
-rw-r--r--servers/visual/visual_server_wrap_mt.h6
-rw-r--r--servers/visual_server.cpp36
-rw-r--r--servers/visual_server.h9
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;