summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--core/register_core_types.cpp1
-rw-r--r--doc/classes/Control.xml8
-rw-r--r--drivers/gles2/rasterizer_storage_gles2.cpp9
-rw-r--r--drivers/gles2/shaders/canvas.glsl5
-rw-r--r--drivers/gles2/shaders/cubemap_filter.glsl4
-rw-r--r--drivers/gles2/shaders/scene.glsl4
-rw-r--r--drivers/gles3/rasterizer_scene_gles3.cpp4
-rw-r--r--drivers/gles3/rasterizer_storage_gles3.cpp10
-rw-r--r--editor/editor_sectioned_inspector.cpp2
-rw-r--r--editor/plugin_config_dialog.cpp29
-rw-r--r--modules/gdscript/gdscript.cpp3
-rw-r--r--modules/gdscript/gdscript_parser.cpp38
-rw-r--r--platform/windows/os_windows.cpp10
-rw-r--r--scene/2d/canvas_item.cpp7
-rw-r--r--scene/2d/canvas_item.h4
-rw-r--r--scene/3d/physics_body.cpp8
-rw-r--r--scene/gui/base_button.cpp12
-rw-r--r--scene/gui/progress_bar.cpp1
-rw-r--r--scene/resources/dynamic_font.cpp2
-rw-r--r--scene/resources/style_box.cpp7
-rw-r--r--scene/resources/style_box.h4
-rw-r--r--scene/resources/texture.cpp4
-rw-r--r--thirdparty/README.md3
-rw-r--r--thirdparty/libtheora/decode.c8
-rw-r--r--thirdparty/libtheora/patches/theora.git-0ae66d565e6bead8604d312bc1a4e9dccf245c88.patch38
25 files changed, 175 insertions, 50 deletions
diff --git a/core/register_core_types.cpp b/core/register_core_types.cpp
index 666384b093..a31aa9cb01 100644
--- a/core/register_core_types.cpp
+++ b/core/register_core_types.cpp
@@ -142,6 +142,7 @@ void register_core_types() {
ClassDB::register_virtual_class<InputEventGesture>();
ClassDB::register_class<InputEventMagnifyGesture>();
ClassDB::register_class<InputEventPanGesture>();
+ ClassDB::register_class<InputEventMIDI>();
ClassDB::register_class<FuncRef>();
ClassDB::register_virtual_class<StreamPeer>();
diff --git a/doc/classes/Control.xml b/doc/classes/Control.xml
index f067b50c72..d27839e0a6 100644
--- a/doc/classes/Control.xml
+++ b/doc/classes/Control.xml
@@ -681,7 +681,7 @@
[b]Note:[/b] On Linux, shapes may vary depending on the cursor theme of the system.
</member>
<member name="mouse_filter" type="int" setter="set_mouse_filter" getter="get_mouse_filter" enum="Control.MouseFilter">
- Controls whether the control will be able to receive mouse button input events through [method _gui_input] and how these events should be handled. See the constants to learn what each does.
+ Controls whether the control will be able to receive mouse button input events through [method _gui_input] and how these events should be handled. Also controls whether the control can receive the [signal mouse_entered], and [signal mouse_exited] signals. See the constants to learn what each does.
</member>
<member name="rect_clip_content" type="bool" setter="set_clip_contents" getter="is_clipping_contents">
Enables whether rendering of children should be clipped to this control's rectangle. If true, parts of a child which would be visibly outside of this control's rectangle will not be rendered.
@@ -929,13 +929,13 @@
Tells the parent [Container] to align the node with its end, either the bottom or the right edge. It doesn't work with the fill or expand size flags. Use with [member size_flags_horizontal] and [member size_flags_vertical].
</constant>
<constant name="MOUSE_FILTER_STOP" value="0" enum="MouseFilter">
- The control will receive mouse button input events through [method _gui_input] if clicked on. These events are automatically marked as handled and they will not propagate further to other controls.
+ The control will receive mouse button input events through [method _gui_input] if clicked on. And the control will receive the [signal mouse_entered] and [signal mouse_exited] signals. These events are automatically marked as handled and they will not propagate further to other controls. This also results in blocking signals in other controls.
</constant>
<constant name="MOUSE_FILTER_PASS" value="1" enum="MouseFilter">
- The control will receive mouse button input events through [method _gui_input] if clicked on. If this control does not handle the event, the parent control (if any) will be considered for a mouse click, and so on until there is no more parent control to potentially handle it. Even if no control handled it at all, the event will still be handled automatically, so unhandled input will not be fired.
+ The control will receive mouse button input events through [method _gui_input] if clicked on. And the control will receive the [signal mouse_entered] and [signal mouse_exited] signals. If this control does not handle the event, the parent control (if any) will be considered, and so on until there is no more parent control to potentially handle it. This also allows signals to fire in other controls. Even if no control handled it at all, the event will still be handled automatically, so unhandled input will not be fired.
</constant>
<constant name="MOUSE_FILTER_IGNORE" value="2" enum="MouseFilter">
- The control will not receive mouse button input events through [method _gui_input] and will not block other controls from receiving these events. These events will also not be handled automatically.
+ The control will not receive mouse button input events through [method _gui_input]. Also the control will not receive the [signal mouse_entered] nor [signal mouse_exited] signals. This will not block other controls from receiving these events or firing the signals. Ignored events will not be handled automatically.
</constant>
<constant name="GROW_DIRECTION_BEGIN" value="0" enum="GrowDirection">
The control will grow to the left or top to make up if its minimum size is changed to be greater than its current size on the respective axis.
diff --git a/drivers/gles2/rasterizer_storage_gles2.cpp b/drivers/gles2/rasterizer_storage_gles2.cpp
index c9c4cd3892..22c05d9d77 100644
--- a/drivers/gles2/rasterizer_storage_gles2.cpp
+++ b/drivers/gles2/rasterizer_storage_gles2.cpp
@@ -1715,15 +1715,6 @@ RID RasterizerStorageGLES2::mesh_create() {
return mesh_owner.make_rid(mesh);
}
-static float Float16ToFloat(short fltInt16) {
- int fltInt32 = ((fltInt16 & 0x8000) << 16);
- fltInt32 |= ((fltInt16 & 0x7fff) << 13) + 0x38000000;
-
- float fRet;
- memcpy(&fRet, &fltInt32, sizeof(float));
- return fRet;
-}
-
static PoolVector<uint8_t> _unpack_half_floats(const PoolVector<uint8_t> &array, uint32_t &format, int p_vertices) {
uint32_t p_format = format;
diff --git a/drivers/gles2/shaders/canvas.glsl b/drivers/gles2/shaders/canvas.glsl
index 45d26e7254..bc734a6597 100644
--- a/drivers/gles2/shaders/canvas.glsl
+++ b/drivers/gles2/shaders/canvas.glsl
@@ -223,16 +223,19 @@ VERTEX_SHADER_CODE
#define textureCubeLod(img, coord, lod) textureCubeLodEXT(img, coord, lod)
#endif
+#endif
+
#ifdef GL_ARB_shader_texture_lod
#extension GL_ARB_shader_texture_lod : enable
#endif
+
#if !defined(GL_EXT_shader_texture_lod) && !defined(GL_ARB_shader_texture_lod)
#define texture2DLod(img, coord, lod) texture2D(img, coord, lod)
#define textureCubeLod(img, coord, lod) textureCube(img, coord, lod)
#endif
-#endif
+
#ifdef USE_GLES_OVER_GL
diff --git a/drivers/gles2/shaders/cubemap_filter.glsl b/drivers/gles2/shaders/cubemap_filter.glsl
index c9a0fd4ba2..558c83960e 100644
--- a/drivers/gles2/shaders/cubemap_filter.glsl
+++ b/drivers/gles2/shaders/cubemap_filter.glsl
@@ -33,6 +33,8 @@ void main() {
#define textureCubeLod(img, coord, lod) textureCubeLodEXT(img, coord, lod)
#endif
+#endif
+
#ifdef GL_ARB_shader_texture_lod
#extension GL_ARB_shader_texture_lod : enable
#endif
@@ -42,7 +44,7 @@ void main() {
#define textureCubeLod(img, coord, lod) textureCube(img, coord, lod)
#endif
-#endif
+
#ifdef USE_GLES_OVER_GL
#define lowp
diff --git a/drivers/gles2/shaders/scene.glsl b/drivers/gles2/shaders/scene.glsl
index 148b5ae7ef..6aa91df20f 100644
--- a/drivers/gles2/shaders/scene.glsl
+++ b/drivers/gles2/shaders/scene.glsl
@@ -664,6 +664,8 @@ VERTEX_SHADER_CODE
#define textureCubeLod(img, coord, lod) textureCubeLodEXT(img, coord, lod)
#endif
+#endif
+
#ifdef GL_ARB_shader_texture_lod
#extension GL_ARB_shader_texture_lod : enable
#endif
@@ -673,7 +675,7 @@ VERTEX_SHADER_CODE
#define textureCubeLod(img, coord, lod) textureCube(img, coord, lod)
#endif
-#endif
+
#ifdef USE_GLES_OVER_GL
diff --git a/drivers/gles3/rasterizer_scene_gles3.cpp b/drivers/gles3/rasterizer_scene_gles3.cpp
index 02dbe096c5..b831197759 100644
--- a/drivers/gles3/rasterizer_scene_gles3.cpp
+++ b/drivers/gles3/rasterizer_scene_gles3.cpp
@@ -3114,7 +3114,7 @@ void RasterizerSceneGLES3::_copy_screen(bool p_invalidate_color, bool p_invalida
GLenum attachments[2] = {
GL_COLOR_ATTACHMENT0,
- GL_DEPTH_STENCIL_ATTACHMENT
+ GL_DEPTH_ATTACHMENT
};
glInvalidateFramebuffer(GL_FRAMEBUFFER, p_invalidate_depth ? 2 : 1, attachments);
@@ -4164,7 +4164,7 @@ void RasterizerSceneGLES3::render_scene(const Transform &p_cam_transform, const
glBindFramebuffer(GL_READ_FRAMEBUFFER, storage->frame.current_rt->buffers.fbo);
glReadBuffer(GL_COLOR_ATTACHMENT0);
glBindFramebuffer(GL_DRAW_FRAMEBUFFER, storage->frame.current_rt->fbo);
- glBlitFramebuffer(0, 0, storage->frame.current_rt->width, storage->frame.current_rt->height, 0, 0, storage->frame.current_rt->width, storage->frame.current_rt->height, GL_DEPTH_BUFFER_BIT, GL_NEAREST);
+ glBlitFramebuffer(0, 0, storage->frame.current_rt->width, storage->frame.current_rt->height, 0, 0, storage->frame.current_rt->width, storage->frame.current_rt->height, GL_COLOR_BUFFER_BIT, GL_NEAREST);
glBindFramebuffer(GL_READ_FRAMEBUFFER, 0);
glBindFramebuffer(GL_DRAW_FRAMEBUFFER, 0);
//bind depth for read
diff --git a/drivers/gles3/rasterizer_storage_gles3.cpp b/drivers/gles3/rasterizer_storage_gles3.cpp
index 8b3f1a1b77..8e6606a95d 100644
--- a/drivers/gles3/rasterizer_storage_gles3.cpp
+++ b/drivers/gles3/rasterizer_storage_gles3.cpp
@@ -7052,7 +7052,12 @@ void RasterizerStorageGLES3::_render_target_allocate(RenderTarget *rt) {
glGenTextures(1, &rt->exposure.color);
glBindTexture(GL_TEXTURE_2D, rt->exposure.color);
+#ifdef IPHONE_ENABLED
+ ///@TODO ugly hack to get around iOS not supporting 32bit single channel floating point textures...
+ glTexImage2D(GL_TEXTURE_2D, 0, GL_R16F, 1, 1, 0, GL_RED, GL_FLOAT, NULL);
+#else
glTexImage2D(GL_TEXTURE_2D, 0, GL_R32F, 1, 1, 0, GL_RED, GL_FLOAT, NULL);
+#endif
glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, rt->exposure.color, 0);
status = glCheckFramebufferStatus(GL_FRAMEBUFFER);
@@ -7284,7 +7289,12 @@ RID RasterizerStorageGLES3::canvas_light_shadow_buffer_create(int p_width) {
if (config.use_rgba_2d_shadows) {
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA8, cls->size, cls->height, 0, GL_RGBA, GL_UNSIGNED_BYTE, NULL);
} else {
+#ifdef IPHONE_ENABLED
+ ///@TODO ugly hack to get around iOS not supporting 32bit single channel floating point textures...
+ glTexImage2D(GL_TEXTURE_2D, 0, GL_R16F, cls->size, cls->height, 0, GL_RED, GL_FLOAT, NULL);
+#else
glTexImage2D(GL_TEXTURE_2D, 0, GL_R32F, cls->size, cls->height, 0, GL_RED, GL_FLOAT, NULL);
+#endif
}
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
diff --git a/editor/editor_sectioned_inspector.cpp b/editor/editor_sectioned_inspector.cpp
index a2883690da..acc7637c0b 100644
--- a/editor/editor_sectioned_inspector.cpp
+++ b/editor/editor_sectioned_inspector.cpp
@@ -241,7 +241,7 @@ void SectionedInspector::update_category_list() {
int sp = pi.name.find("/");
if (sp == -1)
- pi.name = "Global/" + pi.name;
+ pi.name = "global/" + pi.name;
Vector<String> sectionarr = pi.name.split("/");
String metasection;
diff --git a/editor/plugin_config_dialog.cpp b/editor/plugin_config_dialog.cpp
index 1b99059f32..88672bdf34 100644
--- a/editor/plugin_config_dialog.cpp
+++ b/editor/plugin_config_dialog.cpp
@@ -65,11 +65,16 @@ void PluginConfigDialog::_on_confirmed() {
cf->save(path.plus_file("plugin.cfg"));
if (!_edit_mode) {
- String type = script_option_edit->get_item_text(script_option_edit->get_selected());
+ int lang_idx = script_option_edit->get_selected();
+ String lang_name = ScriptServer::get_language(lang_idx)->get_name();
Ref<Script> script;
- if (type == GDScriptLanguage::get_singleton()->get_name()) {
+ // TODO Use script templates. Right now, this code won't add the 'tool' annotation to other languages.
+ // TODO Better support script languages with named classes (has_named_classes).
+
+ if (lang_name == GDScriptLanguage::get_singleton()->get_name()) {
+ // Hard-coded GDScript template to keep usability until we use script templates.
Ref<GDScript> gdscript = memnew(GDScript);
gdscript->set_source_code(
"tool\n"
@@ -84,8 +89,13 @@ void PluginConfigDialog::_on_confirmed() {
gdscript->set_path(script_path);
ResourceSaver::save(script_path, gdscript);
script = gdscript;
+ } else {
+ String script_path = path.plus_file(script_edit->get_text());
+ String class_name = script_path.get_file().get_basename();
+ script = ScriptServer::get_language(lang_idx)->get_template(class_name, "EditorPlugin");
+ script->set_path(script_path);
+ ResourceSaver::save(script_path, script);
}
- //TODO: other languages
emit_signal("plugin_ready", script.operator->(), active_edit->is_pressed() ? subfolder_edit->get_text() : "");
} else {
@@ -98,8 +108,9 @@ void PluginConfigDialog::_on_cancelled() {
_clear_fields();
}
-void PluginConfigDialog::_on_required_text_changed(const String &p_text) {
- String ext = script_option_edit->get_item_metadata(script_option_edit->get_selected());
+void PluginConfigDialog::_on_required_text_changed(const String &) {
+ int lang_idx = script_option_edit->get_selected();
+ String ext = ScriptServer::get_language(lang_idx)->get_extension();
get_ok()->set_disabled(script_edit->get_text().get_basename().empty() || script_edit->get_text().get_extension() != ext || name_edit->get_text().empty());
}
@@ -204,10 +215,11 @@ PluginConfigDialog::PluginConfigDialog() {
grid->add_child(script_option_lb);
script_option_edit = memnew(OptionButton);
- script_option_edit->add_item(GDScriptLanguage::get_singleton()->get_name());
- script_option_edit->set_item_metadata(0, GDScriptLanguage::get_singleton()->get_extension());
+ for (int i = 0; i < ScriptServer::get_language_count(); i++) {
+ ScriptLanguage *lang = ScriptServer::get_language(i);
+ script_option_edit->add_item(lang->get_name());
+ }
script_option_edit->select(0);
- //TODO: add other languages
grid->add_child(script_option_edit);
Label *script_lb = memnew(Label);
@@ -219,6 +231,7 @@ PluginConfigDialog::PluginConfigDialog() {
script_edit->set_placeholder("\"plugin.gd\" -> res://addons/my_plugin/plugin.gd");
grid->add_child(script_edit);
+ // TODO Make this option work better with languages like C#. Right now, it does not work because the C# project must be compiled first.
Label *active_lb = memnew(Label);
active_lb->set_text(TTR("Activate now?"));
grid->add_child(active_lb);
diff --git a/modules/gdscript/gdscript.cpp b/modules/gdscript/gdscript.cpp
index 9d263aa5e1..ae70525de5 100644
--- a/modules/gdscript/gdscript.cpp
+++ b/modules/gdscript/gdscript.cpp
@@ -642,7 +642,8 @@ Variant GDScript::call(const StringName &p_method, const Variant **p_args, int p
if (E) {
if (!E->get()->is_static()) {
- WARN_PRINT(String("Can't call non-static function: '" + String(p_method) + "' in script.").utf8().get_data());
+ ERR_EXPLAIN("Can't call non-static function: '" + String(p_method) + "' in script.");
+ ERR_FAIL_V(Variant());
}
return E->get()->call(NULL, p_args, p_argcount, r_error);
diff --git a/modules/gdscript/gdscript_parser.cpp b/modules/gdscript/gdscript_parser.cpp
index a012ccad30..af189fdb7e 100644
--- a/modules/gdscript/gdscript_parser.cpp
+++ b/modules/gdscript/gdscript_parser.cpp
@@ -811,6 +811,21 @@ GDScriptParser::Node *GDScriptParser::_parse_expression(Node *p_parent, bool p_s
expr = constant;
bfn = true;
}
+
+ // Check parents for the constant
+ if (!bfn && cln->extends_file != StringName()) {
+ Ref<GDScript> parent = ResourceLoader::load(cln->extends_file);
+ if (parent.is_valid() && parent->is_valid()) {
+ Map<StringName, Variant> parent_constants;
+ parent->get_constants(&parent_constants);
+ if (parent_constants.has(identifier)) {
+ ConstantNode *constant = alloc_node<ConstantNode>();
+ constant->value = parent_constants[identifier];
+ expr = constant;
+ bfn = true;
+ }
+ }
+ }
}
if (!bfn) {
@@ -4667,7 +4682,7 @@ void GDScriptParser::_parse_class(ClassNode *p_class) {
}
}
#ifdef TOOLS_ENABLED
- if (subexpr->type == Node::TYPE_CONSTANT && member._export.type != Variant::NIL) {
+ if (subexpr->type == Node::TYPE_CONSTANT && (member._export.type != Variant::NIL || member.data_type.has_type)) {
ConstantNode *cn = static_cast<ConstantNode *>(subexpr);
if (cn->value.get_type() != Variant::NIL) {
@@ -5438,6 +5453,12 @@ GDScriptParser::DataType GDScriptParser::_resolve_type(const DataType &p_source,
// Inner classes
ClassNode *outer_class = p;
while (outer_class) {
+ if (outer_class->name == id) {
+ found = true;
+ result.kind = DataType::CLASS;
+ result.class_type = outer_class;
+ break;
+ }
for (int i = 0; i < outer_class->subclasses.size(); i++) {
if (outer_class->subclasses[i] == p) {
continue;
@@ -7277,7 +7298,7 @@ void GDScriptParser::_check_class_level_types(ClassNode *p_class) {
DataType cont = _resolve_type(c.type, c.expression->line);
DataType expr = _resolve_type(c.expression->get_datatype(), c.expression->line);
- if (!_is_type_compatible(cont, expr)) {
+ if (check_types && !_is_type_compatible(cont, expr)) {
_set_error("Constant value type (" + expr.to_string() + ") is not compatible with declared type (" + cont.to_string() + ").",
c.expression->line);
return;
@@ -7321,7 +7342,7 @@ void GDScriptParser::_check_class_level_types(ClassNode *p_class) {
if (v.expression) {
DataType expr_type = _reduce_node_type(v.expression);
- if (!_is_type_compatible(v.data_type, expr_type)) {
+ if (check_types && !_is_type_compatible(v.data_type, expr_type)) {
// Try supertype test
if (_is_type_compatible(expr_type, v.data_type)) {
_mark_line_as_unsafe(v.line);
@@ -7783,7 +7804,7 @@ void GDScriptParser::_check_block_types(BlockNode *p_block) {
return;
}
- if (!lh_type.has_type) {
+ if (!lh_type.has_type && check_types) {
if (op->arguments[0]->type == Node::TYPE_OPERATOR) {
_mark_line_as_unsafe(op->line);
}
@@ -7805,7 +7826,7 @@ void GDScriptParser::_check_block_types(BlockNode *p_block) {
bool valid = false;
rh_type = _get_operation_type(oper, lh_type, arg_type, valid);
- if (!valid) {
+ if (check_types && !valid) {
_set_error("Invalid operand types ('" + lh_type.to_string() + "' and '" + arg_type.to_string() +
"') to assignment operator '" + Variant::get_operator_name(oper) + "'.",
op->line);
@@ -7828,7 +7849,7 @@ void GDScriptParser::_check_block_types(BlockNode *p_block) {
}
#endif // DEBUG_ENABLED
- if (!_is_type_compatible(lh_type, rh_type)) {
+ if (check_types && !_is_type_compatible(lh_type, rh_type)) {
// Try supertype test
if (_is_type_compatible(rh_type, lh_type)) {
_mark_line_as_unsafe(op->line);
@@ -7864,9 +7885,11 @@ void GDScriptParser::_check_block_types(BlockNode *p_block) {
#endif // DEBUG_ENABLED
}
}
+#ifdef DEBUG_ENABLED
if (!rh_type.has_type && (op->op != OperatorNode::OP_ASSIGN || lh_type.has_type || op->arguments[0]->type == Node::TYPE_OPERATOR)) {
_mark_line_as_unsafe(op->line);
}
+#endif // DEBUG_ENABLED
} break;
case OperatorNode::OP_CALL:
case OperatorNode::OP_PARENT_CALL: {
@@ -8103,7 +8126,6 @@ Error GDScriptParser::_parse(const String &p_base_path) {
check_types = false;
#endif
-#ifdef DEBUG_ENABLED
// Resolve all class-level stuff before getting into function blocks
_check_class_level_types(main_class);
@@ -8118,6 +8140,8 @@ Error GDScriptParser::_parse(const String &p_base_path) {
return ERR_PARSE_ERROR;
}
+#ifdef DEBUG_ENABLED
+
// Resolve warning ignores
Vector<Pair<int, String> > warning_skips = tokenizer->get_warning_skips();
bool warning_is_error = GLOBAL_GET("debug/gdscript/warnings/treat_warnings_as_errors").booleanize();
diff --git a/platform/windows/os_windows.cpp b/platform/windows/os_windows.cpp
index 9fd372fd98..35f9d541ef 100644
--- a/platform/windows/os_windows.cpp
+++ b/platform/windows/os_windows.cpp
@@ -805,6 +805,13 @@ LRESULT OS_Windows::WndProc(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam)
gr_mem = alt_mem;
}
+ if (mouse_mode == MOUSE_MODE_CAPTURED) {
+ // When SetCapture is used, ALT+F4 hotkey is ignored by Windows, so handle it ourselves
+ if (wParam == VK_F4 && alt_mem && (uMsg == WM_KEYDOWN || uMsg == WM_SYSKEYDOWN)) {
+ if (main_loop)
+ main_loop->notification(MainLoop::NOTIFICATION_WM_QUIT_REQUEST);
+ }
+ }
/*
if (wParam==VK_WIN) TODO wtf is this?
meta_mem=uMsg==WM_KEYDOWN;
@@ -2335,6 +2342,9 @@ void OS_Windows::set_custom_mouse_cursor(const RES &p_cursor, CursorShape p_shap
iconinfo.hbmMask = hAndMask;
iconinfo.hbmColor = hXorMask;
+ if (cursors[p_shape])
+ DestroyIcon(cursors[p_shape]);
+
cursors[p_shape] = CreateIconIndirect(&iconinfo);
if (p_shape == cursor_shape) {
diff --git a/scene/2d/canvas_item.cpp b/scene/2d/canvas_item.cpp
index 6ed008cf9c..dced688899 100644
--- a/scene/2d/canvas_item.cpp
+++ b/scene/2d/canvas_item.cpp
@@ -434,6 +434,11 @@ void CanvasItem::hide() {
_change_notify("visible");
}
+CanvasItem *CanvasItem::current_item_drawn = NULL;
+CanvasItem *CanvasItem::get_current_item_drawn() {
+ return current_item_drawn;
+}
+
void CanvasItem::_update_callback() {
if (!is_inside_tree()) {
@@ -449,11 +454,13 @@ void CanvasItem::_update_callback() {
first_draw = false;
}
drawing = true;
+ current_item_drawn = this;
notification(NOTIFICATION_DRAW);
emit_signal(SceneStringNames::get_singleton()->draw);
if (get_script_instance()) {
get_script_instance()->call_multilevel_reversed(SceneStringNames::get_singleton()->_draw, NULL, 0);
}
+ current_item_drawn = NULL;
drawing = false;
}
//todo updating = false
diff --git a/scene/2d/canvas_item.h b/scene/2d/canvas_item.h
index a02e792cf2..bf7cfa8e75 100644
--- a/scene/2d/canvas_item.h
+++ b/scene/2d/canvas_item.h
@@ -222,6 +222,8 @@ private:
void _set_on_top(bool p_on_top) { set_draw_behind_parent(!p_on_top); }
bool _is_on_top() const { return !is_draw_behind_parent_enabled(); }
+ static CanvasItem *current_item_drawn;
+
protected:
_FORCE_INLINE_ void _notify_transform() {
if (!is_inside_tree()) return;
@@ -324,6 +326,8 @@ public:
void draw_set_transform(const Point2 &p_offset, float p_rot, const Size2 &p_scale);
void draw_set_transform_matrix(const Transform2D &p_matrix);
+ static CanvasItem *get_current_item_drawn();
+
/* RECT / TRANSFORM */
void set_as_toplevel(bool p_toplevel);
diff --git a/scene/3d/physics_body.cpp b/scene/3d/physics_body.cpp
index 22da51ac30..50abbd483a 100644
--- a/scene/3d/physics_body.cpp
+++ b/scene/3d/physics_body.cpp
@@ -188,7 +188,7 @@ PhysicsBody::PhysicsBody(PhysicsServer::BodyMode p_mode) :
#ifndef DISABLE_DEPRECATED
void StaticBody::set_friction(real_t p_friction) {
- if (p_friction == 1.0) { // default value, don't create an override for that
+ if (p_friction == 1.0 && physics_material_override.is_null()) { // default value, don't create an override for that
return;
}
@@ -218,7 +218,7 @@ real_t StaticBody::get_friction() const {
void StaticBody::set_bounce(real_t p_bounce) {
- if (p_bounce == 0.0) { // default value, don't create an override for that
+ if (p_bounce == 0.0 && physics_material_override.is_null()) { // default value, don't create an override for that
return;
}
@@ -632,7 +632,7 @@ real_t RigidBody::get_weight() const {
#ifndef DISABLE_DEPRECATED
void RigidBody::set_friction(real_t p_friction) {
- if (p_friction == 1.0) { // default value, don't create an override for that
+ if (p_friction == 1.0 && physics_material_override.is_null()) { // default value, don't create an override for that
return;
}
@@ -661,7 +661,7 @@ real_t RigidBody::get_friction() const {
void RigidBody::set_bounce(real_t p_bounce) {
- if (p_bounce == 0.0) { // default value, don't create an override for that
+ if (p_bounce == 0.0 && physics_material_override.is_null()) { // default value, don't create an override for that
return;
}
diff --git a/scene/gui/base_button.cpp b/scene/gui/base_button.cpp
index a6b4d475ba..806c8afa5b 100644
--- a/scene/gui/base_button.cpp
+++ b/scene/gui/base_button.cpp
@@ -82,16 +82,16 @@ void BaseButton::_gui_input(Ref<InputEvent> p_event) {
get_script_instance()->call(SceneStringNames::get_singleton()->_pressed, NULL, 0, ce);
}
- emit_signal("pressed");
_unpress_group();
+ emit_signal("pressed");
} else {
status.pressed = !status.pressed;
pressed();
- emit_signal("pressed");
_unpress_group();
+ emit_signal("pressed");
toggled(status.pressed);
if (get_script_instance()) {
@@ -135,6 +135,7 @@ void BaseButton::_gui_input(Ref<InputEvent> p_event) {
get_script_instance()->call(SceneStringNames::get_singleton()->_pressed, NULL, 0, ce);
}
+ _unpress_group();
emit_signal("pressed");
} else {
@@ -142,6 +143,7 @@ void BaseButton::_gui_input(Ref<InputEvent> p_event) {
status.pressed = !status.pressed;
pressed();
+ _unpress_group();
emit_signal("pressed");
toggled(status.pressed);
@@ -150,8 +152,6 @@ void BaseButton::_gui_input(Ref<InputEvent> p_event) {
}
emit_signal("toggled", status.pressed);
}
-
- _unpress_group();
}
status.press_attempt = false;
@@ -215,12 +215,14 @@ void BaseButton::_gui_input(Ref<InputEvent> p_event) {
get_script_instance()->call(SceneStringNames::get_singleton()->_pressed, NULL, 0, ce);
}
+ _unpress_group();
emit_signal("pressed");
} else {
status.pressed = !status.pressed;
pressed();
+ _unpress_group();
emit_signal("pressed");
toggled(status.pressed);
@@ -229,8 +231,6 @@ void BaseButton::_gui_input(Ref<InputEvent> p_event) {
}
emit_signal("toggled", status.pressed);
}
-
- _unpress_group();
}
accept_event();
diff --git a/scene/gui/progress_bar.cpp b/scene/gui/progress_bar.cpp
index e7564bbf73..2195ec9778 100644
--- a/scene/gui/progress_bar.cpp
+++ b/scene/gui/progress_bar.cpp
@@ -92,5 +92,6 @@ void ProgressBar::_bind_methods() {
ProgressBar::ProgressBar() {
set_v_size_flags(0);
+ set_step(0.01);
percent_visible = true;
}
diff --git a/scene/resources/dynamic_font.cpp b/scene/resources/dynamic_font.cpp
index 5660f0a1b9..fd7b67a218 100644
--- a/scene/resources/dynamic_font.cpp
+++ b/scene/resources/dynamic_font.cpp
@@ -1009,7 +1009,7 @@ void DynamicFont::_bind_methods() {
ADD_GROUP("Settings", "");
ADD_PROPERTY(PropertyInfo(Variant::INT, "size"), "set_size", "get_size");
- ADD_PROPERTY(PropertyInfo(Variant::INT, "outline_size"), "set_outline_size", "get_outline_size");
+ ADD_PROPERTY(PropertyInfo(Variant::INT, "outline_size", PROPERTY_HINT_RANGE, "0,255,1"), "set_outline_size", "get_outline_size");
ADD_PROPERTY(PropertyInfo(Variant::COLOR, "outline_color"), "set_outline_color", "get_outline_color");
ADD_PROPERTY(PropertyInfo(Variant::BOOL, "use_mipmaps"), "set_use_mipmaps", "get_use_mipmaps");
ADD_PROPERTY(PropertyInfo(Variant::BOOL, "use_filter"), "set_use_filter", "get_use_filter");
diff --git a/scene/resources/style_box.cpp b/scene/resources/style_box.cpp
index db7153e9ad..affe9a3e24 100644
--- a/scene/resources/style_box.cpp
+++ b/scene/resources/style_box.cpp
@@ -29,6 +29,8 @@
/*************************************************************************/
#include "style_box.h"
+#include "scene/2d/canvas_item.h"
+
#include <limits.h>
bool StyleBox::test_mask(const Point2 &p_point, const Rect2 &p_rect) const {
@@ -54,6 +56,10 @@ float StyleBox::get_margin(Margin p_margin) const {
return margin[p_margin];
}
+CanvasItem *StyleBox::get_current_item_drawn() const {
+ return CanvasItem::get_current_item_drawn();
+}
+
Size2 StyleBox::get_minimum_size() const {
return Size2(get_margin(MARGIN_LEFT) + get_margin(MARGIN_RIGHT), get_margin(MARGIN_TOP) + get_margin(MARGIN_BOTTOM));
@@ -83,6 +89,7 @@ void StyleBox::_bind_methods() {
ClassDB::bind_method(D_METHOD("get_minimum_size"), &StyleBox::get_minimum_size);
ClassDB::bind_method(D_METHOD("get_center_size"), &StyleBox::get_center_size);
ClassDB::bind_method(D_METHOD("get_offset"), &StyleBox::get_offset);
+ ClassDB::bind_method(D_METHOD("get_current_item_drawn"), &StyleBox::get_current_item_drawn);
ClassDB::bind_method(D_METHOD("draw", "canvas_item", "rect"), &StyleBox::draw);
diff --git a/scene/resources/style_box.h b/scene/resources/style_box.h
index 911a457990..9062270765 100644
--- a/scene/resources/style_box.h
+++ b/scene/resources/style_box.h
@@ -37,6 +37,8 @@
/**
@author Juan Linietsky <reduzio@gmail.com>
*/
+class CanvasItem;
+
class StyleBox : public Resource {
GDCLASS(StyleBox, Resource);
@@ -58,6 +60,8 @@ public:
virtual void draw(RID p_canvas_item, const Rect2 &p_rect) const = 0;
+ CanvasItem *get_current_item_drawn() const;
+
Size2 get_minimum_size() const;
Point2 get_offset() const;
diff --git a/scene/resources/texture.cpp b/scene/resources/texture.cpp
index 4984af57b5..3870916779 100644
--- a/scene/resources/texture.cpp
+++ b/scene/resources/texture.cpp
@@ -185,6 +185,7 @@ void ImageTexture::create(int p_width, int p_height, Image::Format p_format, uin
format = p_format;
w = p_width;
h = p_height;
+ _change_notify();
}
void ImageTexture::create_from_image(const Ref<Image> &p_image, uint32_t p_flags) {
@@ -211,6 +212,7 @@ void ImageTexture::set_flags(uint32_t p_flags) {
return; //uninitialized, do not set to texture
}
VisualServer::get_singleton()->texture_set_flags(texture, p_flags);
+ _change_notify("flags");
}
uint32_t ImageTexture::get_flags() const {
@@ -712,6 +714,7 @@ Error StreamTexture::load(const String &p_path) {
path_to_file = p_path;
format = image->get_format();
+ _change_notify();
return OK;
}
String StreamTexture::get_load_path() const {
@@ -801,6 +804,7 @@ bool StreamTexture::is_pixel_opaque(int p_x, int p_y) const {
void StreamTexture::set_flags(uint32_t p_flags) {
flags = p_flags;
VS::get_singleton()->texture_set_flags(texture, flags);
+ _change_notify("flags");
}
void StreamTexture::reload_from_file() {
diff --git a/thirdparty/README.md b/thirdparty/README.md
index 186f183ea2..738835c70a 100644
--- a/thirdparty/README.md
+++ b/thirdparty/README.md
@@ -202,6 +202,9 @@ Files extracted from upstream source:
- all .h files in include/theora/ as theora/
- COPYING and LICENSE
+Upstream patches included in the `patches` directory have been applied
+on top of the 1.1.1 source (not included in any stable release yet).
+
## libvorbis
diff --git a/thirdparty/libtheora/decode.c b/thirdparty/libtheora/decode.c
index 7be66463d8..bde967b794 100644
--- a/thirdparty/libtheora/decode.c
+++ b/thirdparty/libtheora/decode.c
@@ -397,10 +397,10 @@ static int oc_dec_init(oc_dec_ctx *_dec,const th_info *_info,
int qsum;
qsum=0;
for(qti=0;qti<2;qti++)for(pli=0;pli<3;pli++){
- qsum+=_dec->state.dequant_tables[qti][pli][qi][12]+
- _dec->state.dequant_tables[qti][pli][qi][17]+
- _dec->state.dequant_tables[qti][pli][qi][18]+
- _dec->state.dequant_tables[qti][pli][qi][24]<<(pli==0);
+ qsum+=_dec->state.dequant_tables[qi][pli][qti][12]+
+ _dec->state.dequant_tables[qi][pli][qti][17]+
+ _dec->state.dequant_tables[qi][pli][qti][18]+
+ _dec->state.dequant_tables[qi][pli][qti][24]<<(pli==0);
}
_dec->pp_sharp_mod[qi]=-(qsum>>11);
}
diff --git a/thirdparty/libtheora/patches/theora.git-0ae66d565e6bead8604d312bc1a4e9dccf245c88.patch b/thirdparty/libtheora/patches/theora.git-0ae66d565e6bead8604d312bc1a4e9dccf245c88.patch
new file mode 100644
index 0000000000..1b9c8e20be
--- /dev/null
+++ b/thirdparty/libtheora/patches/theora.git-0ae66d565e6bead8604d312bc1a4e9dccf245c88.patch
@@ -0,0 +1,38 @@
+From 0ae66d565e6bead8604d312bc1a4e9dccf245c88 Mon Sep 17 00:00:00 2001
+From: Tim Terriberry <tterribe@xiph.org>
+Date: Tue, 8 May 2012 02:51:57 +0000
+Subject: [PATCH] Fix pp_sharp_mod calculation.
+
+This was broken when the dequant_tables indexing changed in commit
+ r16102, but it only affected post-processing quality, so we never
+ noticed.
+With gcc 4.8.0, this can now trigger a segfault during decoder
+ initialization.
+
+svn path=/trunk/theora/; revision=18268
+---
+ decode.c | 8 ++++----
+ 1 file changed, 4 insertions(+), 4 deletions(-)
+
+diff --git a/decode.c b/decode.c
+index b803505..9f2516a 100644
+--- a/decode.c
++++ b/decode.c
+@@ -400,10 +400,10 @@ static int oc_dec_init(oc_dec_ctx *_dec,const th_info *_info,
+ int qsum;
+ qsum=0;
+ for(qti=0;qti<2;qti++)for(pli=0;pli<3;pli++){
+- qsum+=_dec->state.dequant_tables[qti][pli][qi][12]+
+- _dec->state.dequant_tables[qti][pli][qi][17]+
+- _dec->state.dequant_tables[qti][pli][qi][18]+
+- _dec->state.dequant_tables[qti][pli][qi][24]<<(pli==0);
++ qsum+=_dec->state.dequant_tables[qi][pli][qti][12]+
++ _dec->state.dequant_tables[qi][pli][qti][17]+
++ _dec->state.dequant_tables[qi][pli][qti][18]+
++ _dec->state.dequant_tables[qi][pli][qti][24]<<(pli==0);
+ }
+ _dec->pp_sharp_mod[qi]=-(qsum>>11);
+ }
+--
+2.11.0
+