diff options
47 files changed, 646 insertions, 358 deletions
diff --git a/core/os/memory.cpp b/core/os/memory.cpp index 069ee48fae..acc960acd9 100644 --- a/core/os/memory.cpp +++ b/core/os/memory.cpp @@ -29,6 +29,7 @@ /*************************************************************************/ #include "memory.h" #include "copymem.h" +#include "core/safe_refcount.h" #include "error_macros.h" #include <stdio.h> #include <stdlib.h> @@ -43,14 +44,12 @@ void *operator new(size_t p_size, void *(*p_allocfunc)(size_t p_size)) { return p_allocfunc(p_size); } -#include <stdio.h> - #ifdef DEBUG_ENABLED -size_t Memory::mem_usage = 0; -size_t Memory::max_usage = 0; +uint64_t Memory::mem_usage = 0; +uint64_t Memory::max_usage = 0; #endif -size_t Memory::alloc_count = 0; +uint64_t Memory::alloc_count = 0; void *Memory::alloc_static(size_t p_bytes, bool p_pad_align) { @@ -62,10 +61,10 @@ void *Memory::alloc_static(size_t p_bytes, bool p_pad_align) { void *mem = malloc(p_bytes + (prepad ? PAD_ALIGN : 0)); - alloc_count++; - ERR_FAIL_COND_V(!mem, NULL); + atomic_increment(&alloc_count); + if (prepad) { uint64_t *s = (uint64_t *)mem; *s = p_bytes; @@ -73,10 +72,8 @@ void *Memory::alloc_static(size_t p_bytes, bool p_pad_align) { uint8_t *s8 = (uint8_t *)mem; #ifdef DEBUG_ENABLED - mem_usage += p_bytes; - if (mem_usage > max_usage) { - max_usage = mem_usage; - } + atomic_add(&mem_usage, p_bytes); + atomic_exchange_if_greater(&max_usage, mem_usage); #endif return s8 + PAD_ALIGN; } else { @@ -103,8 +100,12 @@ void *Memory::realloc_static(void *p_memory, size_t p_bytes, bool p_pad_align) { uint64_t *s = (uint64_t *)mem; #ifdef DEBUG_ENABLED - mem_usage -= *s; - mem_usage += p_bytes; + if (p_bytes > *s) { + atomic_add(&mem_usage, p_bytes - *s); + atomic_exchange_if_greater(&max_usage, mem_usage); + } else { + atomic_sub(&mem_usage, *s - p_bytes); + } #endif if (p_bytes == 0) { @@ -144,14 +145,14 @@ void Memory::free_static(void *p_ptr, bool p_pad_align) { bool prepad = p_pad_align; #endif - alloc_count--; + atomic_decrement(&alloc_count); if (prepad) { mem -= PAD_ALIGN; uint64_t *s = (uint64_t *)mem; #ifdef DEBUG_ENABLED - mem_usage -= *s; + atomic_sub(&mem_usage, *s); #endif free(mem); @@ -161,19 +162,20 @@ void Memory::free_static(void *p_ptr, bool p_pad_align) { } } -size_t Memory::get_mem_available() { +uint64_t Memory::get_mem_available() { - return 0xFFFFFFFFFFFFF; + return -1; // 0xFFFF... } -size_t Memory::get_mem_usage() { +uint64_t Memory::get_mem_usage() { #ifdef DEBUG_ENABLED return mem_usage; #else return 0; #endif } -size_t Memory::get_mem_max_usage() { + +uint64_t Memory::get_mem_max_usage() { #ifdef DEBUG_ENABLED return max_usage; #else diff --git a/core/os/memory.h b/core/os/memory.h index b3eb599955..e1d7138ad5 100644 --- a/core/os/memory.h +++ b/core/os/memory.h @@ -45,20 +45,20 @@ class Memory { Memory(); #ifdef DEBUG_ENABLED - static size_t mem_usage; - static size_t max_usage; + static uint64_t mem_usage; + static uint64_t max_usage; #endif - static size_t alloc_count; + static uint64_t alloc_count; public: static void *alloc_static(size_t p_bytes, bool p_pad_align = false); static void *realloc_static(void *p_memory, size_t p_bytes, bool p_pad_align = false); static void free_static(void *p_ptr, bool p_pad_align = false); - static size_t get_mem_available(); - static size_t get_mem_usage(); - static size_t get_mem_max_usage(); + static uint64_t get_mem_available(); + static uint64_t get_mem_usage(); + static uint64_t get_mem_max_usage(); }; class DefaultAllocator { diff --git a/core/safe_refcount.cpp b/core/safe_refcount.cpp index d7e5297321..971e9ad1d5 100644 --- a/core/safe_refcount.cpp +++ b/core/safe_refcount.cpp @@ -78,6 +78,15 @@ static _ALWAYS_INLINE_ T _atomic_add_impl(register T *pw, register T val) { return *pw; } +template <class T> +static _ALWAYS_INLINE_ T _atomic_exchange_if_greater_impl(register T *pw, register T val) { + + if (val > *pw) + *pw = val; + + return *pw; +} + #elif defined(__GNUC__) /* Implementation for GCC & Clang */ @@ -121,6 +130,18 @@ static _ALWAYS_INLINE_ T _atomic_add_impl(register T *pw, register T val) { return __sync_add_and_fetch(pw, val); } +template <class T> +static _ALWAYS_INLINE_ T _atomic_exchange_if_greater_impl(register T *pw, register T val) { + + while (true) { + T tmp = static_cast<T const volatile &>(*pw); + if (tmp >= val) + return tmp; // already greater, or equal + if (__sync_val_compare_and_swap(pw, tmp, val) == tmp) + return val; + } +} + #elif defined(_MSC_VER) /* Implementation for MSVC-Windows */ @@ -139,6 +160,15 @@ static _ALWAYS_INLINE_ T _atomic_add_impl(register T *pw, register T val) { return tmp + 1; \ } +#define ATOMIC_EXCHANGE_IF_GREATER_BODY(m_pw, m_val, m_win_type, m_win_cmpxchg, m_cpp_type) \ + while (true) { \ + m_cpp_type tmp = static_cast<m_cpp_type const volatile &>(*(m_pw)); \ + if (tmp >= m_val) \ + return tmp; /* already greater, or equal */ \ + if (m_win_cmpxchg((m_win_type volatile *)(m_pw), m_val, tmp) == tmp) \ + return m_val; \ + } + static _ALWAYS_INLINE_ uint32_t _atomic_conditional_increment_impl(register uint32_t *pw) { ATOMIC_CONDITIONAL_INCREMENT_BODY(pw, LONG, InterlockedCompareExchange, uint32_t) @@ -156,11 +186,7 @@ static _ALWAYS_INLINE_ uint32_t _atomic_increment_impl(register uint32_t *pw) { static _ALWAYS_INLINE_ uint32_t _atomic_sub_impl(register uint32_t *pw, register uint32_t val) { -#if _WIN32_WINNT >= 0x0601 // Windows 7+ - return InterlockedExchangeSubtract(pw, val) - val; -#else return InterlockedExchangeAdd((LONG volatile *)pw, -(int32_t)val) - val; -#endif } static _ALWAYS_INLINE_ uint32_t _atomic_add_impl(register uint32_t *pw, register uint32_t val) { @@ -168,6 +194,11 @@ static _ALWAYS_INLINE_ uint32_t _atomic_add_impl(register uint32_t *pw, register return InterlockedAdd((LONG volatile *)pw, val); } +static _ALWAYS_INLINE_ uint32_t _atomic_exchange_if_greater_impl(register uint32_t *pw, register uint32_t val) { + + ATOMIC_EXCHANGE_IF_GREATER_BODY(pw, val, LONG, InterlockedCompareExchange, uint32_t) +} + static _ALWAYS_INLINE_ uint64_t _atomic_conditional_increment_impl(register uint64_t *pw) { ATOMIC_CONDITIONAL_INCREMENT_BODY(pw, LONGLONG, InterlockedCompareExchange64, uint64_t) @@ -185,11 +216,7 @@ static _ALWAYS_INLINE_ uint64_t _atomic_increment_impl(register uint64_t *pw) { static _ALWAYS_INLINE_ uint64_t _atomic_sub_impl(register uint64_t *pw, register uint64_t val) { -#if _WIN32_WINNT >= 0x0601 && !defined(UWP_ENABLED) // Windows 7+ except UWP - return InterlockedExchangeSubtract64(pw, val) - val; -#else return InterlockedExchangeAdd64((LONGLONG volatile *)pw, -(int64_t)val) - val; -#endif } static _ALWAYS_INLINE_ uint64_t _atomic_add_impl(register uint64_t *pw, register uint64_t val) { @@ -197,6 +224,11 @@ static _ALWAYS_INLINE_ uint64_t _atomic_add_impl(register uint64_t *pw, register return InterlockedAdd64((LONGLONG volatile *)pw, val); } +static _ALWAYS_INLINE_ uint64_t _atomic_exchange_if_greater_impl(register uint64_t *pw, register uint64_t val) { + + ATOMIC_EXCHANGE_IF_GREATER_BODY(pw, val, LONGLONG, InterlockedCompareExchange64, uint64_t) +} + #else //no threads supported? @@ -226,6 +258,10 @@ uint32_t atomic_add(register uint32_t *pw, register uint32_t val) { return _atomic_add_impl(pw, val); } +uint32_t atomic_exchange_if_greater(register uint32_t *pw, register uint32_t val) { + return _atomic_exchange_if_greater_impl(pw, val); +} + uint64_t atomic_conditional_increment(register uint64_t *counter) { return _atomic_conditional_increment_impl(counter); } @@ -245,3 +281,7 @@ uint64_t atomic_sub(register uint64_t *pw, register uint64_t val) { uint64_t atomic_add(register uint64_t *pw, register uint64_t val) { return _atomic_add_impl(pw, val); } + +uint64_t atomic_exchange_if_greater(register uint64_t *pw, register uint64_t val) { + return _atomic_exchange_if_greater_impl(pw, val); +} diff --git a/core/safe_refcount.h b/core/safe_refcount.h index a2d2b5e127..ed0620c777 100644 --- a/core/safe_refcount.h +++ b/core/safe_refcount.h @@ -41,12 +41,14 @@ uint32_t atomic_decrement(register uint32_t *pw); uint32_t atomic_increment(register uint32_t *pw); uint32_t atomic_sub(register uint32_t *pw, register uint32_t val); uint32_t atomic_add(register uint32_t *pw, register uint32_t val); +uint32_t atomic_exchange_if_greater(register uint32_t *pw, register uint32_t val); uint64_t atomic_conditional_increment(register uint64_t *counter); uint64_t atomic_decrement(register uint64_t *pw); uint64_t atomic_increment(register uint64_t *pw); uint64_t atomic_sub(register uint64_t *pw, register uint64_t val); uint64_t atomic_add(register uint64_t *pw, register uint64_t val); +uint64_t atomic_exchange_if_greater(register uint64_t *pw, register uint64_t val); struct SafeRefCount { diff --git a/doc/base/classes.xml b/doc/base/classes.xml index 058753132e..268bfeca1a 100644 --- a/doc/base/classes.xml +++ b/doc/base/classes.xml @@ -746,13 +746,16 @@ [AudioServer] singleton </member> <member name="ClassDB" type="ClassDB" setter="" getter="" brief=""> + [ClassDB] singleton </member> <member name="Engine" type="Engine" setter="" getter="" brief=""> + [Engine] singleton </member> <member name="Geometry" type="Geometry" setter="" getter="" brief=""> [Geometry] singleton </member> <member name="ProjectSettings" type="ProjectSettings" setter="" getter="" brief=""> + [ProjectSettings] singleton </member> <member name="IP" type="IP" setter="" getter="" brief=""> [IP] singleton @@ -4632,7 +4635,7 @@ <argument index="0" name="from" type="PoolColorArray"> </argument> <description> - Construct an array from a [PoolByteArray]. + Construct an array from a [PoolColorArray]. </description> </method> <method name="Array"> @@ -4641,7 +4644,7 @@ <argument index="0" name="from" type="PoolVector3Array"> </argument> <description> - Construct an array from a [PoolByteArray]. + Construct an array from a [PoolVector3Array]. </description> </method> <method name="Array"> @@ -4650,7 +4653,7 @@ <argument index="0" name="from" type="PoolVector2Array"> </argument> <description> - Construct an array from a [PoolByteArray]. + Construct an array from a [PoolVector2Array]. </description> </method> <method name="Array"> @@ -4677,7 +4680,7 @@ <argument index="0" name="from" type="PoolIntArray"> </argument> <description> - Construct an array from a [PoolByteArray]. + Construct an array from a [PoolIntArray]. </description> </method> <method name="Array"> @@ -10169,12 +10172,73 @@ <description> </description> </method> + <method name="create_shape_owner"> + <return type="int"> + </return> + <argument index="0" name="owner" type="Object"> + </argument> + <description> + Creates new holder for the shapes. Argument is a [CollisionShape] node. It will return owner_id which usually you will want to save for later use. + </description> + </method> <method name="get_rid" qualifiers="const"> <return type="RID"> </return> <description> </description> </method> + <method name="get_shape_owners"> + <return type="Array"> + </return> + <description> + Shape owner is a node which is holding concrete shape resources. This method will return an array which is holding an integer numbers that are representing unique ID of each owner. You can use those ids when you are using others shape_owner methods. + </description> + </method> + <method name="shape_owner_clear_shapes"> + <argument index="0" name="owner_id" type="int"> + </argument> + <description> + Will remove all the shapes associated with given owner. + </description> + </method> + <method name="shape_owner_get_shape"> + <return type="Shape"> + </return> + <argument index="0" name="owner_id" type="int"> + </argument> + <argument index="1" name="shape_id" type="int"> + </argument> + <description> + Will return a [Shape]. First argument owner_id is an integer that can be obtained from [method get_shape_owners]. Shape_id is a position of the shape inside owner; it's a value in range from 0 to [method shape_owner_get_shape_count]. + </description> + </method> + <method name="shape_owner_get_shape_count"> + <return type="int"> + </return> + <argument index="0" name="owner_id" type="int"> + </argument> + <description> + Returns number of shapes to which given owner is associated to. + </description> + </method> + <method name="shape_owner_get_transform"> + <return type="Transform"> + </return> + <argument index="0" name="owner_id" type="int"> + </argument> + <description> + Will return [Transform] of an owner node. + </description> + </method> + <method name="shape_owner_remove_shape"> + <argument index="0" name="owner_id" type="int"> + </argument> + <argument index="1" name="shape_id" type="int"> + </argument> + <description> + Removes related shape from the owner. + </description> + </method> <method name="is_ray_pickable" qualifiers="const"> <return type="bool"> </return> @@ -10245,6 +10309,15 @@ <description> </description> </method> + <method name="create_shape_owner"> + <return type="int"> + </return> + <argument index="0" name="owner" type="Object"> + </argument> + <description> + Creates new holder for the shapes. Argument is a [CollisionShape2D] node. It will return owner_id which usually you will want to save for later use. + </description> + </method> <method name="get_rid" qualifiers="const"> <return type="RID"> </return> @@ -10252,6 +10325,58 @@ Return the RID of this object. </description> </method> + <method name="get_shape_owners"> + <return type="Array"> + </return> + <description> + Shape owner is a node which is holding concrete shape resources. This method will return an array which is holding an integer numbers that are representing unique ID of each owner. You can use those ids when you are using others shape_owner methods. + </description> + </method> + <method name="shape_owner_clear_shapes"> + <argument index="0" name="owner_id" type="int"> + </argument> + <description> + Will remove all the shapes associated with given owner. + </description> + </method> + <method name="shape_owner_get_shape"> + <return type="Shape2D"> + </return> + <argument index="0" name="owner_id" type="int"> + </argument> + <argument index="1" name="shape_id" type="int"> + </argument> + <description> + Will return a [Shape2D]. First argument owner_id is an integer that can be obtained from [method get_shape_owners]. Shape_id is a position of the shape inside owner; it's a value in range from 0 to [method shape_owner_get_shape_count]. + </description> + </method> + <method name="shape_owner_get_shape_count"> + <return type="int"> + </return> + <argument index="0" name="owner_id" type="int"> + </argument> + <description> + Returns number of shapes to which given owner is associated to. + </description> + </method> + <method name="shape_owner_get_transform"> + <return type="Transform2D"> + </return> + <argument index="0" name="owner_id" type="int"> + </argument> + <description> + Will return [Transform2D] of an owner node. + </description> + </method> + <method name="shape_owner_remove_shape"> + <argument index="0" name="owner_id" type="int"> + </argument> + <argument index="1" name="shape_id" type="int"> + </argument> + <description> + Removes related shape from the owner. + </description> + </method> <method name="is_pickable" qualifiers="const"> <return type="bool"> </return> @@ -11394,7 +11519,7 @@ <return type="Rect2"> </return> <description> - Return position and size of the Control, relative to the top-left corner of the [i]window[/i] Control. This is a helper (see [method get_global_pos], [method get_size]). + Return position and size of the Control, relative to the top-left corner of the [i]window[/i] Control. This is a helper (see [method get_global_position], [method get_size]). </description> </method> <method name="get_h_grow_direction" qualifiers="const"> @@ -11472,7 +11597,7 @@ <return type="Rect2"> </return> <description> - Return position and size of the Control, relative to the top-left corner of the parent Control. This is a helper (see [method get_pos], [method get_size]). + Return position and size of the Control, relative to the top-left corner of the parent Control. This is a helper (see [method get_position], [method get_size]). </description> </method> <method name="get_rotation" qualifiers="const"> @@ -17793,7 +17918,7 @@ Contains global variables accessible from everywhere. </brief_description> <description> - Contains global variables accessible from everywhere. Use the normal [Object] API, such as "Globals.get(variable)", "Globals.set(variable,value)" or "Globals.has(variable)" to access them. Variables stored in project.godot are also loaded into globals, making this object very useful for reading custom game configuration options. + Contains global variables accessible from everywhere. Use the normal [Object] API, such as "ProjectSettings.get(variable)", "ProjectSettings.set(variable,value)" or "ProjectSettings.has(variable)" to access them. Variables stored in project.godot are also loaded into ProjectSettings, making this object very useful for reading custom game configuration options. </description> <methods> <method name="add_property_info"> @@ -17803,7 +17928,7 @@ Add a custom property info to a property. The dictionary must contain: name:[String](the name of the property) and type:[int](see TYPE_* in [@Global Scope]), and optionally hint:[int](see PROPERTY_HINT_* in [@Global Scope]), hint_string:[String]. Example: [codeblock] - Globals.set("category/property_name", 0) + ProjectSettings.set("category/property_name", 0) var property_info = { "name": "category/property_name", @@ -17812,7 +17937,7 @@ "hint_string": "one,two,three" } - Globals.add_property_info(property_info) + ProjectSettings.add_property_info(property_info) [/codeblock] </description> </method> @@ -21520,7 +21645,7 @@ </method> <method name="load_from_globals"> <description> - Clear the [InputMap] and load it anew from [Globals]. + Clear the [InputMap] and load it anew from [ProjectSettings]. </description> </method> </methods> @@ -24967,7 +25092,7 @@ MultiMesh provides low level mesh instancing. If the amount of [Mesh] instances needed goes from hundreds to thousands (and most need to be visible at close proximity) creating such a large amount of [MeshInstance] nodes may affect performance by using too much CPU or video memory. For this case a MultiMesh becomes very useful, as it can draw thousands of instances with little API overhead. As a drawback, if the instances are too far away of each other, performance may be reduced as every single instance will always rendered (they are spatially indexed as one, for the whole object). - Since instances may have any behavior, the Rect3 used for visibility must be provided by the user, or generated with [method generate_aabb]. + Since instances may have any behavior, the Rect3 used for visibility must be provided by the user. </description> <methods> <method name="get_aabb" qualifiers="const"> @@ -27897,7 +28022,7 @@ <return type="Array"> </return> <description> - Return the property list, array of dictionaries, dictionaries must contain: name:String, type:int (see TYPE_* enum in globals) and optionally: hint:int (see PROPERTY_HINT_* in globals), hint_string:String, usage:int (see PROPERTY_USAGE_* in globals). + Return the property list, array of dictionaries, dictionaries must contain: name:String, type:int (see TYPE_* enum in [@Global Scope]) and optionally: hint:int (see PROPERTY_HINT_* in [@Global Scope]), hint_string:String, usage:int (see PROPERTY_USAGE_* in [@Global Scope]). </description> </method> <method name="_init" qualifiers="virtual"> @@ -28058,7 +28183,7 @@ <return type="Array"> </return> <description> - Return the list of properties as an array of dictionaries, dictionaries contain: name:String, type:int (see TYPE_* enum in globals) and optionally: hint:int (see PROPERTY_HINT_* in globals), hint_string:String, usage:int (see PROPERTY_USAGE_* in globals). + Return the list of properties as an array of dictionaries, dictionaries contain: name:String, type:int (see TYPE_* enum in [@Global Scope]) and optionally: hint:int (see PROPERTY_HINT_* in [@Global Scope]), hint_string:String, usage:int (see PROPERTY_USAGE_* in [@Global Scope]). </description> </method> <method name="get_script" qualifiers="const"> @@ -34501,7 +34626,7 @@ <argument index="1" name="to" type="int"> </argument> <description> - Returns the slice of the [PoolByteArray] between indices (inclusive) as a new [RawArray]. Any negative index is considered to be from the end of the array. + Returns the slice of the [PoolByteArray] between indices (inclusive) as a new [PoolByteArray]. Any negative index is considered to be from the end of the array. </description> </method> </methods> @@ -37158,7 +37283,7 @@ <argument index="0" name="with" type="Rect3"> </argument> <description> - Return the intersection between two [Rect3]. An empty AABB (size 0,0,0) is returned on failure. + Return the intersection between two [Rect3]. An empty Rect3 (size 0,0,0) is returned on failure. </description> </method> <method name="intersects"> diff --git a/drivers/gles3/rasterizer_gles3.cpp b/drivers/gles3/rasterizer_gles3.cpp index bb7b85e653..3fc5bed80b 100644 --- a/drivers/gles3/rasterizer_gles3.cpp +++ b/drivers/gles3/rasterizer_gles3.cpp @@ -83,7 +83,6 @@ static void GLAPIENTRY _gl_debug_print(GLenum source, GLenum type, GLuint id, GL if (type == _EXT_DEBUG_TYPE_OTHER_ARB) return; - print_line("mesege"); char debSource[256], debType[256], debSev[256]; if (source == _EXT_DEBUG_SOURCE_API_ARB) strcpy(debSource, "OpenGL"); diff --git a/editor/editor_node.cpp b/editor/editor_node.cpp index 0cdb981306..4e2687449e 100644 --- a/editor/editor_node.cpp +++ b/editor/editor_node.cpp @@ -2803,9 +2803,9 @@ void EditorNode::_discard_changes(const String &p_str) { String exec = OS::get_singleton()->get_executable_path(); List<String> args; - args.push_back("-path"); + args.push_back("--path"); args.push_back(exec.get_base_dir()); - args.push_back("-pm"); + args.push_back("--project-manager"); OS::ProcessID pid = 0; Error err = OS::get_singleton()->execute(exec, args, false, &pid); diff --git a/editor/editor_run.cpp b/editor/editor_run.cpp index aa97dd237b..fee2d0ba4d 100644 --- a/editor/editor_run.cpp +++ b/editor/editor_run.cpp @@ -45,24 +45,24 @@ Error EditorRun::run(const String &p_scene, const String p_custom_args, const Li int remote_port = (int)EditorSettings::get_singleton()->get("network/debug/remote_port"); if (resource_path != "") { - args.push_back("-path"); + args.push_back("--path"); args.push_back(resource_path.replace(" ", "%20")); } if (true) { - args.push_back("-rdebug"); + args.push_back("--remote-debug"); args.push_back(remote_host + ":" + String::num(remote_port)); } - args.push_back("-epid"); + args.push_back("--editor-pid"); args.push_back(String::num(OS::get_singleton()->get_process_ID())); if (debug_collisions) { - args.push_back("-debugcol"); + args.push_back("--debug-collision"); } if (debug_navigation) { - args.push_back("-debugnav"); + args.push_back("--debug-navigation"); } int screen = EditorSettings::get_singleton()->get("run/window_placement/screen"); @@ -101,33 +101,33 @@ Error EditorRun::run(const String &p_scene, const String p_custom_args, const Li case 1: { // centered Vector2 pos = screen_rect.position + ((screen_rect.size - desired_size) / 2).floor(); args.push_back("-p"); - args.push_back(itos(pos.x) + "x" + itos(pos.y)); + args.push_back(itos(pos.x) + "," + itos(pos.y)); } break; case 2: { // custom pos Vector2 pos = EditorSettings::get_singleton()->get("run/window_placement/rect_custom_position"); pos += screen_rect.position; args.push_back("-p"); - args.push_back(itos(pos.x) + "x" + itos(pos.y)); + args.push_back(itos(pos.x) + "," + itos(pos.y)); } break; case 3: { // force maximized Vector2 pos = screen_rect.position; args.push_back("-p"); - args.push_back(itos(pos.x) + "x" + itos(pos.y)); - args.push_back("-mx"); + args.push_back(itos(pos.x) + "," + itos(pos.y)); + args.push_back("-m"); } break; case 4: { // force fullscreen Vector2 pos = screen_rect.position; args.push_back("-p"); - args.push_back(itos(pos.x) + "x" + itos(pos.y)); + args.push_back(itos(pos.x) + "," + itos(pos.y)); args.push_back("-f"); } break; } if (p_breakpoints.size()) { - args.push_back("-bp"); + args.push_back("-b"); String bpoints; for (const List<String>::Element *E = p_breakpoints.front(); E; E = E->next()) { diff --git a/editor/editor_themes.cpp b/editor/editor_themes.cpp index 6b985c7b4b..df16de947e 100644 --- a/editor/editor_themes.cpp +++ b/editor/editor_themes.cpp @@ -163,6 +163,13 @@ Ref<Theme> create_editor_theme() { theme->set_color("light_color_1", "Editor", light_color_1); theme->set_color("light_color_2", "Editor", light_color_2); + Color success_color = highlight_color.linear_interpolate(Color(0, 1, .8), 0.8); + Color warning_color = highlight_color.linear_interpolate(Color(1, 1, .2), 0.8); + Color error_color = highlight_color.linear_interpolate(Color(1, .2, .2), 0.8); + theme->set_color("success_color", "Editor", success_color); + theme->set_color("warning_color", "Editor", warning_color); + theme->set_color("error_color", "Editor", error_color); + // Checkbox icon theme->set_icon("checked", "CheckBox", theme->get_icon("GuiChecked", "EditorIcons")); theme->set_icon("unchecked", "CheckBox", theme->get_icon("GuiUnchecked", "EditorIcons")); @@ -307,8 +314,8 @@ Ref<Theme> create_editor_theme() { theme->set_icon("arrow_collapsed", "Tree", theme->get_icon("GuiTreeArrowRight", "EditorIcons")); theme->set_icon("select_arrow", "Tree", theme->get_icon("GuiDropdown", "EditorIcons")); theme->set_stylebox("bg_focus", "Tree", focus_sbt); - theme->set_stylebox("custom_button", "Tree", style_button_type); - theme->set_stylebox("custom_button_pressed", "Tree", style_button_type); + theme->set_stylebox("custom_button", "Tree", make_empty_stylebox()); + theme->set_stylebox("custom_button_pressed", "Tree", make_empty_stylebox()); theme->set_stylebox("custom_button_hover", "Tree", style_button_type); theme->set_color("custom_button_font_highlight", "Tree", HIGHLIGHT_COLOR_LIGHT); diff --git a/editor/icons/2x/icon_GUI_dropdown.png b/editor/icons/2x/icon_GUI_dropdown.png Binary files differindex c959378430..78d3352e4e 100644 --- a/editor/icons/2x/icon_GUI_dropdown.png +++ b/editor/icons/2x/icon_GUI_dropdown.png diff --git a/editor/icons/icon_GUI_dropdown.png b/editor/icons/icon_GUI_dropdown.png Binary files differindex 4bd6544830..d21cdb634e 100644 --- a/editor/icons/icon_GUI_dropdown.png +++ b/editor/icons/icon_GUI_dropdown.png diff --git a/editor/icons/source/icon_GUI_dropdown.svg b/editor/icons/source/icon_GUI_dropdown.svg index f313b09983..897f63c268 100644 --- a/editor/icons/source/icon_GUI_dropdown.svg +++ b/editor/icons/source/icon_GUI_dropdown.svg @@ -9,9 +9,9 @@ xmlns="http://www.w3.org/2000/svg" xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd" xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape" - width="8" + width="14" height="14" - viewBox="0 0 8 14" + viewBox="0 0 14 14" id="svg2" version="1.1" inkscape:version="0.92+devel unknown" @@ -28,9 +28,9 @@ borderopacity="1.0" inkscape:pageopacity="0.0" inkscape:pageshadow="2" - inkscape:zoom="45.254834" - inkscape:cx="1.2944669" - inkscape:cy="5.9830116" + inkscape:zoom="32" + inkscape:cx="6.5843041" + inkscape:cy="6.8000184" inkscape:document-units="px" inkscape:current-layer="layer1" showgrid="true" @@ -72,21 +72,21 @@ id="layer1" transform="translate(0,-1038.3622)"> <circle - style="fill:#ffffff;fill-opacity:0.58823532;stroke-width:2;stroke-linejoin:round;stroke-opacity:0.39215686" + style="fill:#ffffff;fill-opacity:0.58823529;stroke-width:2;stroke-linejoin:round;stroke-opacity:0.39215686" id="path4268" - cx="4.5" + cx="7.5" cy="1040.8622" r="1.5" /> <circle r="1.5" cy="1045.8622" - cx="4.5" + cx="7.5" id="circle4271" - style="fill:#ffffff;fill-opacity:0.58823532;stroke-width:2;stroke-linejoin:round;stroke-opacity:0.39215686" /> + style="fill:#ffffff;fill-opacity:0.58823529;stroke-width:2;stroke-linejoin:round;stroke-opacity:0.39215686" /> <circle - style="fill:#ffffff;fill-opacity:0.58823532;stroke-width:2;stroke-linejoin:round;stroke-opacity:0.39215686" + style="fill:#ffffff;fill-opacity:0.58823529;stroke-width:2;stroke-linejoin:round;stroke-opacity:0.39215686" id="circle4273" - cx="4.5" + cx="7.5" cy="1050.8622" r="1.5" /> </g> diff --git a/editor/icons/source/icon_connect.svg b/editor/icons/source/icon_connect.svg index 745d3cc436..15c8b481a1 100644 --- a/editor/icons/source/icon_connect.svg +++ b/editor/icons/source/icon_connect.svg @@ -14,7 +14,7 @@ viewBox="0 0 16 16" id="svg2" version="1.1" - inkscape:version="0.91 r13725" + inkscape:version="0.92+devel unknown" inkscape:export-filename="/home/djrm/Projects/godot/tools/editor/icons/icon_add_track.png" inkscape:export-xdpi="45" inkscape:export-ydpi="45" @@ -28,9 +28,9 @@ borderopacity="1.0" inkscape:pageopacity="0.0" inkscape:pageshadow="2" - inkscape:zoom="22.627418" - inkscape:cx="0.78663326" - inkscape:cy="12.940707" + inkscape:zoom="32.000001" + inkscape:cx="13.864856" + inkscape:cy="7.2235346" inkscape:document-units="px" inkscape:current-layer="layer1" showgrid="true" @@ -46,7 +46,8 @@ inkscape:window-height="1016" inkscape:window-x="0" inkscape:window-y="27" - inkscape:window-maximized="1"> + inkscape:window-maximized="1" + inkscape:document-rotation="0"> <inkscape:grid type="xygrid" id="grid3336" /> @@ -68,10 +69,37 @@ inkscape:groupmode="layer" id="layer1" transform="translate(0,-1036.3622)"> + <circle + style="fill:#e0e0e0;stroke:none;stroke-width:2;stroke-linecap:round;stroke-linejoin:round" + id="path4266" + cx="4" + cy="1048.3622" + r="2" /> <path - style="fill:#e0e0e0;fill-opacity:1;stroke:none;stroke-width:3;stroke-linecap:round;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1" - d="M 7 2 A 2 2 0 0 0 5 4 L 5 7 L 1 7 L 1 9 L 5 9 L 5 12 A 2 2 0 0 0 7 14 L 11 14 L 11 12 L 14 12 L 14 10 L 11 10 L 11 6 L 14 6 L 14 4 L 11 4 L 11 2 L 7 2 z " - transform="translate(0,1036.3622)" - id="rect4155" /> + id="circle4268" + style="fill:none;stroke:#e0e0e0;stroke-width:2;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1" + sodipodi:type="arc" + sodipodi:cx="4" + sodipodi:cy="1048.3622" + sodipodi:rx="5" + sodipodi:ry="5" + sodipodi:start="4.712389" + sodipodi:end="0" + sodipodi:arc-type="arc" + d="M 4.0000001,1043.3622 A 5,5 0 0 1 9,1048.3622" + sodipodi:open="true" /> + <path + id="circle4270" + style="fill:none;stroke:#e0e0e0;stroke-width:2;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1" + sodipodi:type="arc" + sodipodi:cx="4" + sodipodi:cy="1048.3622" + sodipodi:rx="9" + sodipodi:ry="9" + sodipodi:start="4.712389" + sodipodi:end="0" + sodipodi:open="true" + sodipodi:arc-type="arc" + d="m 4.0000002,1039.3622 a 9,9 0 0 1 8.9999998,9" /> </g> </svg> diff --git a/editor/import/resource_importer_texture.cpp b/editor/import/resource_importer_texture.cpp index 98020ed9b8..c0c507c2d6 100644 --- a/editor/import/resource_importer_texture.cpp +++ b/editor/import/resource_importer_texture.cpp @@ -236,7 +236,7 @@ void ResourceImporterTexture::_save_stex(const Ref<Image> &p_image, const String format |= StreamTexture::FORMAT_BIT_DETECT_NORMAL; if ((p_compress_mode == COMPRESS_LOSSLESS || p_compress_mode == COMPRESS_LOSSY) && p_image->get_format() > Image::FORMAT_RGBA8) { - p_compress_mode == COMPRESS_UNCOMPRESSED; //these can't go as lossy + p_compress_mode = COMPRESS_UNCOMPRESSED; //these can't go as lossy } switch (p_compress_mode) { diff --git a/editor/import/resource_importer_wav.cpp b/editor/import/resource_importer_wav.cpp index 18c4bed5dd..8cb712cb78 100644 --- a/editor/import/resource_importer_wav.cpp +++ b/editor/import/resource_importer_wav.cpp @@ -291,7 +291,7 @@ Error ResourceImporterWAV::import(const String &p_source_file, const String &p_s bool limit_rate = p_options["force/max_rate"]; int limit_rate_hz = p_options["force/max_rate_hz"]; - if (limit_rate && rate > limit_rate_hz) { + if (limit_rate && rate > limit_rate_hz && rate > 0 && frames > 0) { //resampleeee!!! int new_data_frames = frames * limit_rate_hz / rate; Vector<float> new_data; @@ -356,7 +356,7 @@ Error ResourceImporterWAV::import(const String &p_source_file, const String &p_s bool trim = p_options["edit/trim"]; - if (trim && !loop) { + if (trim && !loop && format_channels > 0) { int first = 0; int last = (frames * format_channels) - 1; diff --git a/editor/plugins/spatial_editor_plugin.cpp b/editor/plugins/spatial_editor_plugin.cpp index c31e11cc38..2d77bfb2c1 100644 --- a/editor/plugins/spatial_editor_plugin.cpp +++ b/editor/plugins/spatial_editor_plugin.cpp @@ -3142,7 +3142,7 @@ void SpatialEditor::_menu_item_pressed(int p_option) { xform_scale[i]->set_text("1"); } - xform_dialog->popup_centered(Size2(200, 200)); + xform_dialog->popup_centered(Size2(320, 240) * EDSCALE); } break; case MENU_VIEW_USE_1_VIEWPORT: { @@ -3964,55 +3964,59 @@ SpatialEditor::SpatialEditor(EditorNode *p_editor) { xform_dialog = memnew(ConfirmationDialog); xform_dialog->set_title(TTR("Transform Change")); add_child(xform_dialog); + + VBoxContainer *xform_vbc = memnew(VBoxContainer); + xform_dialog->add_child(xform_vbc); + Label *l = memnew(Label); l->set_text(TTR("Translate:")); - l->set_position(Point2(5, 5)); - xform_dialog->add_child(l); + xform_vbc->add_child(l); + + HBoxContainer *xform_hbc = memnew(HBoxContainer); + xform_vbc->add_child(xform_hbc); for (int i = 0; i < 3; i++) { xform_translate[i] = memnew(LineEdit); - xform_translate[i]->set_position(Point2(15 + i * 60, 22)); - xform_translate[i]->set_size(Size2(50, 12)); - xform_dialog->add_child(xform_translate[i]); + xform_translate[i]->set_h_size_flags(SIZE_EXPAND_FILL); + xform_hbc->add_child(xform_translate[i]); } l = memnew(Label); l->set_text(TTR("Rotate (deg.):")); - l->set_position(Point2(5, 45)); - xform_dialog->add_child(l); + xform_vbc->add_child(l); + + xform_hbc = memnew(HBoxContainer); + xform_vbc->add_child(xform_hbc); for (int i = 0; i < 3; i++) { xform_rotate[i] = memnew(LineEdit); - xform_rotate[i]->set_position(Point2(15 + i * 60, 62)); - xform_rotate[i]->set_size(Size2(50, 22)); - xform_dialog->add_child(xform_rotate[i]); + xform_rotate[i]->set_h_size_flags(SIZE_EXPAND_FILL); + xform_hbc->add_child(xform_rotate[i]); } l = memnew(Label); l->set_text(TTR("Scale (ratio):")); - l->set_position(Point2(5, 85)); - xform_dialog->add_child(l); + xform_vbc->add_child(l); + + xform_hbc = memnew(HBoxContainer); + xform_vbc->add_child(xform_hbc); for (int i = 0; i < 3; i++) { xform_scale[i] = memnew(LineEdit); - xform_scale[i]->set_position(Point2(15 + i * 60, 102)); - xform_scale[i]->set_size(Size2(50, 22)); - xform_dialog->add_child(xform_scale[i]); + xform_scale[i]->set_h_size_flags(SIZE_EXPAND_FILL); + xform_hbc->add_child(xform_scale[i]); } l = memnew(Label); l->set_text(TTR("Transform Type")); - l->set_position(Point2(5, 125)); - xform_dialog->add_child(l); + xform_vbc->add_child(l); xform_type = memnew(OptionButton); - xform_type->set_anchor(MARGIN_RIGHT, ANCHOR_END); - xform_type->set_begin(Point2(15, 142)); - xform_type->set_end(Point2(15, 75)); + xform_type->set_h_size_flags(SIZE_EXPAND_FILL); xform_type->add_item(TTR("Pre")); xform_type->add_item(TTR("Post")); - xform_dialog->add_child(xform_type); + xform_vbc->add_child(xform_type); xform_dialog->connect("confirmed", this, "_xform_dialog_action"); diff --git a/editor/plugins/texture_editor_plugin.cpp b/editor/plugins/texture_editor_plugin.cpp index 125d906460..57c27a8a7e 100644 --- a/editor/plugins/texture_editor_plugin.cpp +++ b/editor/plugins/texture_editor_plugin.cpp @@ -102,14 +102,24 @@ void TextureEditor::_notification(int p_what) { } } +void TextureEditor::_changed_callback(Object *p_changed, const char *p_prop) { + + if (!is_visible()) + return; + update(); +} + void TextureEditor::edit(Ref<Texture> p_texture) { + if (!texture.is_null()) + texture->remove_change_receptor(this); + texture = p_texture; - if (!texture.is_null()) + if (!texture.is_null()) { + texture->add_change_receptor(this); update(); - else { - + } else { hide(); } } diff --git a/editor/plugins/texture_editor_plugin.h b/editor/plugins/texture_editor_plugin.h index 9382983538..13f8dd7fbd 100644 --- a/editor/plugins/texture_editor_plugin.h +++ b/editor/plugins/texture_editor_plugin.h @@ -43,6 +43,7 @@ class TextureEditor : public Control { protected: void _notification(int p_what); void _gui_input(Ref<InputEvent> p_event); + void _changed_callback(Object *p_changed, const char *p_prop); static void _bind_methods(); public: diff --git a/editor/plugins/texture_region_editor_plugin.cpp b/editor/plugins/texture_region_editor_plugin.cpp index 8a7dcea393..4cd18b090a 100644 --- a/editor/plugins/texture_region_editor_plugin.cpp +++ b/editor/plugins/texture_region_editor_plugin.cpp @@ -617,38 +617,24 @@ void TextureRegionEditor::_bind_methods() { } void TextureRegionEditor::edit(Object *p_obj) { - if (node_sprite && node_sprite->is_connected("texture_changed", this, "_edit_region")) - node_sprite->disconnect("texture_changed", this, "_edit_region"); - if (node_patch9 && node_patch9->is_connected("texture_changed", this, "_edit_region")) - node_patch9->disconnect("texture_changed", this, "_edit_region"); - if (obj_styleBox.is_valid() && obj_styleBox->is_connected("texture_changed", this, "_edit_region")) - obj_styleBox->disconnect("texture_changed", this, "_edit_region"); - if (atlas_tex.is_valid() && atlas_tex->is_connected("atlas_changed", this, "_edit_region")) - atlas_tex->disconnect("atlas_changed", this, "_edit_region"); + if (node_sprite) + node_sprite->remove_change_receptor(this); + if (node_patch9) + node_patch9->remove_change_receptor(this); + if (obj_styleBox.is_valid()) + obj_styleBox->remove_change_receptor(this); + if (atlas_tex.is_valid()) + atlas_tex->remove_change_receptor(this); if (p_obj) { node_sprite = p_obj->cast_to<Sprite>(); node_patch9 = p_obj->cast_to<NinePatchRect>(); if (p_obj->cast_to<StyleBoxTexture>()) obj_styleBox = Ref<StyleBoxTexture>(p_obj->cast_to<StyleBoxTexture>()); - if (p_obj->cast_to<AtlasTexture>()) { + if (p_obj->cast_to<AtlasTexture>()) atlas_tex = Ref<AtlasTexture>(p_obj->cast_to<AtlasTexture>()); - atlas_tex->connect("atlas_changed", this, "_edit_region"); - } else { - p_obj->connect("texture_changed", this, "_edit_region"); - } p_obj->add_change_receptor(this); - p_obj->connect("tree_exited", this, "_node_removed", varray(p_obj), CONNECT_ONESHOT); _edit_region(); } else { - if (node_sprite) - node_sprite->disconnect("tree_exited", this, "_node_removed"); - else if (node_patch9) - node_patch9->disconnect("tree_exited", this, "_node_removed"); - else if (obj_styleBox.is_valid()) - obj_styleBox->disconnect("tree_exited", this, "_node_removed"); - else if (atlas_tex.is_valid()) - atlas_tex->disconnect("tree_exited", this, "_node_removed"); - node_sprite = NULL; node_patch9 = NULL; obj_styleBox = Ref<StyleBoxTexture>(NULL); @@ -658,9 +644,11 @@ void TextureRegionEditor::edit(Object *p_obj) { } void TextureRegionEditor::_changed_callback(Object *p_changed, const char *p_prop) { - if ((String)p_prop == "region_rect") { + + if (!is_visible()) + return; + if (p_prop == StringName("atlas") || p_prop == StringName("texture")) _edit_region(); - } } void TextureRegionEditor::_edit_region() { diff --git a/editor/project_manager.cpp b/editor/project_manager.cpp index 82f17b80d5..87340b1fe8 100644 --- a/editor/project_manager.cpp +++ b/editor/project_manager.cpp @@ -935,10 +935,10 @@ void ProjectManager::_open_project_confirm() { List<String> args; - args.push_back("-path"); + args.push_back("--path"); args.push_back(path); - args.push_back("-editor"); + args.push_back("--editor"); String exec = OS::get_singleton()->get_executable_path(); @@ -977,7 +977,7 @@ void ProjectManager::_run_project_confirm() { List<String> args; - args.push_back("-path"); + args.push_back("--path"); args.push_back(path); String exec = OS::get_singleton()->get_executable_path(); diff --git a/editor/project_settings_editor.cpp b/editor/project_settings_editor.cpp index 6d23e874df..6238cad14d 100644 --- a/editor/project_settings_editor.cpp +++ b/editor/project_settings_editor.cpp @@ -140,7 +140,7 @@ void ProjectSettingsEditor::_action_edited() { add_at = "input/" + old_name; message->set_text(TTR("Invalid action (anything goes but '/' or ':').")); - message->popup_centered(Size2(300, 100)); + message->popup_centered(Size2(300, 100) * EDSCALE); return; } @@ -152,7 +152,7 @@ void ProjectSettingsEditor::_action_edited() { add_at = "input/" + old_name; message->set_text(vformat(TTR("Action '%s' already exists!"), new_name)); - message->popup_centered(Size2(300, 100)); + message->popup_centered(Size2(300, 100) * EDSCALE); return; } @@ -399,7 +399,7 @@ void ProjectSettingsEditor::_add_item(int p_item, Ref<InputEvent> p_exiting_even device_index->add_item(TTR("Button 7")); device_index->add_item(TTR("Button 8")); device_index->add_item(TTR("Button 9")); - device_input->popup_centered_minsize(Size2(350, 95)); + device_input->popup_centered_minsize(Size2(350, 95) * EDSCALE); Ref<InputEventMouseButton> mb = p_exiting_event; if (mb.is_valid()) { @@ -420,7 +420,7 @@ void ProjectSettingsEditor::_add_item(int p_item, Ref<InputEvent> p_exiting_even String desc = _axis_names[i]; device_index->add_item(TTR("Axis") + " " + itos(i / 2) + " " + (i & 1 ? "+" : "-") + desc); } - device_input->popup_centered_minsize(Size2(350, 95)); + device_input->popup_centered_minsize(Size2(350, 95) * EDSCALE); Ref<InputEventJoypadMotion> jm = p_exiting_event; if (jm.is_valid()) { @@ -441,7 +441,7 @@ void ProjectSettingsEditor::_add_item(int p_item, Ref<InputEvent> p_exiting_even device_index->add_item(itos(i) + ": " + String(_button_names[i])); } - device_input->popup_centered_minsize(Size2(350, 95)); + device_input->popup_centered_minsize(Size2(350, 95) * EDSCALE); Ref<InputEventJoypadButton> jb = p_exiting_event; if (jb.is_valid()) { @@ -835,13 +835,13 @@ void ProjectSettingsEditor::_action_add() { String action = action_name->get_text(); if (action.find("/") != -1 || action.find(":") != -1 || action == "") { message->set_text(TTR("Invalid action (anything goes but '/' or ':').")); - message->popup_centered(Size2(300, 100)); + message->popup_centered(Size2(300, 100) * EDSCALE); return; } if (ProjectSettings::get_singleton()->has("input/" + action)) { message->set_text(vformat(TTR("Action '%s' already exists!"), action)); - message->popup_centered(Size2(300, 100)); + message->popup_centered(Size2(300, 100) * EDSCALE); return; } @@ -879,7 +879,7 @@ void ProjectSettingsEditor::_save() { Error err = ProjectSettings::get_singleton()->save(); message->set_text(err != OK ? TTR("Error saving settings.") : TTR("Settings saved OK.")); - message->popup_centered(Size2(300, 100)); + message->popup_centered(Size2(300, 100) * EDSCALE); } void ProjectSettingsEditor::_settings_prop_edited(const String &p_name) { @@ -1554,7 +1554,7 @@ ProjectSettingsEditor::ProjectSettingsEditor(EditorData *p_data) { add = memnew(Button); hbc->add_child(add); - add->set_custom_minimum_size(Size2(150, 0)); + add->set_custom_minimum_size(Size2(150, 0) * EDSCALE); add->set_text(TTR("Add")); add->connect("pressed", this, "_action_add"); diff --git a/editor/script_create_dialog.cpp b/editor/script_create_dialog.cpp index d81161ae94..0748c43b5f 100644 --- a/editor/script_create_dialog.cpp +++ b/editor/script_create_dialog.cpp @@ -29,6 +29,7 @@ /*************************************************************************/ #include "script_create_dialog.h" +#include "editor/editor_node.h" #include "editor/editor_scale.h" #include "editor_file_system.h" #include "io/resource_saver.h" @@ -229,7 +230,7 @@ void ScriptCreateDialog::_lang_changed(int l) { List<String> extensions; // get all possible extensions for script for (int l = 0; l < language_menu->get_item_count(); l++) { - language->get_recognized_extensions(&extensions); + ScriptServer::get_language(l)->get_recognized_extensions(&extensions); } for (List<String>::Element *E = extensions.front(); E; E = E->next()) { @@ -240,8 +241,11 @@ void ScriptCreateDialog::_lang_changed(int l) { } } } - file_path->set_text(path); + } else { + path = "class" + selected_ext; + _path_changed(path); } + file_path->set_text(path); bool use_templates = language->is_using_templates(); template_menu->set_disabled(!use_templates); @@ -403,9 +407,9 @@ void ScriptCreateDialog::_msg_script_valid(bool valid, const String &p_msg) { error_label->set_text(TTR(p_msg)); if (valid) { - error_label->add_color_override("font_color", Color(0, 1.0, 0.8, 0.8)); + error_label->add_color_override("font_color", get_color("success_color", "Editor")); } else { - error_label->add_color_override("font_color", Color(1, 0.2, 0.2, 0.8)); + error_label->add_color_override("font_color", get_color("error_color", "Editor")); } } @@ -413,9 +417,9 @@ void ScriptCreateDialog::_msg_path_valid(bool valid, const String &p_msg) { path_error_label->set_text(TTR(p_msg)); if (valid) { - path_error_label->add_color_override("font_color", Color(0, 1.0, 0.8, 0.8)); + path_error_label->add_color_override("font_color", get_color("success_color", "Editor")); } else { - path_error_label->add_color_override("font_color", Color(1, 0.4, 0.0, 0.8)); + path_error_label->add_color_override("font_color", get_color("error_color", "Editor")); } } @@ -543,19 +547,6 @@ ScriptCreateDialog::ScriptCreateDialog() { gc = memnew(GridContainer); gc->set_columns(2); - /* Error Stylebox Background */ - - StyleBoxFlat *sb = memnew(StyleBoxFlat); - sb->set_bg_color(Color(0, 0, 0, 0.05)); - sb->set_light_color(Color(1, 1, 1, 0.05)); - sb->set_dark_color(Color(1, 1, 1, 0.05)); - sb->set_border_blend(false); - sb->set_border_size(1); - sb->set_default_margin(MARGIN_TOP, 10.0 * EDSCALE); - sb->set_default_margin(MARGIN_BOTTOM, 10.0 * EDSCALE); - sb->set_default_margin(MARGIN_LEFT, 10.0 * EDSCALE); - sb->set_default_margin(MARGIN_RIGHT, 10.0 * EDSCALE); - /* Error Messages Field */ vb = memnew(VBoxContainer); @@ -582,7 +573,7 @@ ScriptCreateDialog::ScriptCreateDialog() { pc = memnew(PanelContainer); pc->set_h_size_flags(Control::SIZE_FILL); - pc->add_style_override("panel", sb); + pc->add_style_override("panel", EditorNode::get_singleton()->get_gui_base()->get_stylebox("bg", "Tree")); pc->add_child(vb); /* Margins */ diff --git a/main/main.cpp b/main/main.cpp index 8960d85c45..c2058ee8d4 100644 --- a/main/main.cpp +++ b/main/main.cpp @@ -127,62 +127,62 @@ static String unescape_cmdline(const String &p_str) { void Main::print_help(const char *p_binary) { OS::get_singleton()->print(VERSION_FULL_NAME " (c) 2008-2017 Juan Linietsky, Ariel Manzur.\n"); - OS::get_singleton()->print("Usage: %s [options] [scene]\n", p_binary); + OS::get_singleton()->print("Usage: %s [options] [path to scene or 'project.godot' file]\n", p_binary); OS::get_singleton()->print("Options:\n"); - OS::get_singleton()->print("\t-path [dir] : Path to a game, containing project.godot\n"); + OS::get_singleton()->print(" -h, --help Display this help message.\n"); + OS::get_singleton()->print(" --path <directory> Path to the project (<directory> must contain a 'project.godot' file).\n"); #ifdef TOOLS_ENABLED - OS::get_singleton()->print("\t-e,-editor : Bring up the editor instead of running the scene.\n"); + OS::get_singleton()->print(" -e, --editor Bring up the editor instead of running the scene.\n"); #endif - OS::get_singleton()->print("\t-test [test] : Run a test.\n"); - OS::get_singleton()->print("\t\t("); + OS::get_singleton()->print(" --test <test> Run a test ("); const char **test_names = tests_get_names(); const char *coma = ""; while (*test_names) { - OS::get_singleton()->print("%s%s", coma, *test_names); + OS::get_singleton()->print("%s'%s'", coma, *test_names); test_names++; coma = ", "; } - OS::get_singleton()->print(")\n"); - - OS::get_singleton()->print("\t-r WIDTHxHEIGHT\t : Request Window Resolution\n"); - OS::get_singleton()->print("\t-p XxY\t : Request Window Position\n"); - OS::get_singleton()->print("\t-f\t\t : Request Fullscreen\n"); - OS::get_singleton()->print("\t-mx\t\t Request Maximized\n"); - OS::get_singleton()->print("\t-w\t\t Request Windowed\n"); - OS::get_singleton()->print("\t-vd DRIVER\t : Video Driver ("); + OS::get_singleton()->print(").\n"); + + OS::get_singleton()->print(" -r, --resolution <W>x<H> Request window resolution.\n"); + OS::get_singleton()->print(" -p, --position <X>,<Y> Request window position.\n"); + OS::get_singleton()->print(" -f, --fullscreen Request fullscreen mode.\n"); + OS::get_singleton()->print(" -m, --maximized Request a maximized window.\n"); + OS::get_singleton()->print(" -w, --windowed Request windowed mode.\n"); + OS::get_singleton()->print(" --video-driver <driver> Video driver ("); for (int i = 0; i < OS::get_singleton()->get_video_driver_count(); i++) { if (i != 0) OS::get_singleton()->print(", "); - OS::get_singleton()->print("%s", OS::get_singleton()->get_video_driver_name(i)); + OS::get_singleton()->print("'%s'", OS::get_singleton()->get_video_driver_name(i)); } - OS::get_singleton()->print(")\n"); - OS::get_singleton()->print("\t-ldpi\t : Force low-dpi mode (OSX Only)\n"); + OS::get_singleton()->print(").\n"); + OS::get_singleton()->print(" --low-dpi Force low-DPI mode (macOS only).\n"); - OS::get_singleton()->print("\t-ad DRIVER\t : Audio Driver ("); + OS::get_singleton()->print(" --audio-driver <driver> Audio driver ("); for (int i = 0; i < OS::get_singleton()->get_audio_driver_count(); i++) { if (i != 0) OS::get_singleton()->print(", "); - OS::get_singleton()->print("%s", OS::get_singleton()->get_audio_driver_name(i)); + OS::get_singleton()->print("'%s'", OS::get_singleton()->get_audio_driver_name(i)); } - OS::get_singleton()->print(")\n"); - OS::get_singleton()->print("\t-rthread <mode>\t : Render Thread Mode ('unsafe', 'safe', 'separate').\n"); - OS::get_singleton()->print("\t-s,-script [script] : Run a script.\n"); - OS::get_singleton()->print("\t-d,-debug : Debug (local stdout debugger).\n"); - OS::get_singleton()->print("\t-rdebug ADDRESS : Remote debug (<ip>:<port> host address).\n"); - OS::get_singleton()->print("\t-fdelay [msec]: Simulate high CPU load (delay each frame by [msec]).\n"); - OS::get_singleton()->print("\t-timescale [msec]: Simulate high CPU load (delay each frame by [msec]).\n"); - OS::get_singleton()->print("\t-bp : breakpoint list as source::line comma separated pairs, no spaces (%%20,%%2C,etc instead).\n"); - OS::get_singleton()->print("\t-v : Verbose stdout mode\n"); - OS::get_singleton()->print("\t-lang [locale]: Use a specific locale\n"); - OS::get_singleton()->print("\t-rfs <host/ip>[:<port>] : Remote FileSystem.\n"); - OS::get_singleton()->print("\t-rfs_pass <password> : Password for Remote FileSystem.\n"); + OS::get_singleton()->print(").\n"); + OS::get_singleton()->print(" --render-thread <mode> Render thread mode ('unsafe', 'safe', 'separate').\n"); + OS::get_singleton()->print(" -s, --script <script> Run a script.\n"); + OS::get_singleton()->print(" -d, --debug Debug (local stdout debugger).\n"); + OS::get_singleton()->print(" -r, --remote-debug <address> Remote debug (<ip>:<port> host address).\n"); + OS::get_singleton()->print(" --frame-delay <ms> Simulate high CPU load (delay each frame by <ms> milliseconds).\n"); + OS::get_singleton()->print(" --time-scale <scale> Force time scale (higher values are faster, 1.0 is normal speed).\n"); + OS::get_singleton()->print(" -b, --breakpoints Breakpoint list as source::line comma-separated pairs, no spaces (use %%20, %%2C, ... instead).\n"); + OS::get_singleton()->print(" -v, --verbose Use verbose stdout mode.\n"); + OS::get_singleton()->print(" -l, --language <locale> Use a specific locale (<locale> being a two-letter code).\n"); + OS::get_singleton()->print(" --remote-fs <host/IP>[:<port>] Remote filesystem.\n"); + OS::get_singleton()->print(" --remote-fs-password <password> Password for remote filesystem.\n"); #ifdef TOOLS_ENABLED - OS::get_singleton()->print("\t-doctool FILE: Dump the whole engine api to FILE in XML format. If FILE exists, it will be merged.\n"); - OS::get_singleton()->print("\t-nodocbase: Disallow dump the base types (used with -doctool).\n"); - OS::get_singleton()->print("\t-export [target] Export the project using given export target.\n"); + OS::get_singleton()->print(" --doctool <file> Dump the whole engine API to <file> in XML format. If <file> exists, it will be merged.\n"); + OS::get_singleton()->print(" --no-docbase Disallow dumping the base types (used with --doctool).\n"); + OS::get_singleton()->print(" --export <target> Export the project using the given export target.\n"); #endif } @@ -281,14 +281,14 @@ Error Main::setup(const char *execpath, int argc, char *argv[], bool p_second_ph List<String>::Element *N = I->next(); - if (I->get() == "-noop") { + if (I->get() == "--noop") { // no op - } else if (I->get() == "-h" || I->get() == "--help" || I->get() == "/?") { // resolution + } else if (I->get() == "-h" || I->get() == "--help" || I->get() == "/?") { // display help goto error; - } else if (I->get() == "-r") { // resolution + } else if (I->get() == "-r" || I->get() == "--resolution") { // force resolution if (I->next()) { @@ -296,7 +296,7 @@ Error Main::setup(const char *execpath, int argc, char *argv[], bool p_second_ph if (vm.find("x") == -1) { // invalid parameter format - OS::get_singleton()->print("Invalid -r argument: %s\n", vm.utf8().get_data()); + OS::get_singleton()->print("Invalid resolution argument: %s\n", vm.utf8().get_data()); goto error; } @@ -305,7 +305,7 @@ Error Main::setup(const char *execpath, int argc, char *argv[], bool p_second_ph if (w == 0 || h == 0) { - OS::get_singleton()->print("Invalid -r resolution, x and y must be >0\n"); + OS::get_singleton()->print("Invalid resolution, width and height must be above 0\n"); goto error; } @@ -315,66 +315,66 @@ Error Main::setup(const char *execpath, int argc, char *argv[], bool p_second_ph N = I->next()->next(); } else { - OS::get_singleton()->print("Invalid -p argument, needs resolution\n"); + OS::get_singleton()->print("Invalid resolution argument, needs resolution\n"); goto error; } - } else if (I->get() == "-p") { // position + } else if (I->get() == "-p" || I->get() == "--position") { // position if (I->next()) { String vm = I->next()->get(); - if (vm.find("x") == -1) { // invalid parameter format + if (vm.find(",") == -1) { // invalid parameter format - OS::get_singleton()->print("Invalid -p argument: %s\n", vm.utf8().get_data()); + OS::get_singleton()->print("Invalid position argument: %s\n", vm.utf8().get_data()); goto error; } - int x = vm.get_slice("x", 0).to_int(); - int y = vm.get_slice("x", 1).to_int(); + int x = vm.get_slice(",", 0).to_int(); + int y = vm.get_slice(",", 1).to_int(); init_custom_pos = Point2(x, y); init_use_custom_pos = true; N = I->next()->next(); } else { - OS::get_singleton()->print("Invalid -r argument, needs position\n"); + OS::get_singleton()->print("Invalid position argument, needs position\n"); goto error; } - } else if (I->get() == "-mx") { // video driver + } else if (I->get() == "-m" || I->get() == "--maximized") { // force maximized window init_maximized = true; - } else if (I->get() == "-w") { // video driver + } else if (I->get() == "-w" || I->get() == "--windowed") { // force windowed window init_windowed = true; - } else if (I->get() == "-profile") { // video driver + } else if (I->get() == "--profile") { // enable profiler use_debug_profiler = true; - } else if (I->get() == "-vd") { // video driver + } else if (I->get() == "--video-driver") { // force video driver if (I->next()) { video_driver = I->next()->get(); N = I->next()->next(); } else { - OS::get_singleton()->print("Invalid -cd argument, needs driver name\n"); + OS::get_singleton()->print("Invalid --video-driver argument, needs driver name\n"); goto error; } - } else if (I->get() == "-lang") { // language + } else if (I->get() == "-l" || I->get() == "--language") { // language if (I->next()) { locale = I->next()->get(); N = I->next()->next(); } else { - OS::get_singleton()->print("Invalid -lang argument, needs language code\n"); + OS::get_singleton()->print("Invalid language argument, needs language code\n"); goto error; } - } else if (I->get() == "-ldpi") { // language + } else if (I->get() == "--low-dpi") { // force low DPI force_lowdpi = true; - } else if (I->get() == "-rfs") { // language + } else if (I->get() == "--remote-fs") { // remote filesystem if (I->next()) { @@ -383,7 +383,7 @@ Error Main::setup(const char *execpath, int argc, char *argv[], bool p_second_ph } else { goto error; } - } else if (I->get() == "-rfs_pass") { // language + } else if (I->get() == "--remote-fs-password") { // remote filesystem password if (I->next()) { @@ -392,7 +392,7 @@ Error Main::setup(const char *execpath, int argc, char *argv[], bool p_second_ph } else { goto error; } - } else if (I->get() == "-rthread") { // language + } else if (I->get() == "--render-thread") { // rendering thread if (I->next()) { @@ -408,7 +408,7 @@ Error Main::setup(const char *execpath, int argc, char *argv[], bool p_second_ph goto error; } - } else if (I->get() == "-ad") { // video driver + } else if (I->get() == "--audio-driver") { // audio driver if (I->next()) { @@ -418,22 +418,22 @@ Error Main::setup(const char *execpath, int argc, char *argv[], bool p_second_ph goto error; } - } else if (I->get() == "-f") { // fullscreen + } else if (I->get() == "-f" || I->get() == "--fullscreen") { // force fullscreen //video_mode.fullscreen=false; init_fullscreen = true; - } else if (I->get() == "-e" || I->get() == "-editor") { // fonud editor + } else if (I->get() == "-e" || I->get() == "--editor") { // starts editor editor = true; - } else if (I->get() == "-nowindow") { // fullscreen + } else if (I->get() == "--no-window") { // disable window creation OS::get_singleton()->set_no_window_mode(true); - } else if (I->get() == "-quiet") { // fullscreen + } else if (I->get() == "--quiet") { // quieter output quiet_stdout = true; - } else if (I->get() == "-v") { // fullscreen + } else if (I->get() == "-v" || I->get() == "--verbose") { // verbose output OS::get_singleton()->_verbose_stdout = true; - } else if (I->get() == "-path") { // resolution + } else if (I->get() == "--path") { // set path of project to start or edit if (I->next()) { @@ -464,7 +464,7 @@ Error Main::setup(const char *execpath, int argc, char *argv[], bool p_second_ph #ifdef TOOLS_ENABLED editor = true; #endif - } else if (I->get() == "-bp") { // /breakpoints + } else if (I->get() == "-b" || I->get() == "--breakpoints") { // add breakpoints if (I->next()) { @@ -475,7 +475,7 @@ Error Main::setup(const char *execpath, int argc, char *argv[], bool p_second_ph goto error; } - } else if (I->get() == "-fdelay") { // resolution + } else if (I->get() == "--frame-delay") { // force frame delay if (I->next()) { @@ -485,7 +485,7 @@ Error Main::setup(const char *execpath, int argc, char *argv[], bool p_second_ph goto error; } - } else if (I->get() == "-timescale") { // resolution + } else if (I->get() == "--time-scale") { // force time scale if (I->next()) { @@ -495,7 +495,7 @@ Error Main::setup(const char *execpath, int argc, char *argv[], bool p_second_ph goto error; } - } else if (I->get() == "-pack") { + } else if (I->get() == "--pack") { if (I->next()) { @@ -506,7 +506,7 @@ Error Main::setup(const char *execpath, int argc, char *argv[], bool p_second_ph goto error; }; - } else if (I->get() == "-main_pack") { + } else if (I->get() == "--main-pack") { if (I->next()) { @@ -517,15 +517,15 @@ Error Main::setup(const char *execpath, int argc, char *argv[], bool p_second_ph goto error; }; - } else if (I->get() == "-debug" || I->get() == "-d") { + } else if (I->get() == "--debug" || I->get() == "-d") { debug_mode = "local"; #ifdef DEBUG_ENABLED - } else if (I->get() == "-debugcol" || I->get() == "-dc") { + } else if (I->get() == "--debug-collision") { debug_collisions = true; - } else if (I->get() == "-debugnav" || I->get() == "-dn") { + } else if (I->get() == "--debug-navigation") { debug_navigation = true; #endif - } else if (I->get() == "-editor_scene") { + } else if (I->get() == "--editor-scene") { if (I->next()) { @@ -534,7 +534,7 @@ Error Main::setup(const char *execpath, int argc, char *argv[], bool p_second_ph goto error; } - } else if (I->get() == "-rdebug") { + } else if (I->get() == "-r" || I->get() == "--remote-debug") { if (I->next()) { debug_mode = "remote"; @@ -547,7 +547,7 @@ Error Main::setup(const char *execpath, int argc, char *argv[], bool p_second_ph } else { goto error; } - } else if (I->get() == "-epid") { + } else if (I->get() == "--editor-pid") { if (I->next()) { int editor_pid = I->next()->get().to_int(); @@ -660,7 +660,7 @@ Error Main::setup(const char *execpath, int argc, char *argv[], bool p_second_ph } if (editor) { - main_args.push_back("-editor"); + main_args.push_back("--editor"); init_maximized = true; use_custom_res = false; } @@ -1057,13 +1057,13 @@ bool Main::start() { List<String> args = OS::get_singleton()->get_cmdline_args(); for (int i = 0; i < args.size(); i++) { //parameters that do not have an argument to the right - if (args[i] == "-nodocbase") { + if (args[i] == "--no-docbase") { doc_base = false; - } else if (args[i] == "-noquit") { + } else if (args[i] == "--no-quit") { noquit = true; - } else if (args[i] == "-editor" || args[i] == "-e") { + } else if (args[i] == "--editor" || args[i] == "-e") { editor = true; - } else if (args[i] == "-pm" || args[i] == "-project_manager") { + } else if (args[i] == "-P" || args[i] == "--project-manager") { project_manager_request = true; } else if (args[i].length() && args[i][0] != '-' && game_path == "") { game_path = args[i]; @@ -1071,27 +1071,27 @@ bool Main::start() { //parameters that have an argument to the right else if (i < (args.size() - 1)) { bool parsed_pair = true; - if (args[i] == "-doctool") { + if (args[i] == "--doctool") { doc_tool = args[i + 1]; for (int j = i + 2; j < args.size(); j++) removal_docs.push_back(args[j]); - } else if (args[i] == "-script" || args[i] == "-s") { + } else if (args[i] == "--script" || args[i] == "-s") { script = args[i + 1]; - } else if (args[i] == "-level" || args[i] == "-l") { + } else if (args[i] == "--level" || args[i] == "-l") { Engine::get_singleton()->_custom_level = args[i + 1]; - } else if (args[i] == "-test") { + } else if (args[i] == "--test") { test = args[i + 1]; - } else if (args[i] == "-export") { + } else if (args[i] == "--export") { editor = true; //needs editor _export_platform = args[i + 1]; - } else if (args[i] == "-export_debug") { + } else if (args[i] == "--export-debug") { editor = true; //needs editor _export_platform = args[i + 1]; export_debug = true; - } else if (args[i] == "-import") { + } else if (args[i] == "--import") { editor = true; //needs editor _import = args[i + 1]; - } else if (args[i] == "-import_script") { + } else if (args[i] == "--import-script") { editor = true; //needs editor _import_script = args[i + 1]; } else { @@ -1139,7 +1139,7 @@ bool Main::start() { if (_export_platform != "") { if (game_path == "") { String err = "Command line param "; - err += export_debug ? "-export_debug" : "-export"; + err += export_debug ? "--export-debug" : "--export"; err += " passed but no destination path given.\n"; err += "Please specify the binary's file path to export to. Aborting export."; ERR_PRINT(err.utf8().get_data()); @@ -1704,6 +1704,7 @@ void Main::cleanup() { #endif if (audio_server) { + audio_server->finish(); memdelete(audio_server); } diff --git a/main/performance.cpp b/main/performance.cpp index c819e15f71..3d8e21bf33 100644 --- a/main/performance.cpp +++ b/main/performance.cpp @@ -117,8 +117,8 @@ float Performance::get_monitor(Monitor p_monitor) const { case TIME_FIXED_PROCESS: return _fixed_process_time; case MEMORY_STATIC: return Memory::get_mem_usage(); case MEMORY_DYNAMIC: return MemoryPool::total_memory; - case MEMORY_STATIC_MAX: return MemoryPool::max_memory; - case MEMORY_DYNAMIC_MAX: return 0; + case MEMORY_STATIC_MAX: return Memory::get_mem_max_usage(); + case MEMORY_DYNAMIC_MAX: return MemoryPool::max_memory; case MEMORY_MESSAGE_BUFFER_MAX: return MessageQueue::get_singleton()->get_max_buffer_usage(); case OBJECT_COUNT: return ObjectDB::get_object_count(); case OBJECT_RESOURCE_COUNT: return ResourceCache::get_cached_resource_count(); diff --git a/platform/android/SCsub b/platform/android/SCsub index 7fb3c876be..b124a1a5a8 100644 --- a/platform/android/SCsub +++ b/platform/android/SCsub @@ -141,6 +141,8 @@ if env['android_arch'] == 'armv6': lib_arch_dir = 'armeabi' elif env['android_arch'] == 'armv7': lib_arch_dir = 'armeabi-v7a' +elif env['android_arch'] == 'arm64v8': + lib_arch_dir = 'arm64-v8a' elif env['android_arch'] == 'x86': lib_arch_dir = 'x86' else: diff --git a/platform/android/detect.py b/platform/android/detect.py index fae1df3f27..ad5bfb4949 100644 --- a/platform/android/detect.py +++ b/platform/android/detect.py @@ -22,7 +22,7 @@ def get_opts(): return [ ('ANDROID_NDK_ROOT', 'Path to the Android NDK', os.environ.get("ANDROID_NDK_ROOT", 0)), ('ndk_platform', 'Target platform (android-<api>, e.g. "android-18")', "android-18"), - ('android_arch', 'Target architecture (armv7/armv6/x86)', "armv7"), + ('android_arch', 'Target architecture (armv7/armv6/arm64v8/x86)', "armv7"), ('android_neon', 'Enable NEON support (armv7 only)', "yes"), ('android_stl', 'Enable Android STL support (for modules)', "no") ] @@ -89,7 +89,7 @@ def configure(env): ## Architecture - if env['android_arch'] not in ['armv7', 'armv6', 'x86']: + if env['android_arch'] not in ['armv7', 'armv6', 'arm64v8', 'x86']: env['android_arch'] = 'armv7' neon_text = "" @@ -99,18 +99,21 @@ def configure(env): can_vectorize = True if env['android_arch'] == 'x86': + env['ARCH'] = 'arch-x86' env.extra_suffix = ".x86" + env.extra_suffix target_subpath = "x86-4.9" abi_subpath = "i686-linux-android" arch_subpath = "x86" env["x86_libtheora_opt_gcc"] = True elif env['android_arch'] == 'armv6': + env['ARCH'] = 'arch-arm' env.extra_suffix = ".armv6" + env.extra_suffix target_subpath = "arm-linux-androideabi-4.9" abi_subpath = "arm-linux-androideabi" arch_subpath = "armeabi" can_vectorize = False elif env["android_arch"] == "armv7": + env['ARCH'] = 'arch-arm' target_subpath = "arm-linux-androideabi-4.9" abi_subpath = "arm-linux-androideabi" arch_subpath = "armeabi-v7a" @@ -118,6 +121,12 @@ def configure(env): env.extra_suffix = ".armv7.neon" + env.extra_suffix else: env.extra_suffix = ".armv7" + env.extra_suffix + elif env["android_arch"] == "arm64v8": + env['ARCH'] = 'arch-arm64' + target_subpath = "aarch64-linux-android-4.9" + abi_subpath = "aarch64-linux-android" + arch_subpath = "arm64-v8a" + env.extra_suffix = ".armv8" + env.extra_suffix ## Build type @@ -149,6 +158,8 @@ def configure(env): elif (sys.platform.startswith('win')): if (platform.machine().endswith('64')): host_subpath = "windows-x86_64" + if env["android_arch"] == "arm64v8": + mt_link = False else: mt_link = False host_subpath = "windows" @@ -166,11 +177,6 @@ def configure(env): env['RANLIB'] = tools_path + "/ranlib" env['AS'] = tools_path + "/as" - if env['android_arch'] == 'x86': - env['ARCH'] = 'arch-x86' - else: - env['ARCH'] = 'arch-arm' - sysroot = env["ANDROID_NDK_ROOT"] + "/platforms/" + env['ndk_platform'] + "/" + env['ARCH'] common_opts = ['-fno-integrated-as', '-gcc-toolchain', gcc_toolchain_path] @@ -199,6 +205,11 @@ def configure(env): else: env.Append(CPPFLAGS=['-mfpu=vfpv3-d16']) + elif env["android_arch"] == "arm64v8": + target_opts = ['-target', 'aarch64-none-linux-android'] + env.Append(CPPFLAGS=['-D__ARM_ARCH_8A__']) + env.Append(CPPFLAGS=['-mfix-cortex-a53-835769']) + env.Append(CPPFLAGS=target_opts) env.Append(CPPFLAGS=common_opts) @@ -213,7 +224,8 @@ def configure(env): ## Link flags env['LINKFLAGS'] = ['-shared', '--sysroot=' + sysroot, '-Wl,--warn-shared-textrel'] - env.Append(LINKFLAGS=string.split('-Wl,--fix-cortex-a8')) + if env["android_arch"] == "armv7": + env.Append(LINKFLAGS=string.split('-Wl,--fix-cortex-a8')) env.Append(LINKFLAGS=string.split('-Wl,--no-undefined -Wl,-z,noexecstack -Wl,-z,relro -Wl,-z,now')) env.Append(LINKFLAGS=string.split('-Wl,-soname,libgodot_android.so -Wl,--gc-sections')) if mt_link: diff --git a/platform/android/export/export.cpp b/platform/android/export/export.cpp index a722cd1b8c..3c52834d92 100644 --- a/platform/android/export/export.cpp +++ b/platform/android/export/export.cpp @@ -219,6 +219,7 @@ class EditorExportPlatformAndroid : public EditorExportPlatform { bool use_32_fb; bool immersive; bool export_arm; + bool export_arm64; bool export_x86; String apk_expansion_salt; String apk_expansion_pkey; @@ -319,6 +320,8 @@ bool EditorExportPlatformAndroid::_set(const StringName& p_name, const Variant& _signed=p_value; else if (n=="architecture/arm") export_arm=p_value; + else if (n=="architecture/arm64") + export_arm64=p_value; else if (n=="architecture/x86") export_x86=p_value; else if (n=="screen/use_32_bits_view") @@ -392,6 +395,8 @@ bool EditorExportPlatformAndroid::_get(const StringName& p_name,Variant &r_ret) r_ret=_signed; else if (n=="architecture/arm") r_ret=export_arm; + else if (n=="architecture/arm64") + r_ret=export_arm64; else if (n=="architecture/x86") r_ret=export_x86; else if (n=="screen/use_32_bits_view") @@ -1164,6 +1169,10 @@ Error EditorExportPlatformAndroid::export_project(const String& p_path, bool p_d skip=true; } + if (file.match("lib/arm64*/libgodot_android.so") && !export_arm64) { + skip = true; + } + if (file.begins_with("META-INF") && _signed) { skip=true; } @@ -1801,6 +1810,7 @@ EditorExportPlatformAndroid::EditorExportPlatformAndroid() { immersive=true; export_arm=true; + export_arm64=false; export_x86=false; @@ -3176,6 +3186,7 @@ public: bool export_x86 = p_preset->get("architecture/x86"); bool export_arm = p_preset->get("architecture/arm"); + bool export_arm64 = p_preset->get("architecture/arm64"); bool use_32_fb = p_preset->get("screen/use_32_bits_view"); bool immersive = p_preset->get("screen/immersive_mode"); @@ -3267,6 +3278,10 @@ public: skip = true; } + if (file.match("lib/arm64*/libgodot_android.so") && !export_arm64) { + skip = true; + } + if (file.begins_with("META-INF") && _signed) { skip = true; } diff --git a/platform/android/java_class_wrapper.cpp b/platform/android/java_class_wrapper.cpp index 56a27fa0e0..52ff9cd562 100644 --- a/platform/android/java_class_wrapper.cpp +++ b/platform/android/java_class_wrapper.cpp @@ -190,7 +190,7 @@ bool JavaClass::_call_method(JavaObject *p_instance, const StringName &p_method, argv[i].i = *p_args[i]; } break; case ARG_TYPE_LONG: { - argv[i].j = *p_args[i]; + argv[i].j = (int64_t)*p_args[i]; } break; case ARG_TYPE_FLOAT: { argv[i].f = *p_args[i]; @@ -350,7 +350,7 @@ bool JavaClass::_call_method(JavaObject *p_instance, const StringName &p_method, Array arr = *p_args[i]; jlongArray a = env->NewLongArray(arr.size()); for (int j = 0; j < arr.size(); j++) { - jlong val = arr[j]; + jlong val = (int64_t)arr[j]; env->SetLongArrayRegion(a, j, 1, &val); } argv[i].l = a; @@ -460,9 +460,9 @@ bool JavaClass::_call_method(JavaObject *p_instance, const StringName &p_method, case ARG_TYPE_LONG: { if (method->_static) { - ret = env->CallStaticLongMethodA(_class, method->method, argv); + ret = (int64_t)env->CallStaticLongMethodA(_class, method->method, argv); } else { - ret = env->CallLongMethodA(p_instance->instance, method->method, argv); + ret = (int64_t)env->CallLongMethodA(p_instance->instance, method->method, argv); } } break; @@ -680,7 +680,7 @@ bool JavaClass::_convert_object_to_variant(JNIEnv *env, jobject obj, Variant &va } break; case ARG_TYPE_LONG | ARG_NUMBER_CLASS_BIT: { - var = env->CallLongMethod(obj, JavaClassWrapper::singleton->Long_longValue); + var = (int64_t)env->CallLongMethod(obj, JavaClassWrapper::singleton->Long_longValue); return true; } break; @@ -802,7 +802,7 @@ bool JavaClass::_convert_object_to_variant(JNIEnv *env, jobject obj, Variant &va jlong val; env->GetLongArrayRegion((jlongArray)arr, 0, 1, &val); - ret.push_back(val); + ret.push_back((int64_t)val); } var = ret; diff --git a/platform/windows/os_windows.cpp b/platform/windows/os_windows.cpp index c091c7d022..da14d5c284 100644 --- a/platform/windows/os_windows.cpp +++ b/platform/windows/os_windows.cpp @@ -805,7 +805,12 @@ void OS_Windows::process_key_events() { k->set_pressed(ke.uMsg == WM_KEYDOWN); - k->set_scancode(KeyMappingWindows::get_keysym(ke.wParam)); + if ((ke.lParam & (1 << 24)) && (ke.wParam == VK_RETURN)) { + // Special case for Numpad Enter key + k->set_scancode(KEY_ENTER); + } else { + k->set_scancode(KeyMappingWindows::get_keysym(ke.wParam)); + } if (i + 1 < key_event_pos && key_event_buffer[i + 1].uMsg == WM_CHAR) { k->set_unicode(key_event_buffer[i + 1].wParam); diff --git a/scene/2d/sprite.cpp b/scene/2d/sprite.cpp index b469013819..ad34dfd63a 100644 --- a/scene/2d/sprite.cpp +++ b/scene/2d/sprite.cpp @@ -109,6 +109,7 @@ void Sprite::set_texture(const Ref<Texture> &p_texture) { update(); emit_signal("texture_changed"); item_rect_changed(); + _change_notify("texture"); } void Sprite::set_normal_map(const Ref<Texture> &p_texture) { diff --git a/scene/gui/menu_button.cpp b/scene/gui/menu_button.cpp index fe76b16460..57aa72b7d0 100644 --- a/scene/gui/menu_button.cpp +++ b/scene/gui/menu_button.cpp @@ -55,7 +55,6 @@ void MenuButton::pressed() { popup->set_size(Size2(size.width, 0)); popup->set_parent_rect(Rect2(Point2(gp - popup->get_global_position()), get_size())); popup->popup(); - popup->call_deferred("grab_click_focus"); popup->set_invalidate_click_until_motion(); } @@ -112,6 +111,7 @@ MenuButton::MenuButton() { popup->hide(); add_child(popup); popup->set_as_toplevel(true); + connect("button_up", popup, "call_deferred", make_binds("grab_click_focus")); set_process_unhandled_key_input(true); set_action_mode(ACTION_MODE_BUTTON_PRESS); } diff --git a/scene/gui/patch_9_rect.cpp b/scene/gui/patch_9_rect.cpp index 16f2bb6b6f..e577000f99 100644 --- a/scene/gui/patch_9_rect.cpp +++ b/scene/gui/patch_9_rect.cpp @@ -99,6 +99,7 @@ void NinePatchRect::set_texture(const Ref<Texture> &p_tex) { */ minimum_size_changed(); emit_signal("texture_changed"); + _change_notify("texture"); } Ref<Texture> NinePatchRect::get_texture() const { diff --git a/scene/gui/text_edit.cpp b/scene/gui/text_edit.cpp index 8baca50d32..d604738da1 100644 --- a/scene/gui/text_edit.cpp +++ b/scene/gui/text_edit.cpp @@ -49,6 +49,10 @@ static bool _is_symbol(CharType c) { return c != '_' && ((c >= '!' && c <= '/') || (c >= ':' && c <= '@') || (c >= '[' && c <= '`') || (c >= '{' && c <= '~') || c == '\t' || c == ' '); } +static bool _is_whitespace(CharType c) { + return c == '\t' || c == ' '; +} + static bool _is_char(CharType c) { return (c >= 'a' && c <= 'z') || (c >= 'A' && c <= 'Z') || c == '_'; @@ -2096,45 +2100,43 @@ void TextEdit::_gui_input(const Ref<InputEvent> &p_gui_input) { break; #ifdef APPLE_STYLE_KEYS - if (k->get_alt()) { + if (k->get_alt() && cursor.column > 1) { #else if (k->get_alt()) { scancode_handled = false; break; - } else if (k->get_command()) { + } else if (k->get_command() && cursor.column > 1) { #endif int line = cursor.line; int column = cursor.column; - bool prev_char = false; - bool only_whitespace = true; - - while (only_whitespace && line > 0) { - - while (column > 0) { - CharType c = text[line][column - 1]; - - if (c != '\t' && c != ' ') { - only_whitespace = false; - break; - } + // check if we are removing a single whitespace, if so remove it and the next char type + // else we just remove the whitespace + bool only_whitespace = false; + if (_is_whitespace(text[line][column - 1]) && _is_whitespace(text[line][column - 2])) { + only_whitespace = true; + } else if (_is_whitespace(text[line][column - 1])) { + // remove the single whitespace + column--; + } - column--; - } + // check if its a text char + bool only_char = (_is_text_char(text[line][column - 1]) && !only_whitespace); - if (only_whitespace) { - line--; - column = text[line].length(); - } - } + // if its not whitespace or char then symbol. + bool only_symbols = !(only_whitespace || only_char); while (column > 0) { - bool ischar = _is_text_char(text[line][column - 1]); + bool is_whitespace = _is_whitespace(text[line][column - 1]); + bool is_text_char = _is_text_char(text[line][column - 1]); - if (prev_char && !ischar) + if (only_whitespace && !is_whitespace) { break; - - prev_char = ischar; + } else if (only_char && !is_text_char) { + break; + } else if (only_symbols && (is_whitespace || is_text_char)) { + break; + } column--; } @@ -2356,52 +2358,50 @@ void TextEdit::_gui_input(const Ref<InputEvent> &p_gui_input) { int next_column; #ifdef APPLE_STYLE_KEYS - if (k->get_alt()) { + if (k->get_alt() && cursor.column < curline_len - 1) { #else if (k->get_alt()) { scancode_handled = false; break; - } else if (k->get_command()) { + } else if (k->get_command() && cursor.column < curline_len - 1) { #endif - int last_line = text.size() - 1; int line = cursor.line; int column = cursor.column; - bool prev_char = false; - bool only_whitespace = true; - - while (only_whitespace && line < last_line) { - - while (column < text[line].length()) { - CharType c = text[line][column]; - - if (c != '\t' && c != ' ') { - only_whitespace = false; - break; - } - - column++; - } - - if (only_whitespace) { - line++; - column = 0; - } + // check if we are removing a single whitespace, if so remove it and the next char type + // else we just remove the whitespace + bool only_whitespace = false; + if (_is_whitespace(text[line][column]) && _is_whitespace(text[line][column + 1])) { + only_whitespace = true; + } else if (_is_whitespace(text[line][column])) { + // remove the single whitespace + column++; } - while (column < text[line].length()) { + // check if its a text char + bool only_char = (_is_text_char(text[line][column]) && !only_whitespace); - bool ischar = _is_text_char(text[line][column]); + // if its not whitespace or char then symbol. + bool only_symbols = !(only_whitespace || only_char); - if (prev_char && !ischar) + while (column < curline_len) { + bool is_whitespace = _is_whitespace(text[line][column]); + bool is_text_char = _is_text_char(text[line][column]); + + if (only_whitespace && !is_whitespace) { break; - prev_char = ischar; + } else if (only_char && !is_text_char) { + break; + } else if (only_symbols && (is_whitespace || is_text_char)) { + break; + } column++; } next_line = line; next_column = column; + } else { next_column = cursor.column < curline_len ? (cursor.column + 1) : 0; } diff --git a/scene/gui/tree.cpp b/scene/gui/tree.cpp index 1456ab51c0..0b57841be7 100644 --- a/scene/gui/tree.cpp +++ b/scene/gui/tree.cpp @@ -1605,7 +1605,6 @@ int Tree::propagate_mouse_event(const Point2i &p_pos, int x_ofs, int y_ofs, bool int plus = 1; while (i + plus < columns.size() && !p_item->cells[i + plus].editable && p_item->cells[i + plus].mode == TreeItem::CELL_MODE_STRING && p_item->cells[i + plus].text == "" && p_item->cells[i + plus].icon.is_null()) { - plus++; col_width += cache.hseparation; col_width += get_column_width(i + plus); plus++; diff --git a/scene/resources/style_box.cpp b/scene/resources/style_box.cpp index e0a9de6062..3666c18487 100644 --- a/scene/resources/style_box.cpp +++ b/scene/resources/style_box.cpp @@ -107,6 +107,7 @@ void StyleBoxTexture::set_texture(RES p_texture) { region_rect = Rect2(Point2(), texture->get_size()); emit_signal("texture_changed"); emit_changed(); + _change_notify("texture"); } RES StyleBoxTexture::get_texture() const { diff --git a/scene/resources/surface_tool.cpp b/scene/resources/surface_tool.cpp index 8b747e1b43..8478432a04 100644 --- a/scene/resources/surface_tool.cpp +++ b/scene/resources/surface_tool.cpp @@ -818,6 +818,7 @@ void SurfaceTool::clear() { void SurfaceTool::_bind_methods() { ClassDB::bind_method(D_METHOD("begin", "primitive"), &SurfaceTool::begin); + ClassDB::bind_method(D_METHOD("add_vertex", "vertex"), &SurfaceTool::add_vertex); ClassDB::bind_method(D_METHOD("add_color", "color"), &SurfaceTool::add_color); ClassDB::bind_method(D_METHOD("add_normal", "normal"), &SurfaceTool::add_normal); @@ -827,15 +828,25 @@ void SurfaceTool::_bind_methods() { ClassDB::bind_method(D_METHOD("add_bones", "bones"), &SurfaceTool::add_bones); ClassDB::bind_method(D_METHOD("add_weights", "weights"), &SurfaceTool::add_weights); ClassDB::bind_method(D_METHOD("add_smooth_group", "smooth"), &SurfaceTool::add_smooth_group); + ClassDB::bind_method(D_METHOD("add_triangle_fan", "vertexes", "uvs", "colors", "uv2s", "normals", "tangents"), &SurfaceTool::add_triangle_fan, DEFVAL(Vector<Vector2>()), DEFVAL(Vector<Color>()), DEFVAL(Vector<Vector2>()), DEFVAL(Vector<Vector3>()), DEFVAL(Vector<Plane>())); - ClassDB::bind_method(D_METHOD("set_material", "material:Material"), &SurfaceTool::set_material); + + ClassDB::bind_method(D_METHOD("add_index", "index"), &SurfaceTool::add_index); + ClassDB::bind_method(D_METHOD("index"), &SurfaceTool::index); ClassDB::bind_method(D_METHOD("deindex"), &SurfaceTool::deindex); - ///ClassDB::bind_method(D_METHOD("generate_flat_normals"),&SurfaceTool::generate_flat_normals); ClassDB::bind_method(D_METHOD("generate_normals"), &SurfaceTool::generate_normals); - ClassDB::bind_method(D_METHOD("add_index", "index"), &SurfaceTool::add_index); - ClassDB::bind_method(D_METHOD("commit:Mesh", "existing:Mesh"), &SurfaceTool::commit, DEFVAL(Variant())); + ClassDB::bind_method(D_METHOD("generate_tangents"), &SurfaceTool::generate_tangents); + + ClassDB::bind_method(D_METHOD("add_to_format", "flags"), &SurfaceTool::add_to_format); + + ClassDB::bind_method(D_METHOD("set_material", "material:Material"), &SurfaceTool::set_material); + ClassDB::bind_method(D_METHOD("clear"), &SurfaceTool::clear); + + ClassDB::bind_method(D_METHOD("create_from", "existing:Mesh", "surface"), &SurfaceTool::create_from); + ClassDB::bind_method(D_METHOD("append_from", "existing:Mesh", "surface", "transform"), &SurfaceTool::append_from); + ClassDB::bind_method(D_METHOD("commit:Mesh", "existing:Mesh"), &SurfaceTool::commit, DEFVAL(Variant())); } SurfaceTool::SurfaceTool() { diff --git a/scene/resources/texture.cpp b/scene/resources/texture.cpp index 5cd75b5a69..fe7cd0097c 100644 --- a/scene/resources/texture.cpp +++ b/scene/resources/texture.cpp @@ -830,7 +830,7 @@ void AtlasTexture::set_atlas(const Ref<Texture> &p_atlas) { return; atlas = p_atlas; emit_changed(); - emit_signal("atlas_changed"); + _change_notify("atlas"); } Ref<Texture> AtlasTexture::get_atlas() const { @@ -839,8 +839,11 @@ Ref<Texture> AtlasTexture::get_atlas() const { void AtlasTexture::set_region(const Rect2 &p_region) { + if (region == p_region) + return; region = p_region; emit_changed(); + _change_notify("region"); } Rect2 AtlasTexture::get_region() const { @@ -850,8 +853,11 @@ Rect2 AtlasTexture::get_region() const { void AtlasTexture::set_margin(const Rect2 &p_margin) { + if (margin == p_margin) + return; margin = p_margin; emit_changed(); + _change_notify("margin"); } Rect2 AtlasTexture::get_margin() const { @@ -870,8 +876,6 @@ void AtlasTexture::_bind_methods() { ClassDB::bind_method(D_METHOD("set_margin", "margin"), &AtlasTexture::set_margin); ClassDB::bind_method(D_METHOD("get_margin"), &AtlasTexture::get_margin); - ADD_SIGNAL(MethodInfo("atlas_changed")); - ADD_PROPERTY(PropertyInfo(Variant::OBJECT, "atlas", PROPERTY_HINT_RESOURCE_TYPE, "Texture"), "set_atlas", "get_atlas"); ADD_PROPERTY(PropertyInfo(Variant::RECT2, "region"), "set_region", "get_region"); ADD_PROPERTY(PropertyInfo(Variant::RECT2, "margin"), "set_margin", "get_margin"); diff --git a/servers/audio_server.cpp b/servers/audio_server.cpp index 5303aea6d0..0d2550e53b 100644 --- a/servers/audio_server.cpp +++ b/servers/audio_server.cpp @@ -66,7 +66,8 @@ void AudioDriver::audio_server_process(int p_frames, int32_t *p_buffer, bool p_u void AudioDriver::update_mix_time(int p_frames) { _mix_amount += p_frames; - _last_mix_time = OS::get_singleton()->get_ticks_usec(); + if (OS::get_singleton()) + _last_mix_time = OS::get_singleton()->get_ticks_usec(); } double AudioDriver::get_mix_time() const { diff --git a/servers/physics/area_sw.h b/servers/physics/area_sw.h index 06e58e3d5a..3dae1db13f 100644 --- a/servers/physics/area_sw.h +++ b/servers/physics/area_sw.h @@ -154,6 +154,7 @@ public: _FORCE_INLINE_ void add_constraint(ConstraintSW *p_constraint) { constraints.insert(p_constraint); } _FORCE_INLINE_ void remove_constraint(ConstraintSW *p_constraint) { constraints.erase(p_constraint); } _FORCE_INLINE_ const Set<ConstraintSW *> &get_constraints() const { return constraints; } + _FORCE_INLINE_ void clear_constraints() { constraints.clear(); } void set_monitorable(bool p_monitorable); _FORCE_INLINE_ bool is_monitorable() const { return monitorable; } diff --git a/servers/physics/body_sw.cpp b/servers/physics/body_sw.cpp index 1f32c059a8..e065fae2be 100644 --- a/servers/physics/body_sw.cpp +++ b/servers/physics/body_sw.cpp @@ -757,7 +757,8 @@ BodySW::BodySW() contact_count = 0; gravity_scale = 1.0; - + linear_damp = -1; + angular_damp = -1; area_angular_damp = 0; area_linear_damp = 0; diff --git a/servers/physics/body_sw.h b/servers/physics/body_sw.h index c3e051c2d0..512b868570 100644 --- a/servers/physics/body_sw.h +++ b/servers/physics/body_sw.h @@ -194,6 +194,7 @@ public: _FORCE_INLINE_ void add_constraint(ConstraintSW *p_constraint, int p_pos) { constraint_map[p_constraint] = p_pos; } _FORCE_INLINE_ void remove_constraint(ConstraintSW *p_constraint) { constraint_map.erase(p_constraint); } const Map<ConstraintSW *, int> &get_constraint_map() const { return constraint_map; } + _FORCE_INLINE_ void clear_constraint_map() { constraint_map.clear(); } _FORCE_INLINE_ void set_omit_force_integration(bool p_omit_force_integration) { omit_force_integration = p_omit_force_integration; } _FORCE_INLINE_ bool get_omit_force_integration() const { return omit_force_integration; } diff --git a/servers/physics/physics_server_sw.cpp b/servers/physics/physics_server_sw.cpp index 101bd4b185..833c77216e 100644 --- a/servers/physics/physics_server_sw.cpp +++ b/servers/physics/physics_server_sw.cpp @@ -222,12 +222,24 @@ void PhysicsServerSW::area_set_space(RID p_area, RID p_space) { AreaSW *area = area_owner.get(p_area); ERR_FAIL_COND(!area); + SpaceSW *space = NULL; if (p_space.is_valid()) { space = space_owner.get(p_space); ERR_FAIL_COND(!space); } + if (area->get_space() == space) + return; //pointless + + for (Set<ConstraintSW *>::Element *E = area->get_constraints().front(); E; E = E->next()) { + RID self = E->get()->get_self(); + if (!self.is_valid()) + continue; + free(self); + } + area->clear_constraints(); + area->set_space(space); }; @@ -471,15 +483,23 @@ void PhysicsServerSW::body_set_space(RID p_body, RID p_space) { BodySW *body = body_owner.get(p_body); ERR_FAIL_COND(!body); - SpaceSW *space = NULL; + SpaceSW *space = NULL; if (p_space.is_valid()) { space = space_owner.get(p_space); ERR_FAIL_COND(!space); } if (body->get_space() == space) - return; //pointles + return; //pointless + + while (body->get_constraint_map().size()) { + RID self = body->get_constraint_map().front()->key()->get_self(); + if (!self.is_valid()) + continue; + free(self); + } + body->clear_constraint_map(); body->set_space(space); }; @@ -1329,12 +1349,6 @@ void PhysicsServerSW::free(RID p_rid) { body->remove_shape(0); } - while (body->get_constraint_map().size()) { - RID self = body->get_constraint_map().front()->key()->get_self(); - ERR_FAIL_COND(!self.is_valid()); - free(self); - } - body_owner.free(p_rid); memdelete(body); diff --git a/servers/physics/space_sw.cpp b/servers/physics/space_sw.cpp index 5679fc8f60..094cfa4656 100644 --- a/servers/physics/space_sw.cpp +++ b/servers/physics/space_sw.cpp @@ -34,12 +34,12 @@ _FORCE_INLINE_ static bool _match_object_type_query(CollisionObjectSW *p_object, uint32_t p_collision_layer, uint32_t p_type_mask) { - if (p_object->get_type() == CollisionObjectSW::TYPE_AREA) - return p_type_mask & PhysicsDirectSpaceState::TYPE_MASK_AREA; - if ((p_object->get_collision_layer() & p_collision_layer) == 0) return false; + if (p_object->get_type() == CollisionObjectSW::TYPE_AREA) + return p_type_mask & PhysicsDirectSpaceState::TYPE_MASK_AREA; + BodySW *body = static_cast<BodySW *>(p_object); return (1 << body->get_mode()) & p_type_mask; diff --git a/servers/physics_2d/area_2d_sw.h b/servers/physics_2d/area_2d_sw.h index 68b3c61e44..6d74a4b0f6 100644 --- a/servers/physics_2d/area_2d_sw.h +++ b/servers/physics_2d/area_2d_sw.h @@ -153,6 +153,7 @@ public: _FORCE_INLINE_ void add_constraint(Constraint2DSW *p_constraint) { constraints.insert(p_constraint); } _FORCE_INLINE_ void remove_constraint(Constraint2DSW *p_constraint) { constraints.erase(p_constraint); } _FORCE_INLINE_ const Set<Constraint2DSW *> &get_constraints() const { return constraints; } + _FORCE_INLINE_ void clear_constraints() { constraints.clear(); } void set_monitorable(bool p_monitorable); _FORCE_INLINE_ bool is_monitorable() const { return monitorable; } diff --git a/servers/physics_2d/body_2d_sw.h b/servers/physics_2d/body_2d_sw.h index 9e5deef3f2..412f2f51cd 100644 --- a/servers/physics_2d/body_2d_sw.h +++ b/servers/physics_2d/body_2d_sw.h @@ -181,6 +181,7 @@ public: _FORCE_INLINE_ void add_constraint(Constraint2DSW *p_constraint, int p_pos) { constraint_map[p_constraint] = p_pos; } _FORCE_INLINE_ void remove_constraint(Constraint2DSW *p_constraint) { constraint_map.erase(p_constraint); } const Map<Constraint2DSW *, int> &get_constraint_map() const { return constraint_map; } + _FORCE_INLINE_ void clear_constraint_map() { constraint_map.clear(); } _FORCE_INLINE_ void set_omit_force_integration(bool p_omit_force_integration) { omit_force_integration = p_omit_force_integration; } _FORCE_INLINE_ bool get_omit_force_integration() const { return omit_force_integration; } diff --git a/servers/physics_2d/broad_phase_2d_hash_grid.cpp b/servers/physics_2d/broad_phase_2d_hash_grid.cpp index 5b6c7e2f38..0330bfa9f3 100644 --- a/servers/physics_2d/broad_phase_2d_hash_grid.cpp +++ b/servers/physics_2d/broad_phase_2d_hash_grid.cpp @@ -203,9 +203,11 @@ void BroadPhase2DHashGrid::_exit_grid(Element *p_elem, const Rect2 &p_rect, bool if (sz.width * sz.height > large_object_min_surface) { //unpair all elements, instead of checking all, just check what is already paired, so we at least save from checking static vs static - for (Map<Element *, PairData *>::Element *E = p_elem->paired.front(); E; E = E->next()) { - + Map<Element *, PairData *>::Element *E = p_elem->paired.front(); + while (E) { + Map<Element *, PairData *>::Element *next = E->next(); _unpair_attempt(p_elem, E->key()); + E = next; } if (large_elements[p_elem].dec() == 0) { diff --git a/servers/physics_2d/physics_2d_server_sw.cpp b/servers/physics_2d/physics_2d_server_sw.cpp index c20d0d14a2..add376bfb2 100644 --- a/servers/physics_2d/physics_2d_server_sw.cpp +++ b/servers/physics_2d/physics_2d_server_sw.cpp @@ -286,12 +286,24 @@ void Physics2DServerSW::area_set_space(RID p_area, RID p_space) { Area2DSW *area = area_owner.get(p_area); ERR_FAIL_COND(!area); + Space2DSW *space = NULL; if (p_space.is_valid()) { space = space_owner.get(p_space); ERR_FAIL_COND(!space); } + if (area->get_space() == space) + return; //pointless + + for (Set<Constraint2DSW *>::Element *E = area->get_constraints().front(); E; E = E->next()) { + RID self = E->get()->get_self(); + if (!self.is_valid()) + continue; + free(self); + } + area->clear_constraints(); + area->set_space(space); }; @@ -533,6 +545,17 @@ void Physics2DServerSW::body_set_space(RID p_body, RID p_space) { ERR_FAIL_COND(!space); } + if (body->get_space() == space) + return; //pointless + + while (body->get_constraint_map().size()) { + RID self = body->get_constraint_map().front()->key()->get_self(); + if (!self.is_valid()) + continue; + free(self); + } + body->clear_constraint_map(); + body->set_space(space); }; @@ -1073,19 +1096,13 @@ void Physics2DServerSW::free(RID p_rid) { _clear_query(body->get_direct_state_query()); */ - body->set_space(NULL); + body_set_space(p_rid, RID()); while (body->get_shape_count()) { body->remove_shape(0); } - while (body->get_constraint_map().size()) { - RID self = body->get_constraint_map().front()->key()->get_self(); - ERR_FAIL_COND(!self.is_valid()); - free(self); - } - body_owner.free(p_rid); memdelete(body); |