summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--.travis.yml3
-rw-r--r--core/bind/core_bind.cpp14
-rw-r--r--core/bind/core_bind.h3
-rw-r--r--core/io/resource_loader.cpp53
-rw-r--r--core/math/geometry.cpp2
-rw-r--r--core/os/os.cpp8
-rw-r--r--core/os/os.h10
-rw-r--r--core/translation.cpp91
-rw-r--r--core/translation.h1
-rw-r--r--doc/classes/ARVRController.xml7
-rw-r--r--doc/classes/ARVRInterface.xml20
-rw-r--r--doc/classes/AnimationPlayer.xml15
-rw-r--r--doc/classes/CharFXTransform.xml23
-rw-r--r--doc/classes/OS.xml47
-rw-r--r--doc/classes/ProjectSettings.xml3
-rw-r--r--doc/classes/RichTextEffect.xml11
-rw-r--r--doc/classes/VisualServer.xml8
-rwxr-xr-xdoc/tools/makerst.py8
-rw-r--r--drivers/gles2/shader_gles2.h6
-rw-r--r--drivers/gles3/rasterizer_canvas_gles3.cpp17
-rw-r--r--editor/editor_file_dialog.cpp6
-rw-r--r--editor/plugins/canvas_item_editor_plugin.cpp32
-rw-r--r--editor/project_manager.cpp8
-rw-r--r--editor/spatial_editor_gizmos.cpp18
-rw-r--r--editor/translations/af.po9
-rw-r--r--editor/translations/ar.po9
-rw-r--r--editor/translations/bg.po9
-rw-r--r--editor/translations/bn.po9
-rw-r--r--editor/translations/ca.po9
-rw-r--r--editor/translations/cs.po9
-rw-r--r--editor/translations/da.po9
-rw-r--r--editor/translations/de.po10
-rw-r--r--editor/translations/de_CH.po9
-rw-r--r--editor/translations/editor.pot9
-rw-r--r--editor/translations/el.po9
-rw-r--r--editor/translations/eo.po10
-rw-r--r--editor/translations/es.po10
-rw-r--r--editor/translations/es_AR.po10
-rw-r--r--editor/translations/et.po9
-rw-r--r--editor/translations/eu.po19
-rw-r--r--editor/translations/fa.po9
-rw-r--r--editor/translations/fi.po10
-rw-r--r--editor/translations/fil.po9
-rw-r--r--editor/translations/fr.po19
-rw-r--r--editor/translations/ga.po9
-rw-r--r--editor/translations/he.po9
-rw-r--r--editor/translations/hi.po9
-rw-r--r--editor/translations/hr.po9
-rw-r--r--editor/translations/hu.po9
-rw-r--r--editor/translations/id.po9
-rw-r--r--editor/translations/is.po9
-rw-r--r--editor/translations/it.po10
-rw-r--r--editor/translations/ja.po10
-rw-r--r--editor/translations/ka.po9
-rw-r--r--editor/translations/ko.po10
-rw-r--r--editor/translations/lt.po9
-rw-r--r--editor/translations/lv.po9
-rw-r--r--editor/translations/mi.po9
-rw-r--r--editor/translations/ml.po9
-rw-r--r--editor/translations/ms.po9
-rw-r--r--editor/translations/nb.po9
-rw-r--r--editor/translations/nl.po9
-rw-r--r--editor/translations/or.po9
-rw-r--r--editor/translations/pl.po10
-rw-r--r--editor/translations/pr.po9
-rw-r--r--editor/translations/pt_BR.po126
-rw-r--r--editor/translations/pt_PT.po10
-rw-r--r--editor/translations/ro.po9
-rw-r--r--editor/translations/ru.po10
-rw-r--r--editor/translations/si.po9
-rw-r--r--editor/translations/sk.po9
-rw-r--r--editor/translations/sl.po9
-rw-r--r--editor/translations/sq.po9
-rw-r--r--editor/translations/sr_Cyrl.po9
-rw-r--r--editor/translations/sr_Latn.po9
-rw-r--r--editor/translations/sv.po9
-rw-r--r--editor/translations/ta.po9
-rw-r--r--editor/translations/te.po9
-rw-r--r--editor/translations/th.po9
-rw-r--r--editor/translations/tr.po10
-rw-r--r--editor/translations/uk.po10
-rw-r--r--editor/translations/ur_PK.po9
-rw-r--r--editor/translations/vi.po9
-rw-r--r--editor/translations/zh_CN.po10
-rw-r--r--editor/translations/zh_HK.po9
-rw-r--r--editor/translations/zh_TW.po9
-rw-r--r--main/main.cpp21
-rw-r--r--modules/camera/SCsub (renamed from modules/camera/SCSub)0
-rw-r--r--modules/gdscript/gdscript_parser.cpp7
-rw-r--r--modules/mono/build_scripts/mono_android_config.xml28
-rw-r--r--modules/mono/build_scripts/mono_configure.py7
-rw-r--r--modules/mono/editor/GodotTools/GodotTools/Export/ExportPlugin.cs57
-rw-r--r--modules/mono/editor/GodotTools/GodotTools/Utils/OS.cs2
-rw-r--r--modules/mono/editor/editor_internal_calls.cpp7
-rw-r--r--modules/mono/editor/godotsharp_export.cpp25
-rw-r--r--modules/mono/editor/godotsharp_export.h5
-rw-r--r--modules/mono/glue/Managed/Files/Array.cs13
-rw-r--r--modules/mono/glue/Managed/Files/Dictionary.cs13
-rw-r--r--modules/mono/glue/Managed/Files/GD.cs8
-rw-r--r--modules/mono/glue/collections_glue.cpp10
-rw-r--r--modules/mono/glue/collections_glue.h4
-rw-r--r--modules/mono/mono_gd/gd_mono.cpp13
-rw-r--r--modules/mono/mono_gd/gd_mono_android.cpp601
-rw-r--r--modules/mono/mono_gd/gd_mono_android.h6
-rw-r--r--modules/mono/mono_gd/gd_mono_cache.h28
-rw-r--r--modules/mono/mono_gd/gd_mono_marshal.cpp2
-rw-r--r--modules/visual_script/visual_script_editor.cpp1
-rw-r--r--platform/iphone/export/export.cpp2
-rw-r--r--platform/javascript/detect.py7
-rw-r--r--platform/windows/context_gl_windows.cpp41
-rw-r--r--platform/windows/context_gl_windows.h3
-rw-r--r--platform/windows/detect.py5
-rw-r--r--platform/windows/export/export.cpp77
-rwxr-xr-xplatform/windows/os_windows.cpp1
-rw-r--r--scene/gui/file_dialog.cpp6
-rw-r--r--scene/resources/packed_scene.cpp3
-rw-r--r--servers/visual_server.cpp1
-rw-r--r--thirdparty/misc/ifaddrs-android.h19
118 files changed, 1748 insertions, 398 deletions
diff --git a/.travis.yml b/.travis.yml
index 7bf968ba4c..e7a13e3811 100644
--- a/.travis.yml
+++ b/.travis.yml
@@ -20,7 +20,7 @@ cache:
matrix:
include:
- - name: Static checks (clang-format)
+ - name: Static checks (clang-format) + Documentation checks
stage: check
env: STATIC_CHECKS=yes
os: linux
@@ -129,6 +129,7 @@ before_script:
script:
- if [ "$STATIC_CHECKS" = "yes" ]; then
sh ./misc/travis/clang-format.sh;
+ doc/tools/makerst.py --dry-run doc/classes modules;
else
scons -j2 CC=$CC CXX=$CXX platform=$PLATFORM tools=$TOOLS target=$TARGET $OPTIONS $EXTRA_ARGS &&
if [ "$TEST_PROJECT" = "yes" ]; then
diff --git a/core/bind/core_bind.cpp b/core/bind/core_bind.cpp
index 1544503045..4c8dcc20ea 100644
--- a/core/bind/core_bind.cpp
+++ b/core/bind/core_bind.cpp
@@ -584,6 +584,15 @@ bool _OS::is_vsync_enabled() const {
return OS::get_singleton()->is_vsync_enabled();
}
+void _OS::set_vsync_via_compositor(bool p_enable) {
+ OS::get_singleton()->set_vsync_via_compositor(p_enable);
+}
+
+bool _OS::is_vsync_via_compositor_enabled() const {
+
+ return OS::get_singleton()->is_vsync_via_compositor_enabled();
+}
+
_OS::PowerState _OS::get_power_state() {
return _OS::PowerState(OS::get_singleton()->get_power_state());
}
@@ -1335,6 +1344,9 @@ void _OS::_bind_methods() {
ClassDB::bind_method(D_METHOD("set_use_vsync", "enable"), &_OS::set_use_vsync);
ClassDB::bind_method(D_METHOD("is_vsync_enabled"), &_OS::is_vsync_enabled);
+ ClassDB::bind_method(D_METHOD("set_vsync_via_compositor", "enable"), &_OS::set_vsync_via_compositor);
+ ClassDB::bind_method(D_METHOD("is_vsync_via_compositor_enabled"), &_OS::is_vsync_via_compositor_enabled);
+
ClassDB::bind_method(D_METHOD("has_feature", "tag_name"), &_OS::has_feature);
ClassDB::bind_method(D_METHOD("get_power_state"), &_OS::get_power_state);
@@ -1349,6 +1361,7 @@ void _OS::_bind_methods() {
ADD_PROPERTY(PropertyInfo(Variant::INT, "current_screen"), "set_current_screen", "get_current_screen");
ADD_PROPERTY(PropertyInfo(Variant::INT, "exit_code"), "set_exit_code", "get_exit_code");
ADD_PROPERTY(PropertyInfo(Variant::BOOL, "vsync_enabled"), "set_use_vsync", "is_vsync_enabled");
+ ADD_PROPERTY(PropertyInfo(Variant::BOOL, "vsync_via_compositor"), "set_vsync_via_compositor", "is_vsync_via_compositor_enabled");
ADD_PROPERTY(PropertyInfo(Variant::BOOL, "low_processor_usage_mode"), "set_low_processor_usage_mode", "is_in_low_processor_usage_mode");
ADD_PROPERTY(PropertyInfo(Variant::INT, "low_processor_usage_mode_sleep_usec"), "set_low_processor_usage_mode_sleep_usec", "get_low_processor_usage_mode_sleep_usec");
ADD_PROPERTY(PropertyInfo(Variant::BOOL, "keep_screen_on"), "set_keep_screen_on", "is_keep_screen_on");
@@ -1371,6 +1384,7 @@ void _OS::_bind_methods() {
ADD_PROPERTY_DEFAULT("current_screen", 0);
ADD_PROPERTY_DEFAULT("exit_code", 0);
ADD_PROPERTY_DEFAULT("vsync_enabled", true);
+ ADD_PROPERTY_DEFAULT("vsync_via_compositor", false);
ADD_PROPERTY_DEFAULT("low_processor_usage_mode", false);
ADD_PROPERTY_DEFAULT("low_processor_usage_mode_sleep_usec", 6900);
ADD_PROPERTY_DEFAULT("keep_screen_on", true);
diff --git a/core/bind/core_bind.h b/core/bind/core_bind.h
index 18182860c6..d57da36ca5 100644
--- a/core/bind/core_bind.h
+++ b/core/bind/core_bind.h
@@ -345,6 +345,9 @@ public:
void set_use_vsync(bool p_enable);
bool is_vsync_enabled() const;
+ void set_vsync_via_compositor(bool p_enable);
+ bool is_vsync_via_compositor_enabled() const;
+
PowerState get_power_state();
int get_power_seconds_left();
int get_power_percent_left();
diff --git a/core/io/resource_loader.cpp b/core/io/resource_loader.cpp
index f3eba44973..6f64543b3e 100644
--- a/core/io/resource_loader.cpp
+++ b/core/io/resource_loader.cpp
@@ -734,26 +734,49 @@ String ResourceLoader::_path_remap(const String &p_path, bool *r_translation_rem
String new_path = p_path;
- if (translation_remaps.has(new_path)) {
+ if (translation_remaps.has(p_path)) {
+ // translation_remaps has the following format:
+ // { "res://path.png": PoolStringArray( "res://path-ru.png:ru", "res://path-de.png:de" ) }
+
+ // To find the path of the remapped resource, we extract the locale name after
+ // the last ':' to match the project locale.
+ // We also fall back in case of regional locales as done in TranslationServer::translate
+ // (e.g. 'ru_RU' -> 'ru' if the former has no specific mapping).
- Vector<String> &v = *translation_remaps.getptr(new_path);
String locale = TranslationServer::get_singleton()->get_locale();
- if (r_translation_remapped) {
- *r_translation_remapped = true;
- }
- for (int i = 0; i < v.size(); i++) {
+ ERR_FAIL_COND_V_MSG(locale.length() < 2, p_path, "Could not remap path '" + p_path + "' for translation as configured locale '" + locale + "' is invalid.");
+ String lang = TranslationServer::get_language_code(locale);
- int split = v[i].find_last(":");
- if (split == -1)
- continue;
- String l = v[i].right(split + 1).strip_edges();
- if (l == String())
+ Vector<String> &res_remaps = *translation_remaps.getptr(new_path);
+ bool near_match = false;
+
+ for (int i = 0; i < res_remaps.size(); i++) {
+ int split = res_remaps[i].find_last(":");
+ if (split == -1) {
continue;
+ }
- if (l.begins_with(locale)) {
- new_path = v[i].left(split);
+ String l = res_remaps[i].right(split + 1).strip_edges();
+ if (l == locale) { // Exact match.
+ new_path = res_remaps[i].left(split);
break;
+ } else if (near_match) {
+ continue; // Already found near match, keep going for potential exact match.
}
+
+ // No exact match (e.g. locale 'ru_RU' but remap is 'ru'), let's look further
+ // for a near match (same language code, i.e. first 2 or 3 letters before
+ // regional code, if included).
+ if (TranslationServer::get_language_code(l) == lang) {
+ // Language code matches, that's a near match. Keep looking for exact match.
+ near_match = true;
+ new_path = res_remaps[i].left(split);
+ continue;
+ }
+ }
+
+ if (r_translation_remapped) {
+ *r_translation_remapped = true;
}
}
@@ -761,8 +784,8 @@ String ResourceLoader::_path_remap(const String &p_path, bool *r_translation_rem
new_path = path_remaps[new_path];
}
- if (new_path == p_path) { //did not remap
- //try file remap
+ if (new_path == p_path) { // Did not remap.
+ // Try file remap.
Error err;
FileAccess *f = FileAccess::open(p_path + ".remap", FileAccess::READ, &err);
diff --git a/core/math/geometry.cpp b/core/math/geometry.cpp
index e0ead8446f..ada5107a2c 100644
--- a/core/math/geometry.cpp
+++ b/core/math/geometry.cpp
@@ -1158,7 +1158,7 @@ Vector<Vector<Point2> > Geometry::_polypath_offset(const Vector<Point2> &p_polyp
case END_SQUARE: et = etOpenSquare; break;
case END_ROUND: et = etOpenRound; break;
}
- ClipperOffset co;
+ ClipperOffset co(2.0, 0.25 * SCALE_FACTOR); // Defaults from ClipperOffset.
Path path;
// Need to scale points (Clipper's requirement for robust computation).
diff --git a/core/os/os.cpp b/core/os/os.cpp
index 25889de1b3..2d61417b4f 100644
--- a/core/os/os.cpp
+++ b/core/os/os.cpp
@@ -572,6 +572,14 @@ bool OS::is_vsync_enabled() const {
return _use_vsync;
}
+void OS::set_vsync_via_compositor(bool p_enable) {
+ _vsync_via_compositor = p_enable;
+}
+
+bool OS::is_vsync_via_compositor_enabled() const {
+ return _vsync_via_compositor;
+}
+
OS::PowerState OS::get_power_state() {
return POWERSTATE_UNKNOWN;
}
diff --git a/core/os/os.h b/core/os/os.h
index 687ccaaba5..26db629d7c 100644
--- a/core/os/os.h
+++ b/core/os/os.h
@@ -60,6 +60,9 @@ class OS {
bool _allow_hidpi;
bool _allow_layered;
bool _use_vsync;
+ bool _vsync_via_compositor;
+
+ char *last_error;
void *_stack_bottom;
@@ -98,9 +101,10 @@ public:
bool maximized;
bool always_on_top;
bool use_vsync;
+ bool vsync_via_compositor;
bool layered;
float get_aspect() const { return (float)width / (float)height; }
- VideoMode(int p_width = 1024, int p_height = 600, bool p_fullscreen = false, bool p_resizable = true, bool p_borderless_window = false, bool p_maximized = false, bool p_always_on_top = false, bool p_use_vsync = false) {
+ VideoMode(int p_width = 1024, int p_height = 600, bool p_fullscreen = false, bool p_resizable = true, bool p_borderless_window = false, bool p_maximized = false, bool p_always_on_top = false, bool p_use_vsync = false, bool p_vsync_via_compositor = false) {
width = p_width;
height = p_height;
fullscreen = p_fullscreen;
@@ -109,6 +113,7 @@ public:
maximized = p_maximized;
always_on_top = p_always_on_top;
use_vsync = p_use_vsync;
+ vsync_via_compositor = p_vsync_via_compositor;
layered = false;
}
};
@@ -507,6 +512,9 @@ public:
//real, actual overridable function to switch vsync, which needs to be called from graphics thread if needed
virtual void _set_use_vsync(bool p_enable) {}
+ void set_vsync_via_compositor(bool p_enable);
+ bool is_vsync_via_compositor_enabled() const;
+
virtual OS::PowerState get_power_state();
virtual int get_power_seconds_left();
virtual int get_power_percent_left();
diff --git a/core/translation.cpp b/core/translation.cpp
index 4a1ac26433..4a662b2590 100644
--- a/core/translation.cpp
+++ b/core/translation.cpp
@@ -792,11 +792,6 @@ static const char *locale_renames[][2] = {
{ NULL, NULL }
};
-static String get_trimmed_locale(const String &p_locale) {
-
- return p_locale.substr(0, 2);
-}
-
///////////////////////////////////////////////
PoolVector<String> Translation::_get_messages() const {
@@ -846,7 +841,7 @@ void Translation::set_locale(const String &p_locale) {
String univ_locale = TranslationServer::standardize_locale(p_locale);
if (!TranslationServer::is_locale_valid(univ_locale)) {
- String trimmed_locale = get_trimmed_locale(univ_locale);
+ String trimmed_locale = TranslationServer::get_language_code(univ_locale);
ERR_FAIL_COND_MSG(!TranslationServer::is_locale_valid(trimmed_locale), "Invalid locale: " + trimmed_locale + ".");
@@ -945,12 +940,29 @@ String TranslationServer::standardize_locale(const String &p_locale) {
return univ_locale;
}
+String TranslationServer::get_language_code(const String &p_locale) {
+
+ ERR_FAIL_COND_V_MSG(p_locale.length() < 2, p_locale, "Invalid locale '" + p_locale + "'.");
+ // Most language codes are two letters, but some are three,
+ // so we have to look for a regional code separator ('_' or '-')
+ // to extract the left part.
+ // For example we get 'nah_MX' as input and should return 'nah'.
+ int split = p_locale.find("_");
+ if (split == -1) {
+ split = p_locale.find("-");
+ }
+ if (split == -1) { // No separator, so the locale is already only a language code.
+ return p_locale;
+ }
+ return p_locale.left(split);
+}
+
void TranslationServer::set_locale(const String &p_locale) {
String univ_locale = standardize_locale(p_locale);
if (!is_locale_valid(univ_locale)) {
- String trimmed_locale = get_trimmed_locale(univ_locale);
+ String trimmed_locale = get_language_code(univ_locale);
print_verbose(vformat("Unsupported locale '%s', falling back to '%s'.", p_locale, trimmed_locale));
if (!is_locale_valid(trimmed_locale)) {
@@ -1039,11 +1051,13 @@ void TranslationServer::clear() {
StringName TranslationServer::translate(const StringName &p_message) const {
- //translate using locale
+ // Match given message against the translation catalog for the project locale.
if (!enabled)
return p_message;
+ ERR_FAIL_COND_V_MSG(locale.length() < 2, p_message, "Could not translate message as configured locale '" + locale + "' is invalid.");
+
// Locale can be of the form 'll_CC', i.e. language code and regional code,
// e.g. 'en_US', 'en_GB', etc. It might also be simply 'll', e.g. 'en'.
// To find the relevant translation, we look for those with locale starting
@@ -1051,67 +1065,78 @@ StringName TranslationServer::translate(const StringName &p_message) const {
// form. If not found, we fall back to a near match (another locale with
// same language code).
+ // Note: ResourceLoader::_path_remap reproduces this locale near matching
+ // logic, so be sure to propagate changes there when changing things here.
+
StringName res;
+ String lang = get_language_code(locale);
bool near_match = false;
- const CharType *lptr = &locale[0];
for (const Set<Ref<Translation> >::Element *E = translations.front(); E; E = E->next()) {
-
const Ref<Translation> &t = E->get();
- ERR_FAIL_COND_V(t.is_null(), StringName(""));
+ ERR_FAIL_COND_V(t.is_null(), p_message);
String l = t->get_locale();
- if (lptr[0] != l[0] || lptr[1] != l[1])
- continue; // Language code does not match.
bool exact_match = (l == locale);
- if (!exact_match && near_match)
- continue; // Only near-match once, but keep looking for exact matches.
+ if (!exact_match) {
+ if (near_match) {
+ continue; // Only near-match once, but keep looking for exact matches.
+ }
+ if (get_language_code(l) != lang) {
+ continue; // Language code does not match.
+ }
+ }
StringName r = t->get_message(p_message);
-
- if (!r)
+ if (!r) {
continue;
-
+ }
res = r;
- if (exact_match)
+ if (exact_match) {
break;
- else
+ } else {
near_match = true;
+ }
}
if (!res && fallback.length() >= 2) {
// Try again with the fallback locale.
- const CharType *fptr = &fallback[0];
+ String fallback_lang = get_language_code(fallback);
near_match = false;
- for (const Set<Ref<Translation> >::Element *E = translations.front(); E; E = E->next()) {
+ for (const Set<Ref<Translation> >::Element *E = translations.front(); E; E = E->next()) {
const Ref<Translation> &t = E->get();
- ERR_FAIL_COND_V(t.is_null(), StringName(""));
+ ERR_FAIL_COND_V(t.is_null(), p_message);
String l = t->get_locale();
- if (fptr[0] != l[0] || fptr[1] != l[1])
- continue; // Language code does not match.
bool exact_match = (l == fallback);
- if (!exact_match && near_match)
- continue; // Only near-match once, but keep looking for exact matches.
+ if (!exact_match) {
+ if (near_match) {
+ continue; // Only near-match once, but keep looking for exact matches.
+ }
+ if (get_language_code(l) != fallback_lang) {
+ continue; // Language code does not match.
+ }
+ }
StringName r = t->get_message(p_message);
-
- if (!r)
+ if (!r) {
continue;
-
+ }
res = r;
- if (exact_match)
+ if (exact_match) {
break;
- else
+ } else {
near_match = true;
+ }
}
}
- if (!res)
+ if (!res) {
return p_message;
+ }
return res;
}
diff --git a/core/translation.h b/core/translation.h
index d172b9ecf2..834374bda6 100644
--- a/core/translation.h
+++ b/core/translation.h
@@ -105,6 +105,7 @@ public:
static Vector<String> get_all_locale_names();
static bool is_locale_valid(const String &p_locale);
static String standardize_locale(const String &p_locale);
+ static String get_language_code(const String &p_locale);
void set_tool_translation(const Ref<Translation> &p_translation);
StringName tool_translate(const StringName &p_message) const;
diff --git a/doc/classes/ARVRController.xml b/doc/classes/ARVRController.xml
index 9c6cfc1d7d..24d8b48077 100644
--- a/doc/classes/ARVRController.xml
+++ b/doc/classes/ARVRController.xml
@@ -22,7 +22,7 @@
<return type="int" enum="ARVRPositionalTracker.TrackerHand">
</return>
<description>
- Returns the hand holding this controller, if known. See [code]TRACKER_*[/code] constants in [ARVRPositionalTracker].
+ Returns the hand holding this controller, if known. See [enum ARVRPositionalTracker.TrackerHand].
</description>
</method>
<method name="get_is_active" qualifiers="const">
@@ -61,7 +61,7 @@
<argument index="0" name="button" type="int">
</argument>
<description>
- Returns [code]true[/code] if the button at index [code]button[/code] is pressed.
+ Returns [code]true[/code] if the button at index [code]button[/code] is pressed. See [enum JoystickList], in particular the [code]JOY_VR_*[/code] constants.
</description>
</method>
</methods>
@@ -73,7 +73,8 @@
When a controller is turned off, its slot is freed. This ensures controllers will keep the same ID even when controllers with lower IDs are turned off.
</member>
<member name="rumble" type="float" setter="set_rumble" getter="get_rumble" default="0.0">
- The degree to which the tracker rumbles. Ranges from [code]0.0[/code] to [code]1.0[/code] with precision [code].01[/code]. If changed, updates [member ARVRPositionalTracker.rumble] accordingly.
+ The degree to which the controller vibrates. Ranges from [code]0.0[/code] to [code]1.0[/code] with precision [code].01[/code]. If changed, updates [member ARVRPositionalTracker.rumble] accordingly.
+ This is a useful property to animate if you want the controller to vibrate for a limited duration.
</member>
</members>
<signals>
diff --git a/doc/classes/ARVRInterface.xml b/doc/classes/ARVRInterface.xml
index 1da1351e49..41effcaecb 100644
--- a/doc/classes/ARVRInterface.xml
+++ b/doc/classes/ARVRInterface.xml
@@ -21,7 +21,7 @@
<return type="int">
</return>
<description>
- Returns a combination of flags providing information about the capabilities of this interface.
+ Returns a combination of [enum Capabilities] flags providing information about the capabilities of this interface.
</description>
</method>
<method name="get_name" qualifiers="const">
@@ -51,9 +51,9 @@
<description>
Call this to initialize this interface. The first interface that is initialized is identified as the primary interface and it will be used for rendering output.
After initializing the interface you want to use you then need to enable the AR/VR mode of a viewport and rendering should commence.
- [b]Note:[/b] You must enable the AR/VR mode on the main viewport for any device that uses the main output of Godot such as for mobile VR.
- If you do this for a platform that handles its own output (such as OpenVR) Godot will show just one eye without distortion on screen. Alternatively, you can add a separate viewport node to your scene and enable AR/VR on that viewport and it will be used to output to the HMD leaving you free to do anything you like in the main window such as using a separate camera as a spectator camera or render out something completely different.
- While currently not used you can activate additional interfaces, you may wish to do this if you want to track controllers from other platforms. However, at this point in time only one interface can render to an HMD.
+ [b]Note:[/b] You must enable the AR/VR mode on the main viewport for any device that uses the main output of Godot, such as for mobile VR.
+ If you do this for a platform that handles its own output (such as OpenVR) Godot will show just one eye without distortion on screen. Alternatively, you can add a separate viewport node to your scene and enable AR/VR on that viewport. It will be used to output to the HMD, leaving you free to do anything you like in the main window, such as using a separate camera as a spectator camera or rendering something completely different.
+ While currently not used, you can activate additional interfaces. You may wish to do this if you want to track controllers from other platforms. However, at this point in time only one interface can render to an HMD.
</description>
</method>
<method name="is_stereo">
@@ -73,13 +73,13 @@
</methods>
<members>
<member name="ar_is_anchor_detection_enabled" type="bool" setter="set_anchor_detection_is_enabled" getter="get_anchor_detection_is_enabled" default="false">
- On an AR interface, is our anchor detection enabled?
+ On an AR interface, [code]true[/code] if anchor detection is enabled.
</member>
<member name="interface_is_initialized" type="bool" setter="set_is_initialized" getter="is_initialized" default="false">
- Has this interface been initialized?
+ [code]true[/code] if this interface been initialized.
</member>
<member name="interface_is_primary" type="bool" setter="set_is_primary" getter="is_primary" default="false">
- Is this our primary interface?
+ [code]true[/code] if this is the primary interface.
</member>
</members>
<constants>
@@ -93,10 +93,10 @@
This interface supports stereoscopic rendering.
</constant>
<constant name="ARVR_AR" value="4" enum="Capabilities">
- This interface support AR (video background and real world tracking).
+ This interface supports AR (video background and real world tracking).
</constant>
<constant name="ARVR_EXTERNAL" value="8" enum="Capabilities">
- This interface outputs to an external device, if the main viewport is used the on screen output is an unmodified buffer of either the left or right eye (stretched if the viewport size is not changed to the same aspect ratio of [method get_render_targetsize]). Using a separate viewport node frees up the main viewport for other purposes.
+ This interface outputs to an external device. If the main viewport is used, the on screen output is an unmodified buffer of either the left or right eye (stretched if the viewport size is not changed to the same aspect ratio of [method get_render_targetsize]). Using a separate viewport node frees up the main viewport for other purposes.
</constant>
<constant name="EYE_MONO" value="0" enum="Eyes">
Mono output, this is mostly used internally when retrieving positioning information for our camera node or when stereo scopic rendering is not supported.
@@ -111,7 +111,7 @@
Tracking is behaving as expected.
</constant>
<constant name="ARVR_EXCESSIVE_MOTION" value="1" enum="Tracking_status">
- Tracking is hindered by excessive motion, player is moving faster than tracking can keep up.
+ Tracking is hindered by excessive motion (the player is moving faster than tracking can keep up).
</constant>
<constant name="ARVR_INSUFFICIENT_FEATURES" value="2" enum="Tracking_status">
Tracking is hindered by insufficient features, it's too dark (for camera-based tracking), player is blocked, etc.
diff --git a/doc/classes/AnimationPlayer.xml b/doc/classes/AnimationPlayer.xml
index 60d04649a8..a47b4a590e 100644
--- a/doc/classes/AnimationPlayer.xml
+++ b/doc/classes/AnimationPlayer.xml
@@ -106,7 +106,7 @@
<return type="float">
</return>
<description>
- Gets the actual playing speed of current animation or 0 if not playing. This speed is the [code]playback_speed[/code] property multiplied by [code]custom_speed[/code] argument specified when calling the [code]play[/code] method.
+ Gets the actual playing speed of current animation or 0 if not playing. This speed is the [member playback_speed] property multiplied by [code]custom_speed[/code] argument specified when calling the [method play] method.
</description>
</method>
<method name="get_queue">
@@ -144,9 +144,9 @@
<argument index="3" name="from_end" type="bool" default="false">
</argument>
<description>
- Plays the animation with key [code]name[/code]. Custom speed and blend times can be set. If [code]custom_speed[/code] is negative and [code]from_end[/code] is [code]true[/code], the animation will play backwards.
- If the animation has been paused by [method stop], it will be resumed. Calling [method play] without arguments will also resume the animation.
- [b]Note:[/b] The animation will be updated the next time the AnimationPlayer is processed. If other variables are updated at the same time this is called, they may be updated too early. To perform the update immediately, call [code]advance(0)[/code].
+ Plays the animation with key [code]name[/code]. Custom blend times and speed can be set. If [code]custom_speed[/code] is negative and [code]from_end[/code] is [code]true[/code], the animation will play backwards (which is equivalent to calling [method play_backwards]).
+ The [AnimationPlayer] keeps track of its current or last played animation with [member assigned_animation]. If this method is called with that same animation [code]name[/code], or with no [code]name[/code] parameter, the assigned animation will resume playing if it was paused, or restart if it was stopped (see [method stop] for both pause and stop). If the animation was already playing, it will keep playing.
+ [b]Note:[/b] The animation will be updated the next time the [AnimationPlayer] is processed. If other variables are updated at the same time this is called, they may be updated too early. To perform the update immediately, call [code]advance(0)[/code].
</description>
</method>
<method name="play_backwards">
@@ -158,8 +158,7 @@
</argument>
<description>
Plays the animation with key [code]name[/code] in reverse.
- If the animation has been paused by [code]stop(true)[/code], it will be resumed backwards. Calling [code]play_backwards()[/code] without arguments will also resume the animation backwards.
- [b]Note:[/b] This is the same as [code]play[/code] in regards to process/update behavior.
+ This method is a shorthand for [method play] with [code]custom_speed = -1.0[/code] and [code]from_end = true[/code], so see its description for more information.
</description>
</method>
<method name="queue">
@@ -222,8 +221,8 @@
<argument index="0" name="reset" type="bool" default="true">
</argument>
<description>
- Stops the currently playing animation. If [code]reset[/code] is [code]true[/code], the animation position is reset to [code]0[/code] and the playback speed is reset to [code]1.0[/code].
- If [code]reset[/code] is [code]false[/code], then calling [method play] without arguments or [code]play("same_as_before")[/code] will resume the animation. Works the same for the [method play_backwards].
+ Stops or pauses the currently playing animation. If [code]reset[/code] is [code]true[/code], the animation position is reset to [code]0[/code] and the playback speed is reset to [code]1.0[/code].
+ If [code]reset[/code] is [code]false[/code], the [member current_animation_position] will be kept and calling [method play] or [method play_backwards] without arguments or with the same animation name as [member assigned_animation] will resume the animation.
</description>
</method>
</methods>
diff --git a/doc/classes/CharFXTransform.xml b/doc/classes/CharFXTransform.xml
index e03229abe1..399530bb5d 100644
--- a/doc/classes/CharFXTransform.xml
+++ b/doc/classes/CharFXTransform.xml
@@ -1,10 +1,14 @@
<?xml version="1.0" encoding="UTF-8" ?>
<class name="CharFXTransform" inherits="Reference" category="Core" version="3.2">
<brief_description>
+ Controls how an individual character will be displayed in a [RichTextEffect].
</brief_description>
<description>
+ By setting various properties on this object, you can control how individual characters will be displayed in a [RichTextEffect].
</description>
<tutorials>
+ <link>http://docs.godotengine.org/en/latest/tutorials/gui/bbcode_in_richtextlabel.html</link>
+ <link>https://github.com/Eoin-ONeill-Yokai/Godot-Rich-Text-Effect-Test-Project</link>
</tutorials>
<methods>
<method name="get_value_or">
@@ -15,25 +19,44 @@
<argument index="1" name="default_value" type="Variant">
</argument>
<description>
+ Returns the value for [code]key[/code] in the [member env] [Dictionary], or [code]default_value[/code] if [code]key[/code] isn't defined in [member env]. If the value's type doesn't match [code]default_value[/code]'s type, this method will return [code]default_value[/code].
</description>
</method>
</methods>
<members>
<member name="absolute_index" type="int" setter="set_absolute_index" getter="get_absolute_index" default="0">
+ The index of the current character (starting from 0). Setting this property won't affect drawing.
</member>
<member name="character" type="int" setter="set_character" getter="get_character" default="0">
+ The Unicode codepoint the character will use. This only affects non-whitespace characters. [method @GDScript.ord] can be useful here. For example, the following will replace all characters with asterisks:
+ [codeblock]
+ # `char_fx` is the CharFXTransform parameter from `_process_custom_fx()`.
+ # See the RichTextEffect documentation for details.
+ char_fx.character = ord("*")
+ [/codeblock]
</member>
<member name="color" type="Color" setter="set_color" getter="get_color" default="Color( 0, 0, 0, 1 )">
+ The color the character will be drawn with.
</member>
<member name="elapsed_time" type="float" setter="set_elapsed_time" getter="get_elapsed_time" default="0.0">
+ The time elapsed since the [RichTextLabel] was added to the scene tree (in seconds). Time stops when the project is paused, unless the [RichTextLabel]'s [member Node.pause_mode] is set to [constant Node.PAUSE_MODE_PROCESS].
+ [b]Note:[/b] Time still passes while the [RichTextLabel] is hidden.
</member>
<member name="env" type="Dictionary" setter="set_environment" getter="get_environment" default="{}">
+ Contains the arguments passed in the opening BBCode tag. By default, arguments are strings; if their contents match a type such as [bool], [int] or [float], they will be converted automatically. Color codes in the form [code]#rrggbb[/code] or [code]#rgb[/code] will be converted to an opaque [Color]. String arguments may not contain spaces, even if they're quoted. If present, quotes will also be present in the final string.
+ For example, the opening BBCode tag [code][example foo=hello bar=true baz=42 color=#ffffff][/code] will map to the following [Dictionary]:
+ [codeblock]
+ {"foo": "hello", "bar": true, "baz": 42, "color": Color(1, 1, 1, 1)}
+ [/codeblock]
</member>
<member name="offset" type="Vector2" setter="set_offset" getter="get_offset" default="Vector2( 0, 0 )">
+ The position offset the character will be drawn with (in pixels).
</member>
<member name="relative_index" type="int" setter="set_relative_index" getter="get_relative_index" default="0">
+ The index of the current character (starting from 0). Setting this property won't affect drawing.
</member>
<member name="visible" type="bool" setter="set_visibility" getter="is_visible" default="true">
+ If [code]true[/code], the character will be drawn. If [code]false[/code], the character will be hidden. Characters around hidden characters will reflow to take the space of hidden characters. If this is not desired, set their [member color] to [code]Color(1, 1, 1, 0)[/code] instead.
</member>
</members>
<constants>
diff --git a/doc/classes/OS.xml b/doc/classes/OS.xml
index 6da0547352..54b4f3df64 100644
--- a/doc/classes/OS.xml
+++ b/doc/classes/OS.xml
@@ -45,6 +45,8 @@
<return type="void">
</return>
<description>
+ Shuts down system MIDI driver.
+ [b]Note:[/b] This method is implemented on Linux, macOS and Windows.
</description>
</method>
<method name="delay_msec" qualifiers="const">
@@ -119,6 +121,7 @@
[codeblock]
OS.execute("CMD.exe", ["/C", "cd %TEMP% &amp;&amp; dir"], true, output)
[/codeblock]
+ [b]Note:[/b] This method is implemented on Android, iOS, Linux, macOS and Windows.
</description>
</method>
<method name="find_scancode_from_string" qualifiers="const">
@@ -159,6 +162,7 @@
<description>
Returns an array of MIDI device names.
The returned array will be empty if the system MIDI driver has not previously been initialised with [method open_midi_inputs].
+ [b]Note:[/b] This method is implemented on Linux, macOS and Windows.
</description>
</method>
<method name="get_current_video_driver" qualifiers="const">
@@ -224,6 +228,7 @@
</return>
<description>
With this function you can get the list of dangerous permissions that have been granted to the Android application.
+ [b]Note:[/b] This method is implemented on Android.
</description>
</method>
<method name="get_ime_selection" qualifiers="const">
@@ -232,6 +237,7 @@
<description>
Returns the IME cursor position (the currently-edited portion of the string) relative to the characters in the composition string.
[constant MainLoop.NOTIFICATION_OS_IME_UPDATE] is sent to the application to notify it of changes to the IME cursor position.
+ [b]Note:[/b] This method is implemented on macOS.
</description>
</method>
<method name="get_ime_text" qualifiers="const">
@@ -240,6 +246,7 @@
<description>
Returns the IME intermediate composition string.
[constant MainLoop.NOTIFICATION_OS_IME_UPDATE] is sent to the application to notify it of changes to the IME composition string.
+ [b]Note:[/b] This method is implemented on macOS.
</description>
</method>
<method name="get_latin_keyboard_variant" qualifiers="const">
@@ -248,6 +255,7 @@
<description>
Returns the current latin keyboard variant as a String.
Possible return values are: [code]"QWERTY"[/code], [code]"AZERTY"[/code], [code]"QZERTY"[/code], [code]"DVORAK"[/code], [code]"NEO"[/code], [code]"COLEMAK"[/code] or [code]"ERROR"[/code].
+ [b]Note:[/b] This method is implemented on Linux, macOS and Windows. Returns [code]"QWERTY"[/code] on unsupported platforms.
</description>
</method>
<method name="get_locale" qualifiers="const">
@@ -262,6 +270,7 @@
</return>
<description>
Returns the model name of the current device.
+ [b]Note:[/b] This method is implemented on Android and iOS. Returns [code]"GenericDevice"[/code] on unsupported platforms.
</description>
</method>
<method name="get_name" qualifiers="const">
@@ -275,14 +284,16 @@
<return type="int">
</return>
<description>
- Returns the amount of battery left in the device as a percentage.
+ Returns the amount of battery left in the device as a percentage. Returns [code]-1[/code] if power state is unknown.
+ [b]Note:[/b] This method is implemented on Linux, macOS and Windows.
</description>
</method>
<method name="get_power_seconds_left">
<return type="int">
</return>
<description>
- Returns an estimate of the time left in seconds before the device runs out of battery.
+ Returns an estimate of the time left in seconds before the device runs out of battery. Returns [code]-1[/code] if power state is unknown.
+ [b]Note:[/b] This method is implemented on Linux, macOS and Windows.
</description>
</method>
<method name="get_power_state">
@@ -290,6 +301,7 @@
</return>
<description>
Returns the current state of the device regarding battery and power. See [enum PowerState] constants.
+ [b]Note:[/b] This method is implemented on Linux, macOS and Windows.
</description>
</method>
<method name="get_process_id" qualifiers="const">
@@ -297,6 +309,7 @@
</return>
<description>
Returns the project's process ID.
+ [b]Note:[/b] This method is implemented on Android, iOS, Linux, macOS and Windows.
</description>
</method>
<method name="get_processor_count" qualifiers="const">
@@ -345,6 +358,7 @@
xxhdpi - 480 dpi
xxxhdpi - 640 dpi
[/codeblock]
+ [b]Note:[/b] This method is implemented on Android, Linux, macOS and Windows. Returns [code]72[/code] on unsupported platforms.
</description>
</method>
<method name="get_screen_position" qualifiers="const">
@@ -393,6 +407,7 @@
</argument>
<description>
Returns the actual path to commonly used folders across different platforms. Available locations are specified in [enum SystemDir].
+ [b]Note:[/b] This method is implemented on Android, Linux, macOS and Windows.
</description>
</method>
<method name="get_system_time_msecs" qualifiers="const">
@@ -519,6 +534,7 @@
</argument>
<description>
Add a new item with text "label" to global menu. Use "_dock" menu to add item to the macOS dock icon menu.
+ [b]Note:[/b] This method is implemented on macOS.
</description>
</method>
<method name="global_menu_add_separator">
@@ -528,6 +544,7 @@
</argument>
<description>
Add a separator between items. Separators also occupy an index.
+ [b]Note:[/b] This method is implemented on macOS.
</description>
</method>
<method name="global_menu_clear">
@@ -537,6 +554,7 @@
</argument>
<description>
Clear the global menu, in effect removing all items.
+ [b]Note:[/b] This method is implemented on macOS.
</description>
</method>
<method name="global_menu_remove_item">
@@ -548,6 +566,7 @@
</argument>
<description>
Removes the item at index "idx" from the global menu. Note that the indexes of items after the removed item are going to be shifted by one.
+ [b]Note:[/b] This method is implemented on macOS.
</description>
</method>
<method name="has_environment" qualifiers="const">
@@ -644,6 +663,7 @@
<description>
Kill (terminate) the process identified by the given process ID ([code]pid[/code]), e.g. the one returned by [method execute] in non-blocking mode.
[b]Note:[/b] This method can also be used to kill processes that were not spawned by the game.
+ [b]Note:[/b] This method is implemented on Android, iOS, Linux, macOS and Windows.
</description>
</method>
<method name="move_window_to_foreground">
@@ -651,6 +671,7 @@
</return>
<description>
Moves the window to the front.
+ [b]Note:[/b] This method is implemented on Linux, macOS and Windows.
</description>
</method>
<method name="native_video_is_playing">
@@ -658,6 +679,7 @@
</return>
<description>
Returns [code]true[/code] if native video is playing.
+ [b]Note:[/b] This method is implemented on Android and iOS.
</description>
</method>
<method name="native_video_pause">
@@ -665,6 +687,7 @@
</return>
<description>
Pauses native video playback.
+ [b]Note:[/b] This method is implemented on Android and iOS.
</description>
</method>
<method name="native_video_play">
@@ -680,7 +703,7 @@
</argument>
<description>
Plays native video from the specified path, at the given volume and with audio and subtitle tracks.
- [b]Note:[/b] This method is only implemented on Android and iOS, and the current Android implementation does not support the [code]volume[/code], [code]audio_track[/code] and [code]subtitle_track[/code] options.
+ [b]Note:[/b] This method is implemented on Android and iOS, and the current Android implementation does not support the [code]volume[/code], [code]audio_track[/code] and [code]subtitle_track[/code] options.
</description>
</method>
<method name="native_video_stop">
@@ -688,6 +711,7 @@
</return>
<description>
Stops native video playback.
+ [b]Note:[/b] This method is implemented on Android and iOS.
</description>
</method>
<method name="native_video_unpause">
@@ -695,6 +719,7 @@
</return>
<description>
Resumes native video playback.
+ [b]Note:[/b] This method is implemented on Android and iOS.
</description>
</method>
<method name="open_midi_inputs">
@@ -702,6 +727,7 @@
</return>
<description>
Initialises the singleton for the system MIDI driver.
+ [b]Note:[/b] This method is implemented on Linux, macOS and Windows.
</description>
</method>
<method name="print_all_resources">
@@ -743,6 +769,7 @@
</return>
<description>
Request the user attention to the window. It'll flash the taskbar button on Windows or bounce the dock icon on OSX.
+ [b]Note:[/b] This method is implemented on Linux, macOS and Windows.
</description>
</method>
<method name="request_permission">
@@ -759,6 +786,7 @@
</return>
<description>
With this function you can request dangerous permissions since normal permissions are automatically granted at install time in Android application.
+ [b]Note:[/b] This method is implemented on Android.
</description>
</method>
<method name="set_icon">
@@ -769,6 +797,7 @@
<description>
Sets the game's icon using an [Image] resource.
The same image is used for window caption, taskbar/dock and window selection dialog. Image is scaled as needed.
+ [b]Note:[/b] This method is implemented on HTML5, Linux, macOS and Windows.
</description>
</method>
<method name="set_ime_active">
@@ -781,6 +810,7 @@
If active IME handles key events before the application and creates an composition string and suggestion list.
Application can retrieve the composition status by using [method get_ime_selection] and [method get_ime_text] functions.
Completed composition string is committed when input is finished.
+ [b]Note:[/b] This method is implemented on Linux, macOS and Windows.
</description>
</method>
<method name="set_ime_position">
@@ -790,6 +820,7 @@
</argument>
<description>
Sets position of IME suggestion list popup (in window coordinates).
+ [b]Note:[/b] This method is implemented on Linux, macOS and Windows.
</description>
</method>
<method name="set_native_icon">
@@ -800,7 +831,7 @@
<description>
Sets the game's icon using a multi-size platform-specific icon file ([code]*.ico[/code] on Windows and [code]*.icns[/code] on macOS).
Appropriate size sub-icons are used for window caption, taskbar/dock and window selection dialog.
- [b]Note:[/b] This method is only implemented on macOS and Windows.
+ [b]Note:[/b] This method is implemented on macOS and Windows.
</description>
</method>
<method name="set_thread_name">
@@ -828,6 +859,7 @@
</argument>
<description>
Sets whether the window should always be on top.
+ [b]Note:[/b] This method is implemented on Linux, macOS and Windows.
</description>
</method>
<method name="set_window_title">
@@ -838,6 +870,7 @@
<description>
Sets the window title to the specified string.
[b]Note:[/b] This should be used sporadically. Don't set this every frame, as that will negatively affect performance on some window managers.
+ [b]Note:[/b] This method is implemented on HTML5, Linux, macOS and Windows.
</description>
</method>
<method name="shell_open">
@@ -850,6 +883,7 @@
- [code]OS.shell_open("C:\\Users\name\Downloads")[/code] on Windows opens the file explorer at the user's Downloads folder.
- [code]OS.shell_open("https://godotengine.org")[/code] opens the default web browser on the official Godot website.
- [code]OS.shell_open("mailto:example@example.com")[/code] opens the default email client with the "To" field set to [code]example@example.com[/code]. See [url=https://blog.escapecreative.com/customizing-mailto-links/]Customizing [code]mailto:[/code] Links[/url] for a list of fields that can be added.
+ [b]Note:[/b] This method is implemented on Android, iOS, HTML5, Linux, macOS and Windows.
</description>
</method>
<method name="show_virtual_keyboard">
@@ -859,6 +893,7 @@
</argument>
<description>
Shows the virtual keyboard if the platform has one. The [code]existing_text[/code] parameter is useful for implementing your own LineEdit, as it tells the virtual keyboard what text has already been typed (the virtual keyboard uses it for auto-correct and predictions).
+ [b]Note:[/b] This method is implemented on Android, iOS and UWP.
</description>
</method>
</methods>
@@ -893,6 +928,9 @@
<member name="vsync_enabled" type="bool" setter="set_use_vsync" getter="is_vsync_enabled" default="true">
If [code]true[/code], vertical synchronization (Vsync) is enabled.
</member>
+ <member name="vsync_via_compositor" type="bool" setter="set_vsync_via_compositor" getter="is_vsync_via_compositor_enabled" default="false">
+ If [code]true[/code] and [code]vsync_enabled[/code] is true, the operating system's window compositor will be used for vsync when the compositor is enabled and the game is in windowed mode.
+ </member>
<member name="window_borderless" type="bool" setter="set_borderless_window" getter="get_borderless_window" default="false">
If [code]true[/code], removes the window frame.
[b]Note:[/b] Setting [code]window_borderless[/code] to [code]false[/code] disables per-pixel transparency.
@@ -910,6 +948,7 @@
If [code]true[/code], the window background is transparent and window frame is removed.
Use [code]get_tree().get_root().set_transparent_background(true)[/code] to disable main viewport background rendering.
[b]Note:[/b] This property has no effect if [b]Project &gt; Project Settings &gt; Display &gt; Window &gt; Per-pixel transparency &gt; Allowed[/b] setting is disabled.
+ [b]Note:[/b] This property is implemented on Linux, macOS and Windows.
</member>
<member name="window_position" type="Vector2" setter="set_window_position" getter="get_window_position" default="Vector2( 0, 0 )">
The window position relative to the screen, the origin is the top left corner, +Y axis goes to the bottom and +X axis goes to the right.
diff --git a/doc/classes/ProjectSettings.xml b/doc/classes/ProjectSettings.xml
index 772c2f5073..97af3ec77a 100644
--- a/doc/classes/ProjectSettings.xml
+++ b/doc/classes/ProjectSettings.xml
@@ -431,6 +431,9 @@
<member name="display/window/vsync/use_vsync" type="bool" setter="" getter="" default="true">
If [code]true[/code], enables vertical synchronization. This eliminates tearing that may appear in moving scenes, at the cost of higher input latency and stuttering at lower framerates. If [code]false[/code], vertical synchronization will be disabled, however, many platforms will enforce it regardless (such as mobile platforms and HTML5).
</member>
+ <member name="display/window/vsync/vsync_via_compositor" type="bool" setter="" getter="" default="false">
+ If [code]Use Vsync[/code] is enabled and this setting is [code]true[/code], enables vertical synchronization via the operating system's window compositor when in windowed mode and the compositor is enabled. This will prevent stutter in certain situations. (Windows only.)
+ </member>
<member name="editor/script_templates_search_path" type="String" setter="" getter="" default="&quot;res://script_templates&quot;">
</member>
<member name="editor/search_in_file_extensions" type="PoolStringArray" setter="" getter="" default="PoolStringArray( &quot;gd&quot;, &quot;shader&quot; )">
diff --git a/doc/classes/RichTextEffect.xml b/doc/classes/RichTextEffect.xml
index 5c3ffd9cff..0e043b1d50 100644
--- a/doc/classes/RichTextEffect.xml
+++ b/doc/classes/RichTextEffect.xml
@@ -1,10 +1,20 @@
<?xml version="1.0" encoding="UTF-8" ?>
<class name="RichTextEffect" inherits="Resource" category="Core" version="3.2">
<brief_description>
+ A custom effect for use with [RichTextLabel].
</brief_description>
<description>
+ A custom effect for use with [RichTextLabel].
+ [b]Note:[/b] For a [RichTextEffect] to be usable, a BBCode tag must be defined as a member variable called [code]bbcode[/code] in the script.
+ [codeblock]
+ # The RichTextEffect will be usable like this: `[example]Some text[/example]`
+ var bbcode = "example"
+ [/codeblock]
+ [b]Note:[/b] As soon as a [RichTextLabel] contains at least one [RichTextEffect], it will continuously process the effect unless the project is paused. This may impact battery life negatively.
</description>
<tutorials>
+ <link>http://docs.godotengine.org/en/latest/tutorials/gui/bbcode_in_richtextlabel.html</link>
+ <link>https://github.com/Eoin-ONeill-Yokai/Godot-Rich-Text-Effect-Test-Project</link>
</tutorials>
<methods>
<method name="_process_custom_fx" qualifiers="virtual">
@@ -13,6 +23,7 @@
<argument index="0" name="char_fx" type="CharFXTransform">
</argument>
<description>
+ Override this method to modify properties in [code]char_fx[/code]. The method must return [code]true[/code] if the character could be transformed successfully. If the method returns [code]false[/code], it will skip transformation to avoid displaying broken text.
</description>
</method>
</methods>
diff --git a/doc/classes/VisualServer.xml b/doc/classes/VisualServer.xml
index f1926834ad..3f3996e570 100644
--- a/doc/classes/VisualServer.xml
+++ b/doc/classes/VisualServer.xml
@@ -2606,6 +2606,14 @@
<description>
</description>
</method>
+ <method name="multimesh_create">
+ <return type="RID">
+ </return>
+ <description>
+ Creates a new multimesh on the VisualServer and returns an [RID] handle.
+ Once finished with your RID, you will want to free the RID using the VisualServer's [method free_rid] static method.
+ </description>
+ </method>
<method name="multimesh_get_aabb" qualifiers="const">
<return type="AABB">
</return>
diff --git a/doc/tools/makerst.py b/doc/tools/makerst.py
index de53259827..91240e9550 100755
--- a/doc/tools/makerst.py
+++ b/doc/tools/makerst.py
@@ -14,7 +14,7 @@ GODOT_DOCS_PATTERN = re.compile(r'^http(?:s)?://docs\.godotengine\.org/(?:[a-zA-
def print_error(error, state): # type: (str, State) -> None
- print(error)
+ print("ERROR: {}".format(error))
state.errored = True
@@ -982,7 +982,11 @@ def make_enum(t, state): # type: (str, State) -> str
if c in state.classes and e in state.classes[c].enums:
return ":ref:`{0}<enum_{1}_{0}>`".format(e, c)
- print_error("Unresolved enum '{}', file: {}".format(t, state.current_class), state)
+
+ # Don't fail for `Vector3.Axis`, as this enum is a special case which is expected not to be resolved.
+ if "{}.{}".format(c, e) != "Vector3.Axis":
+ print_error("Unresolved enum '{}', file: {}".format(t, state.current_class), state)
+
return t
diff --git a/drivers/gles2/shader_gles2.h b/drivers/gles2/shader_gles2.h
index c7a6465194..fbca69e0bb 100644
--- a/drivers/gles2/shader_gles2.h
+++ b/drivers/gles2/shader_gles2.h
@@ -118,10 +118,12 @@ private:
uint32_t code_version;
bool ok;
Version() {
- code_version = 0;
+ id = 0;
+ vert_id = 0;
frag_id = 0;
- ok = false;
uniform_location = NULL;
+ code_version = 0;
+ ok = false;
}
};
diff --git a/drivers/gles3/rasterizer_canvas_gles3.cpp b/drivers/gles3/rasterizer_canvas_gles3.cpp
index fccbc5f871..b3263ce41c 100644
--- a/drivers/gles3/rasterizer_canvas_gles3.cpp
+++ b/drivers/gles3/rasterizer_canvas_gles3.cpp
@@ -327,9 +327,8 @@ void RasterizerCanvasGLES3::_draw_polygon(const int *p_indices, int p_index_coun
glBindBuffer(GL_ARRAY_BUFFER, data.polygon_buffer);
#ifndef GLES_OVER_GL
- // Orphan the buffers to avoid CPU/GPU sync points caused by glBufferSubData
+ // Orphan the buffer to avoid CPU/GPU sync points caused by glBufferSubData
glBufferData(GL_ARRAY_BUFFER, data.polygon_buffer_size, NULL, GL_DYNAMIC_DRAW);
- glBufferData(GL_ELEMENT_ARRAY_BUFFER, data.polygon_index_buffer_size, NULL, GL_DYNAMIC_DRAW);
#endif
uint32_t buffer_ofs = 0;
@@ -402,6 +401,10 @@ void RasterizerCanvasGLES3::_draw_polygon(const int *p_indices, int p_index_coun
//bind the indices buffer.
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, data.polygon_index_buffer);
+#ifndef GLES_OVER_GL
+ // Orphan the buffer to avoid CPU/GPU sync points caused by glBufferSubData
+ glBufferData(GL_ELEMENT_ARRAY_BUFFER, data.polygon_index_buffer_size, NULL, GL_DYNAMIC_DRAW);
+#endif
glBufferSubData(GL_ELEMENT_ARRAY_BUFFER, 0, sizeof(int) * p_index_count, p_indices);
//draw the triangles.
@@ -424,9 +427,8 @@ void RasterizerCanvasGLES3::_draw_generic(GLuint p_primitive, int p_vertex_count
glBindBuffer(GL_ARRAY_BUFFER, data.polygon_buffer);
#ifndef GLES_OVER_GL
- // Orphan the buffers to avoid CPU/GPU sync points caused by glBufferSubData
+ // Orphan the buffer to avoid CPU/GPU sync points caused by glBufferSubData
glBufferData(GL_ARRAY_BUFFER, data.polygon_buffer_size, NULL, GL_DYNAMIC_DRAW);
- glBufferData(GL_ELEMENT_ARRAY_BUFFER, data.polygon_index_buffer_size, NULL, GL_DYNAMIC_DRAW);
#endif
uint32_t buffer_ofs = 0;
@@ -477,9 +479,8 @@ void RasterizerCanvasGLES3::_draw_generic_indices(GLuint p_primitive, const int
glBindBuffer(GL_ARRAY_BUFFER, data.polygon_buffer);
#ifndef GLES_OVER_GL
- // Orphan the buffers to avoid CPU/GPU sync points caused by glBufferSubData
+ // Orphan the buffer to avoid CPU/GPU sync points caused by glBufferSubData
glBufferData(GL_ARRAY_BUFFER, data.polygon_buffer_size, NULL, GL_DYNAMIC_DRAW);
- glBufferData(GL_ELEMENT_ARRAY_BUFFER, data.polygon_index_buffer_size, NULL, GL_DYNAMIC_DRAW);
#endif
uint32_t buffer_ofs = 0;
@@ -530,6 +531,10 @@ void RasterizerCanvasGLES3::_draw_generic_indices(GLuint p_primitive, const int
//bind the indices buffer.
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, data.polygon_index_buffer);
+#ifndef GLES_OVER_GL
+ // Orphan the buffer to avoid CPU/GPU sync points caused by glBufferSubData
+ glBufferData(GL_ELEMENT_ARRAY_BUFFER, data.polygon_index_buffer_size, NULL, GL_DYNAMIC_DRAW);
+#endif
glBufferSubData(GL_ELEMENT_ARRAY_BUFFER, 0, sizeof(int) * p_index_count, p_indices);
//draw the triangles.
diff --git a/editor/editor_file_dialog.cpp b/editor/editor_file_dialog.cpp
index 2db4f03859..ea01f127b3 100644
--- a/editor/editor_file_dialog.cpp
+++ b/editor/editor_file_dialog.cpp
@@ -916,16 +916,16 @@ void EditorFileDialog::update_filters() {
if (max_filters < filters.size())
all_filters += ", ...";
- filter->add_item(TTR("All Recognized") + " ( " + all_filters + " )");
+ filter->add_item(TTR("All Recognized") + " (" + all_filters + ")");
}
for (int i = 0; i < filters.size(); i++) {
String flt = filters[i].get_slice(";", 0).strip_edges();
String desc = filters[i].get_slice(";", 1).strip_edges();
if (desc.length())
- filter->add_item(desc + " ( " + flt + " )");
+ filter->add_item(desc + " (" + flt + ")");
else
- filter->add_item("( " + flt + " )");
+ filter->add_item("(" + flt + ")");
}
filter->add_item(TTR("All Files (*)"));
diff --git a/editor/plugins/canvas_item_editor_plugin.cpp b/editor/plugins/canvas_item_editor_plugin.cpp
index 9894c8c562..de9efaf8ba 100644
--- a/editor/plugins/canvas_item_editor_plugin.cpp
+++ b/editor/plugins/canvas_item_editor_plugin.cpp
@@ -1111,7 +1111,11 @@ bool CanvasItemEditor::_gui_input_rulers_and_guides(const Ref<InputEvent> &p_eve
if (dragged_guide_index >= 0) {
vguides.remove(dragged_guide_index);
undo_redo->create_action(TTR("Remove Vertical Guide"));
- undo_redo->add_do_method(EditorNode::get_singleton()->get_edited_scene(), "set_meta", "_edit_vertical_guides_", vguides);
+ if (vguides.empty()) {
+ undo_redo->add_do_method(EditorNode::get_singleton()->get_edited_scene(), "remove_meta", "_edit_vertical_guides_");
+ } else {
+ undo_redo->add_do_method(EditorNode::get_singleton()->get_edited_scene(), "set_meta", "_edit_vertical_guides_", vguides);
+ }
undo_redo->add_undo_method(EditorNode::get_singleton()->get_edited_scene(), "set_meta", "_edit_vertical_guides_", prev_vguides);
undo_redo->add_undo_method(viewport, "update");
undo_redo->commit_action();
@@ -1140,7 +1144,11 @@ bool CanvasItemEditor::_gui_input_rulers_and_guides(const Ref<InputEvent> &p_eve
if (dragged_guide_index >= 0) {
hguides.remove(dragged_guide_index);
undo_redo->create_action(TTR("Remove Horizontal Guide"));
- undo_redo->add_do_method(EditorNode::get_singleton()->get_edited_scene(), "set_meta", "_edit_horizontal_guides_", hguides);
+ if (hguides.empty()) {
+ undo_redo->add_do_method(EditorNode::get_singleton()->get_edited_scene(), "remove_meta", "_edit_horizontal_guides_");
+ } else {
+ undo_redo->add_do_method(EditorNode::get_singleton()->get_edited_scene(), "set_meta", "_edit_horizontal_guides_", hguides);
+ }
undo_redo->add_undo_method(EditorNode::get_singleton()->get_edited_scene(), "set_meta", "_edit_horizontal_guides_", prev_hguides);
undo_redo->add_undo_method(viewport, "update");
undo_redo->commit_action();
@@ -4752,19 +4760,21 @@ void CanvasItemEditor::_popup_callback(int p_op) {
} break;
case CLEAR_GUIDES: {
- if (EditorNode::get_singleton()->get_edited_scene()->has_meta("_edit_horizontal_guides_") || EditorNode::get_singleton()->get_edited_scene()->has_meta("_edit_vertical_guides_")) {
+ Node *const root = EditorNode::get_singleton()->get_edited_scene();
+
+ if (root && (root->has_meta("_edit_horizontal_guides_") || root->has_meta("_edit_vertical_guides_"))) {
undo_redo->create_action(TTR("Clear Guides"));
- if (EditorNode::get_singleton()->get_edited_scene()->has_meta("_edit_horizontal_guides_")) {
- Array hguides = EditorNode::get_singleton()->get_edited_scene()->get_meta("_edit_horizontal_guides_");
+ if (root->has_meta("_edit_horizontal_guides_")) {
+ Array hguides = root->get_meta("_edit_horizontal_guides_");
- undo_redo->add_do_method(EditorNode::get_singleton()->get_edited_scene(), "set_meta", "_edit_horizontal_guides_", Array());
- undo_redo->add_undo_method(EditorNode::get_singleton()->get_edited_scene(), "set_meta", "_edit_horizontal_guides_", hguides);
+ undo_redo->add_do_method(root, "remove_meta", "_edit_horizontal_guides_");
+ undo_redo->add_undo_method(root, "set_meta", "_edit_horizontal_guides_", hguides);
}
- if (EditorNode::get_singleton()->get_edited_scene()->has_meta("_edit_vertical_guides_")) {
- Array vguides = EditorNode::get_singleton()->get_edited_scene()->get_meta("_edit_vertical_guides_");
+ if (root->has_meta("_edit_vertical_guides_")) {
+ Array vguides = root->get_meta("_edit_vertical_guides_");
- undo_redo->add_do_method(EditorNode::get_singleton()->get_edited_scene(), "set_meta", "_edit_vertical_guides_", Array());
- undo_redo->add_undo_method(EditorNode::get_singleton()->get_edited_scene(), "set_meta", "_edit_vertical_guides_", vguides);
+ undo_redo->add_do_method(root, "remove_meta", "_edit_vertical_guides_");
+ undo_redo->add_undo_method(root, "set_meta", "_edit_vertical_guides_", vguides);
}
undo_redo->add_undo_method(viewport, "update");
undo_redo->commit_action();
diff --git a/editor/project_manager.cpp b/editor/project_manager.cpp
index ab62a59be1..d3bab64ccf 100644
--- a/editor/project_manager.cpp
+++ b/editor/project_manager.cpp
@@ -2466,9 +2466,9 @@ ProjectManager::ProjectManager() {
sort_label->set_text(TTR("Sort:"));
sort_filters->add_child(sort_label);
Vector<String> sort_filter_titles;
- sort_filter_titles.push_back("Name");
- sort_filter_titles.push_back("Path");
- sort_filter_titles.push_back("Last Modified");
+ sort_filter_titles.push_back(TTR("Name"));
+ sort_filter_titles.push_back(TTR("Path"));
+ sort_filter_titles.push_back(TTR("Last Modified"));
project_order_filter = memnew(ProjectListFilter);
project_order_filter->add_filter_option();
project_order_filter->_setup_filters(sort_filter_titles);
@@ -2696,7 +2696,7 @@ void ProjectListFilter::_setup_filters(Vector<String> options) {
filter_option->clear();
for (int i = 0; i < options.size(); i++)
- filter_option->add_item(TTR(options[i]));
+ filter_option->add_item(options[i]);
}
void ProjectListFilter::_search_text_changed(const String &p_newtext) {
diff --git a/editor/spatial_editor_gizmos.cpp b/editor/spatial_editor_gizmos.cpp
index cfd9ec19d2..fd9e44cd5f 100644
--- a/editor/spatial_editor_gizmos.cpp
+++ b/editor/spatial_editor_gizmos.cpp
@@ -202,6 +202,9 @@ void EditorSpatialGizmo::add_mesh(const Ref<ArrayMesh> &p_mesh, bool p_billboard
}
void EditorSpatialGizmo::add_lines(const Vector<Vector3> &p_lines, const Ref<Material> &p_material, bool p_billboard) {
+ if (p_lines.empty()) {
+ return;
+ }
ERR_FAIL_COND(!spatial_node);
Instance ins;
@@ -4190,8 +4193,19 @@ void JointSpatialGizmoPlugin::redraw(EditorSpatialGizmo *p_gizmo) {
p_gizmo->clear();
- const Spatial *node_body_a = Object::cast_to<Spatial>(joint->get_node(joint->get_node_a()));
- const Spatial *node_body_b = Object::cast_to<Spatial>(joint->get_node(joint->get_node_b()));
+ Spatial *node_body_a = NULL;
+ if (!joint->get_node_a().is_empty()) {
+ node_body_a = Object::cast_to<Spatial>(joint->get_node(joint->get_node_a()));
+ }
+
+ Spatial *node_body_b = NULL;
+ if (!joint->get_node_b().is_empty()) {
+ node_body_b = Object::cast_to<Spatial>(joint->get_node(joint->get_node_b()));
+ }
+
+ if (!node_body_a && !node_body_b) {
+ return;
+ }
Ref<Material> common_material = get_material("joint_material", p_gizmo);
Ref<Material> body_a_material = get_material("joint_body_a_material", p_gizmo);
diff --git a/editor/translations/af.po b/editor/translations/af.po
index bbcaf092e7..329d165510 100644
--- a/editor/translations/af.po
+++ b/editor/translations/af.po
@@ -1009,7 +1009,7 @@ msgid "Resource"
msgstr "Hulpbron"
#: editor/dependency_editor.cpp editor/editor_autoload_settings.cpp
-#: editor/project_settings_editor.cpp
+#: editor/project_manager.cpp editor/project_settings_editor.cpp
msgid "Path"
msgstr "Pad"
@@ -1500,7 +1500,8 @@ msgid "Node Name:"
msgstr "Nodus Naam:"
#: editor/editor_autoload_settings.cpp editor/editor_help_search.cpp
-#: editor/editor_profiler.cpp editor/settings_config_dialog.cpp
+#: editor/editor_profiler.cpp editor/project_manager.cpp
+#: editor/settings_config_dialog.cpp
msgid "Name"
msgstr "Naam"
@@ -9500,6 +9501,10 @@ msgid "Projects"
msgstr "Projek Stigters"
#: editor/project_manager.cpp
+msgid "Last Modified"
+msgstr ""
+
+#: editor/project_manager.cpp
msgid "Scan"
msgstr ""
diff --git a/editor/translations/ar.po b/editor/translations/ar.po
index 6be373b1f1..9ffb777a0f 100644
--- a/editor/translations/ar.po
+++ b/editor/translations/ar.po
@@ -1007,7 +1007,7 @@ msgid "Resource"
msgstr "مورد"
#: editor/dependency_editor.cpp editor/editor_autoload_settings.cpp
-#: editor/project_settings_editor.cpp
+#: editor/project_manager.cpp editor/project_settings_editor.cpp
msgid "Path"
msgstr "المسار"
@@ -1488,7 +1488,8 @@ msgid "Node Name:"
msgstr "إسم العقدة:"
#: editor/editor_autoload_settings.cpp editor/editor_help_search.cpp
-#: editor/editor_profiler.cpp editor/settings_config_dialog.cpp
+#: editor/editor_profiler.cpp editor/project_manager.cpp
+#: editor/settings_config_dialog.cpp
msgid "Name"
msgstr "الأسم"
@@ -9721,6 +9722,10 @@ msgid "Projects"
msgstr "مشروع"
#: editor/project_manager.cpp
+msgid "Last Modified"
+msgstr ""
+
+#: editor/project_manager.cpp
msgid "Scan"
msgstr ""
diff --git a/editor/translations/bg.po b/editor/translations/bg.po
index 9f82d5e72d..da370687cb 100644
--- a/editor/translations/bg.po
+++ b/editor/translations/bg.po
@@ -990,7 +990,7 @@ msgid "Resource"
msgstr ""
#: editor/dependency_editor.cpp editor/editor_autoload_settings.cpp
-#: editor/project_settings_editor.cpp
+#: editor/project_manager.cpp editor/project_settings_editor.cpp
msgid "Path"
msgstr ""
@@ -1461,7 +1461,8 @@ msgid "Node Name:"
msgstr ""
#: editor/editor_autoload_settings.cpp editor/editor_help_search.cpp
-#: editor/editor_profiler.cpp editor/settings_config_dialog.cpp
+#: editor/editor_profiler.cpp editor/project_manager.cpp
+#: editor/settings_config_dialog.cpp
msgid "Name"
msgstr ""
@@ -9577,6 +9578,10 @@ msgid "Projects"
msgstr "Проект"
#: editor/project_manager.cpp
+msgid "Last Modified"
+msgstr ""
+
+#: editor/project_manager.cpp
msgid "Scan"
msgstr "Сканиране"
diff --git a/editor/translations/bn.po b/editor/translations/bn.po
index da5e8b41ac..fda8528844 100644
--- a/editor/translations/bn.po
+++ b/editor/translations/bn.po
@@ -1035,7 +1035,7 @@ msgid "Resource"
msgstr "রিসোর্স"
#: editor/dependency_editor.cpp editor/editor_autoload_settings.cpp
-#: editor/project_settings_editor.cpp
+#: editor/project_manager.cpp editor/project_settings_editor.cpp
msgid "Path"
msgstr "পথ"
@@ -1529,7 +1529,8 @@ msgid "Node Name:"
msgstr "নোডের নাম:"
#: editor/editor_autoload_settings.cpp editor/editor_help_search.cpp
-#: editor/editor_profiler.cpp editor/settings_config_dialog.cpp
+#: editor/editor_profiler.cpp editor/project_manager.cpp
+#: editor/settings_config_dialog.cpp
msgid "Name"
msgstr "নাম"
@@ -10083,6 +10084,10 @@ msgid "Projects"
msgstr "নতুন প্রকল্প"
#: editor/project_manager.cpp
+msgid "Last Modified"
+msgstr ""
+
+#: editor/project_manager.cpp
msgid "Scan"
msgstr "স্ক্যান"
diff --git a/editor/translations/ca.po b/editor/translations/ca.po
index 4740b9ac89..db3074ef51 100644
--- a/editor/translations/ca.po
+++ b/editor/translations/ca.po
@@ -978,7 +978,7 @@ msgid "Resource"
msgstr "Recurs"
#: editor/dependency_editor.cpp editor/editor_autoload_settings.cpp
-#: editor/project_settings_editor.cpp
+#: editor/project_manager.cpp editor/project_settings_editor.cpp
msgid "Path"
msgstr "Camí"
@@ -1461,7 +1461,8 @@ msgid "Node Name:"
msgstr "Nom del node:"
#: editor/editor_autoload_settings.cpp editor/editor_help_search.cpp
-#: editor/editor_profiler.cpp editor/settings_config_dialog.cpp
+#: editor/editor_profiler.cpp editor/project_manager.cpp
+#: editor/settings_config_dialog.cpp
msgid "Name"
msgstr "Nom"
@@ -9693,6 +9694,10 @@ msgid "Projects"
msgstr "Projecte"
#: editor/project_manager.cpp
+msgid "Last Modified"
+msgstr ""
+
+#: editor/project_manager.cpp
msgid "Scan"
msgstr "Explora"
diff --git a/editor/translations/cs.po b/editor/translations/cs.po
index d359c22f28..dfe9b3b4e9 100644
--- a/editor/translations/cs.po
+++ b/editor/translations/cs.po
@@ -987,7 +987,7 @@ msgid "Resource"
msgstr "Zdroj"
#: editor/dependency_editor.cpp editor/editor_autoload_settings.cpp
-#: editor/project_settings_editor.cpp
+#: editor/project_manager.cpp editor/project_settings_editor.cpp
msgid "Path"
msgstr "Cesta"
@@ -1472,7 +1472,8 @@ msgid "Node Name:"
msgstr "Název uzlu:"
#: editor/editor_autoload_settings.cpp editor/editor_help_search.cpp
-#: editor/editor_profiler.cpp editor/settings_config_dialog.cpp
+#: editor/editor_profiler.cpp editor/project_manager.cpp
+#: editor/settings_config_dialog.cpp
msgid "Name"
msgstr "Název"
@@ -9597,6 +9598,10 @@ msgid "Projects"
msgstr "Projekt"
#: editor/project_manager.cpp
+msgid "Last Modified"
+msgstr ""
+
+#: editor/project_manager.cpp
msgid "Scan"
msgstr "Skenovat"
diff --git a/editor/translations/da.po b/editor/translations/da.po
index cd37bbc5f9..8c28f898aa 100644
--- a/editor/translations/da.po
+++ b/editor/translations/da.po
@@ -1014,7 +1014,7 @@ msgid "Resource"
msgstr "Ressource"
#: editor/dependency_editor.cpp editor/editor_autoload_settings.cpp
-#: editor/project_settings_editor.cpp
+#: editor/project_manager.cpp editor/project_settings_editor.cpp
msgid "Path"
msgstr "Sti"
@@ -1501,7 +1501,8 @@ msgid "Node Name:"
msgstr "Node Navn:"
#: editor/editor_autoload_settings.cpp editor/editor_help_search.cpp
-#: editor/editor_profiler.cpp editor/settings_config_dialog.cpp
+#: editor/editor_profiler.cpp editor/project_manager.cpp
+#: editor/settings_config_dialog.cpp
msgid "Name"
msgstr "Navn"
@@ -9692,6 +9693,10 @@ msgid "Projects"
msgstr "Projekt"
#: editor/project_manager.cpp
+msgid "Last Modified"
+msgstr ""
+
+#: editor/project_manager.cpp
msgid "Scan"
msgstr ""
diff --git a/editor/translations/de.po b/editor/translations/de.po
index ab157ee779..76dc2130bc 100644
--- a/editor/translations/de.po
+++ b/editor/translations/de.po
@@ -1015,7 +1015,7 @@ msgid "Resource"
msgstr "Ressource"
#: editor/dependency_editor.cpp editor/editor_autoload_settings.cpp
-#: editor/project_settings_editor.cpp
+#: editor/project_manager.cpp editor/project_settings_editor.cpp
msgid "Path"
msgstr "Pfad"
@@ -1491,7 +1491,8 @@ msgid "Node Name:"
msgstr "Node-Name:"
#: editor/editor_autoload_settings.cpp editor/editor_help_search.cpp
-#: editor/editor_profiler.cpp editor/settings_config_dialog.cpp
+#: editor/editor_profiler.cpp editor/project_manager.cpp
+#: editor/settings_config_dialog.cpp
msgid "Name"
msgstr "Name"
@@ -9562,6 +9563,11 @@ msgid "Projects"
msgstr "Projekte"
#: editor/project_manager.cpp
+#, fuzzy
+msgid "Last Modified"
+msgstr "Bearbeitet"
+
+#: editor/project_manager.cpp
msgid "Scan"
msgstr "Scannen"
diff --git a/editor/translations/de_CH.po b/editor/translations/de_CH.po
index 5b8d7da474..1ad8fb046f 100644
--- a/editor/translations/de_CH.po
+++ b/editor/translations/de_CH.po
@@ -984,7 +984,7 @@ msgid "Resource"
msgstr ""
#: editor/dependency_editor.cpp editor/editor_autoload_settings.cpp
-#: editor/project_settings_editor.cpp
+#: editor/project_manager.cpp editor/project_settings_editor.cpp
msgid "Path"
msgstr ""
@@ -1459,7 +1459,8 @@ msgid "Node Name:"
msgstr ""
#: editor/editor_autoload_settings.cpp editor/editor_help_search.cpp
-#: editor/editor_profiler.cpp editor/settings_config_dialog.cpp
+#: editor/editor_profiler.cpp editor/project_manager.cpp
+#: editor/settings_config_dialog.cpp
msgid "Name"
msgstr ""
@@ -9527,6 +9528,10 @@ msgid "Projects"
msgstr "Projektname:"
#: editor/project_manager.cpp
+msgid "Last Modified"
+msgstr ""
+
+#: editor/project_manager.cpp
msgid "Scan"
msgstr ""
diff --git a/editor/translations/editor.pot b/editor/translations/editor.pot
index d2a8b188f4..34ff822dc4 100644
--- a/editor/translations/editor.pot
+++ b/editor/translations/editor.pot
@@ -935,7 +935,7 @@ msgid "Resource"
msgstr ""
#: editor/dependency_editor.cpp editor/editor_autoload_settings.cpp
-#: editor/project_settings_editor.cpp
+#: editor/project_manager.cpp editor/project_settings_editor.cpp
msgid "Path"
msgstr ""
@@ -1400,7 +1400,8 @@ msgid "Node Name:"
msgstr ""
#: editor/editor_autoload_settings.cpp editor/editor_help_search.cpp
-#: editor/editor_profiler.cpp editor/settings_config_dialog.cpp
+#: editor/editor_profiler.cpp editor/project_manager.cpp
+#: editor/settings_config_dialog.cpp
msgid "Name"
msgstr ""
@@ -9092,6 +9093,10 @@ msgid "Projects"
msgstr ""
#: editor/project_manager.cpp
+msgid "Last Modified"
+msgstr ""
+
+#: editor/project_manager.cpp
msgid "Scan"
msgstr ""
diff --git a/editor/translations/el.po b/editor/translations/el.po
index 7aea9126c6..969f63fbd1 100644
--- a/editor/translations/el.po
+++ b/editor/translations/el.po
@@ -982,7 +982,7 @@ msgid "Resource"
msgstr "Πόρος"
#: editor/dependency_editor.cpp editor/editor_autoload_settings.cpp
-#: editor/project_settings_editor.cpp
+#: editor/project_manager.cpp editor/project_settings_editor.cpp
msgid "Path"
msgstr "Διαδρομή"
@@ -1457,7 +1457,8 @@ msgid "Node Name:"
msgstr "Όνομα κόμβου:"
#: editor/editor_autoload_settings.cpp editor/editor_help_search.cpp
-#: editor/editor_profiler.cpp editor/settings_config_dialog.cpp
+#: editor/editor_profiler.cpp editor/project_manager.cpp
+#: editor/settings_config_dialog.cpp
msgid "Name"
msgstr "Όνομα"
@@ -9593,6 +9594,10 @@ msgid "Projects"
msgstr "Έργο"
#: editor/project_manager.cpp
+msgid "Last Modified"
+msgstr ""
+
+#: editor/project_manager.cpp
msgid "Scan"
msgstr "Σάρωση"
diff --git a/editor/translations/eo.po b/editor/translations/eo.po
index 13b053c4f8..8ce8f7c298 100644
--- a/editor/translations/eo.po
+++ b/editor/translations/eo.po
@@ -971,7 +971,7 @@ msgid "Resource"
msgstr "Rimedo"
#: editor/dependency_editor.cpp editor/editor_autoload_settings.cpp
-#: editor/project_settings_editor.cpp
+#: editor/project_manager.cpp editor/project_settings_editor.cpp
msgid "Path"
msgstr "dosierindiko"
@@ -1436,7 +1436,8 @@ msgid "Node Name:"
msgstr ""
#: editor/editor_autoload_settings.cpp editor/editor_help_search.cpp
-#: editor/editor_profiler.cpp editor/settings_config_dialog.cpp
+#: editor/editor_profiler.cpp editor/project_manager.cpp
+#: editor/settings_config_dialog.cpp
msgid "Name"
msgstr "Nomo"
@@ -9217,6 +9218,11 @@ msgid "Projects"
msgstr "Projektoj"
#: editor/project_manager.cpp
+#, fuzzy
+msgid "Last Modified"
+msgstr "Modifita"
+
+#: editor/project_manager.cpp
msgid "Scan"
msgstr "Esplori"
diff --git a/editor/translations/es.po b/editor/translations/es.po
index a520f0c46e..0c04cb5fff 100644
--- a/editor/translations/es.po
+++ b/editor/translations/es.po
@@ -1013,7 +1013,7 @@ msgid "Resource"
msgstr "Recursos"
#: editor/dependency_editor.cpp editor/editor_autoload_settings.cpp
-#: editor/project_settings_editor.cpp
+#: editor/project_manager.cpp editor/project_settings_editor.cpp
msgid "Path"
msgstr "Ruta"
@@ -1486,7 +1486,8 @@ msgid "Node Name:"
msgstr "Nombre del Nodo:"
#: editor/editor_autoload_settings.cpp editor/editor_help_search.cpp
-#: editor/editor_profiler.cpp editor/settings_config_dialog.cpp
+#: editor/editor_profiler.cpp editor/project_manager.cpp
+#: editor/settings_config_dialog.cpp
msgid "Name"
msgstr "Nombre"
@@ -9549,6 +9550,11 @@ msgid "Projects"
msgstr "Proyectos"
#: editor/project_manager.cpp
+#, fuzzy
+msgid "Last Modified"
+msgstr "Modificado/s"
+
+#: editor/project_manager.cpp
msgid "Scan"
msgstr "Escanear"
diff --git a/editor/translations/es_AR.po b/editor/translations/es_AR.po
index 0bf176e0af..eea6a6da6b 100644
--- a/editor/translations/es_AR.po
+++ b/editor/translations/es_AR.po
@@ -982,7 +982,7 @@ msgid "Resource"
msgstr "Recursos"
#: editor/dependency_editor.cpp editor/editor_autoload_settings.cpp
-#: editor/project_settings_editor.cpp
+#: editor/project_manager.cpp editor/project_settings_editor.cpp
msgid "Path"
msgstr "Ruta"
@@ -1455,7 +1455,8 @@ msgid "Node Name:"
msgstr "Nombre de Nodo:"
#: editor/editor_autoload_settings.cpp editor/editor_help_search.cpp
-#: editor/editor_profiler.cpp editor/settings_config_dialog.cpp
+#: editor/editor_profiler.cpp editor/project_manager.cpp
+#: editor/settings_config_dialog.cpp
msgid "Name"
msgstr "Nombre"
@@ -9514,6 +9515,11 @@ msgid "Projects"
msgstr "Proyectos"
#: editor/project_manager.cpp
+#, fuzzy
+msgid "Last Modified"
+msgstr "Modificado/s"
+
+#: editor/project_manager.cpp
msgid "Scan"
msgstr "Examinar"
diff --git a/editor/translations/et.po b/editor/translations/et.po
index 82bf543b18..05e6e4fb73 100644
--- a/editor/translations/et.po
+++ b/editor/translations/et.po
@@ -943,7 +943,7 @@ msgid "Resource"
msgstr ""
#: editor/dependency_editor.cpp editor/editor_autoload_settings.cpp
-#: editor/project_settings_editor.cpp
+#: editor/project_manager.cpp editor/project_settings_editor.cpp
msgid "Path"
msgstr ""
@@ -1408,7 +1408,8 @@ msgid "Node Name:"
msgstr ""
#: editor/editor_autoload_settings.cpp editor/editor_help_search.cpp
-#: editor/editor_profiler.cpp editor/settings_config_dialog.cpp
+#: editor/editor_profiler.cpp editor/project_manager.cpp
+#: editor/settings_config_dialog.cpp
msgid "Name"
msgstr ""
@@ -9114,6 +9115,10 @@ msgid "Projects"
msgstr ""
#: editor/project_manager.cpp
+msgid "Last Modified"
+msgstr ""
+
+#: editor/project_manager.cpp
msgid "Scan"
msgstr ""
diff --git a/editor/translations/eu.po b/editor/translations/eu.po
index a545199e07..af877a08a2 100644
--- a/editor/translations/eu.po
+++ b/editor/translations/eu.po
@@ -3,18 +3,19 @@
# Copyright (c) 2014-2019 Godot Engine contributors (cf. AUTHORS.md)
# This file is distributed under the same license as the Godot source code.
# Julen Irazoki <rktzbkr.julen@gmail.com>, 2019.
+# Osoitz <oelkoro@gmail.com>, 2019.
msgid ""
msgstr ""
"Project-Id-Version: Godot Engine editor\n"
-"PO-Revision-Date: 2019-08-15 10:23+0000\n"
-"Last-Translator: Julen Irazoki <rktzbkr.julen@gmail.com>\n"
+"PO-Revision-Date: 2019-12-03 14:05+0000\n"
+"Last-Translator: Osoitz <oelkoro@gmail.com>\n"
"Language-Team: Basque <https://hosted.weblate.org/projects/godot-engine/"
"godot/eu/>\n"
"Language: eu\n"
"Content-Type: text/plain; charset=UTF-8\n"
"Content-Transfer-Encoding: 8-bit\n"
"Plural-Forms: nplurals=2; plural=n != 1;\n"
-"X-Generator: Weblate 3.8\n"
+"X-Generator: Weblate 3.10-dev\n"
#: core/math/expression.cpp modules/gdscript/gdscript_functions.cpp
#: modules/visual_script/visual_script_builtin_funcs.cpp
@@ -25,8 +26,7 @@ msgstr ""
#: modules/mono/glue/gd_glue.cpp
#: modules/visual_script/visual_script_builtin_funcs.cpp
msgid "Not enough bytes for decoding bytes, or invalid format."
-msgstr ""
-"Ez daude byte nahikoa byte-ak dekodetzeko, edota formatua ez da zuzena."
+msgstr "Ez daude byte nahikoa byteak deskodetzeko, edo formatua ez da zuzena."
#: core/math/expression.cpp
msgid "Invalid input %i (not passed) in expression"
@@ -940,7 +940,7 @@ msgid "Resource"
msgstr ""
#: editor/dependency_editor.cpp editor/editor_autoload_settings.cpp
-#: editor/project_settings_editor.cpp
+#: editor/project_manager.cpp editor/project_settings_editor.cpp
msgid "Path"
msgstr ""
@@ -1405,7 +1405,8 @@ msgid "Node Name:"
msgstr ""
#: editor/editor_autoload_settings.cpp editor/editor_help_search.cpp
-#: editor/editor_profiler.cpp editor/settings_config_dialog.cpp
+#: editor/editor_profiler.cpp editor/project_manager.cpp
+#: editor/settings_config_dialog.cpp
msgid "Name"
msgstr ""
@@ -9097,6 +9098,10 @@ msgid "Projects"
msgstr ""
#: editor/project_manager.cpp
+msgid "Last Modified"
+msgstr ""
+
+#: editor/project_manager.cpp
msgid "Scan"
msgstr ""
diff --git a/editor/translations/fa.po b/editor/translations/fa.po
index 6ec85e861e..2376b0ac59 100644
--- a/editor/translations/fa.po
+++ b/editor/translations/fa.po
@@ -1009,7 +1009,7 @@ msgid "Resource"
msgstr "منبع"
#: editor/dependency_editor.cpp editor/editor_autoload_settings.cpp
-#: editor/project_settings_editor.cpp
+#: editor/project_manager.cpp editor/project_settings_editor.cpp
msgid "Path"
msgstr "مسیر"
@@ -1490,7 +1490,8 @@ msgid "Node Name:"
msgstr "نام گره:"
#: editor/editor_autoload_settings.cpp editor/editor_help_search.cpp
-#: editor/editor_profiler.cpp editor/settings_config_dialog.cpp
+#: editor/editor_profiler.cpp editor/project_manager.cpp
+#: editor/settings_config_dialog.cpp
msgid "Name"
msgstr ""
@@ -9644,6 +9645,10 @@ msgid "Projects"
msgstr "پروژه"
#: editor/project_manager.cpp
+msgid "Last Modified"
+msgstr ""
+
+#: editor/project_manager.cpp
msgid "Scan"
msgstr "پویش"
diff --git a/editor/translations/fi.po b/editor/translations/fi.po
index 517733d566..dd1d867ae2 100644
--- a/editor/translations/fi.po
+++ b/editor/translations/fi.po
@@ -967,7 +967,7 @@ msgid "Resource"
msgstr "Resurssi"
#: editor/dependency_editor.cpp editor/editor_autoload_settings.cpp
-#: editor/project_settings_editor.cpp
+#: editor/project_manager.cpp editor/project_settings_editor.cpp
msgid "Path"
msgstr "Polku"
@@ -1442,7 +1442,8 @@ msgid "Node Name:"
msgstr "Solmun nimi:"
#: editor/editor_autoload_settings.cpp editor/editor_help_search.cpp
-#: editor/editor_profiler.cpp editor/settings_config_dialog.cpp
+#: editor/editor_profiler.cpp editor/project_manager.cpp
+#: editor/settings_config_dialog.cpp
msgid "Name"
msgstr "Nimi"
@@ -9462,6 +9463,11 @@ msgid "Projects"
msgstr "Projektit"
#: editor/project_manager.cpp
+#, fuzzy
+msgid "Last Modified"
+msgstr "Muutettu"
+
+#: editor/project_manager.cpp
msgid "Scan"
msgstr "Tutki"
diff --git a/editor/translations/fil.po b/editor/translations/fil.po
index 6c9950261b..3568aed2ea 100644
--- a/editor/translations/fil.po
+++ b/editor/translations/fil.po
@@ -947,7 +947,7 @@ msgid "Resource"
msgstr ""
#: editor/dependency_editor.cpp editor/editor_autoload_settings.cpp
-#: editor/project_settings_editor.cpp
+#: editor/project_manager.cpp editor/project_settings_editor.cpp
msgid "Path"
msgstr ""
@@ -1412,7 +1412,8 @@ msgid "Node Name:"
msgstr ""
#: editor/editor_autoload_settings.cpp editor/editor_help_search.cpp
-#: editor/editor_profiler.cpp editor/settings_config_dialog.cpp
+#: editor/editor_profiler.cpp editor/project_manager.cpp
+#: editor/settings_config_dialog.cpp
msgid "Name"
msgstr ""
@@ -9113,6 +9114,10 @@ msgid "Projects"
msgstr ""
#: editor/project_manager.cpp
+msgid "Last Modified"
+msgstr ""
+
+#: editor/project_manager.cpp
msgid "Scan"
msgstr ""
diff --git a/editor/translations/fr.po b/editor/translations/fr.po
index 423452a065..23b73c25b0 100644
--- a/editor/translations/fr.po
+++ b/editor/translations/fr.po
@@ -68,12 +68,13 @@
# Xavier Sellier <contact@binogure-studio.com>, 2019.
# Sofiane <Sofiane-77@caramail.fr>, 2019.
# Camille Mohr-Daurat <pouleyketchoup@gmail.com>, 2019.
+# Pierre Stempin <pierre.stempin@gmail.com>, 2019.
msgid ""
msgstr ""
"Project-Id-Version: Godot Engine editor\n"
"POT-Creation-Date: \n"
-"PO-Revision-Date: 2019-11-29 14:49+0000\n"
-"Last-Translator: Camille Mohr-Daurat <pouleyketchoup@gmail.com>\n"
+"PO-Revision-Date: 2019-12-03 14:05+0000\n"
+"Last-Translator: Pierre Stempin <pierre.stempin@gmail.com>\n"
"Language-Team: French <https://hosted.weblate.org/projects/godot-engine/"
"godot/fr/>\n"
"Language: fr\n"
@@ -1040,7 +1041,7 @@ msgid "Resource"
msgstr "Ressource"
#: editor/dependency_editor.cpp editor/editor_autoload_settings.cpp
-#: editor/project_settings_editor.cpp
+#: editor/project_manager.cpp editor/project_settings_editor.cpp
msgid "Path"
msgstr "Chemin"
@@ -1515,7 +1516,8 @@ msgid "Node Name:"
msgstr "Nom de nœud :"
#: editor/editor_autoload_settings.cpp editor/editor_help_search.cpp
-#: editor/editor_profiler.cpp editor/settings_config_dialog.cpp
+#: editor/editor_profiler.cpp editor/project_manager.cpp
+#: editor/settings_config_dialog.cpp
msgid "Name"
msgstr "Nom"
@@ -6298,7 +6300,7 @@ msgstr "Déplacer de points"
#: editor/plugins/polygon_2d_editor_plugin.cpp
msgid "Ctrl: Rotate"
-msgstr "Contrôle : Tourner"
+msgstr "Ctrl : Tourner"
#: editor/plugins/polygon_2d_editor_plugin.cpp
msgid "Shift: Move All"
@@ -9051,7 +9053,6 @@ msgstr ""
"et de la direction de la caméra (transmettez-lui les entrées associées)."
#: editor/plugins/visual_shader_editor_plugin.cpp
-#, fuzzy
msgid ""
"Custom Godot Shader Language expression, which is placed on top of the "
"resulted shader. You can place various function definitions inside and call "
@@ -9608,6 +9609,11 @@ msgid "Projects"
msgstr "Projets"
#: editor/project_manager.cpp
+#, fuzzy
+msgid "Last Modified"
+msgstr "Modifié"
+
+#: editor/project_manager.cpp
msgid "Scan"
msgstr "Scanner"
@@ -11436,7 +11442,6 @@ msgstr ""
"fonctions."
#: modules/visual_script/visual_script_editor.cpp
-#, fuzzy
msgid "Select at least one node with sequence port."
msgstr "Sélectionnez au moins un nœud avec un port de séquence."
diff --git a/editor/translations/ga.po b/editor/translations/ga.po
index 0994c769e1..8b96d258ad 100644
--- a/editor/translations/ga.po
+++ b/editor/translations/ga.po
@@ -941,7 +941,7 @@ msgid "Resource"
msgstr "Acmhainn"
#: editor/dependency_editor.cpp editor/editor_autoload_settings.cpp
-#: editor/project_settings_editor.cpp
+#: editor/project_manager.cpp editor/project_settings_editor.cpp
msgid "Path"
msgstr "Cosán"
@@ -1406,7 +1406,8 @@ msgid "Node Name:"
msgstr ""
#: editor/editor_autoload_settings.cpp editor/editor_help_search.cpp
-#: editor/editor_profiler.cpp editor/settings_config_dialog.cpp
+#: editor/editor_profiler.cpp editor/project_manager.cpp
+#: editor/settings_config_dialog.cpp
msgid "Name"
msgstr ""
@@ -9107,6 +9108,10 @@ msgid "Projects"
msgstr ""
#: editor/project_manager.cpp
+msgid "Last Modified"
+msgstr ""
+
+#: editor/project_manager.cpp
msgid "Scan"
msgstr ""
diff --git a/editor/translations/he.po b/editor/translations/he.po
index b438d8656d..db308bff70 100644
--- a/editor/translations/he.po
+++ b/editor/translations/he.po
@@ -1006,7 +1006,7 @@ msgid "Resource"
msgstr "משאב"
#: editor/dependency_editor.cpp editor/editor_autoload_settings.cpp
-#: editor/project_settings_editor.cpp
+#: editor/project_manager.cpp editor/project_settings_editor.cpp
msgid "Path"
msgstr "נתיב"
@@ -1483,7 +1483,8 @@ msgid "Node Name:"
msgstr "שם המפרק:"
#: editor/editor_autoload_settings.cpp editor/editor_help_search.cpp
-#: editor/editor_profiler.cpp editor/settings_config_dialog.cpp
+#: editor/editor_profiler.cpp editor/project_manager.cpp
+#: editor/settings_config_dialog.cpp
msgid "Name"
msgstr "שם"
@@ -9610,6 +9611,10 @@ msgid "Projects"
msgstr "מיזם"
#: editor/project_manager.cpp
+msgid "Last Modified"
+msgstr ""
+
+#: editor/project_manager.cpp
msgid "Scan"
msgstr ""
diff --git a/editor/translations/hi.po b/editor/translations/hi.po
index 5ea73e6e98..267e705a88 100644
--- a/editor/translations/hi.po
+++ b/editor/translations/hi.po
@@ -1000,7 +1000,7 @@ msgid "Resource"
msgstr "संसाधन"
#: editor/dependency_editor.cpp editor/editor_autoload_settings.cpp
-#: editor/project_settings_editor.cpp
+#: editor/project_manager.cpp editor/project_settings_editor.cpp
msgid "Path"
msgstr "पथ"
@@ -1489,7 +1489,8 @@ msgid "Node Name:"
msgstr ""
#: editor/editor_autoload_settings.cpp editor/editor_help_search.cpp
-#: editor/editor_profiler.cpp editor/settings_config_dialog.cpp
+#: editor/editor_profiler.cpp editor/project_manager.cpp
+#: editor/settings_config_dialog.cpp
msgid "Name"
msgstr ""
@@ -9357,6 +9358,10 @@ msgid "Projects"
msgstr "परियोजना के संस्थापक"
#: editor/project_manager.cpp
+msgid "Last Modified"
+msgstr ""
+
+#: editor/project_manager.cpp
msgid "Scan"
msgstr ""
diff --git a/editor/translations/hr.po b/editor/translations/hr.po
index 5467aa1523..33566267a1 100644
--- a/editor/translations/hr.po
+++ b/editor/translations/hr.po
@@ -952,7 +952,7 @@ msgid "Resource"
msgstr "Resurs"
#: editor/dependency_editor.cpp editor/editor_autoload_settings.cpp
-#: editor/project_settings_editor.cpp
+#: editor/project_manager.cpp editor/project_settings_editor.cpp
msgid "Path"
msgstr ""
@@ -1420,7 +1420,8 @@ msgid "Node Name:"
msgstr ""
#: editor/editor_autoload_settings.cpp editor/editor_help_search.cpp
-#: editor/editor_profiler.cpp editor/settings_config_dialog.cpp
+#: editor/editor_profiler.cpp editor/project_manager.cpp
+#: editor/settings_config_dialog.cpp
msgid "Name"
msgstr ""
@@ -9138,6 +9139,10 @@ msgid "Projects"
msgstr ""
#: editor/project_manager.cpp
+msgid "Last Modified"
+msgstr ""
+
+#: editor/project_manager.cpp
msgid "Scan"
msgstr ""
diff --git a/editor/translations/hu.po b/editor/translations/hu.po
index 0f20323033..244d3c903e 100644
--- a/editor/translations/hu.po
+++ b/editor/translations/hu.po
@@ -1019,7 +1019,7 @@ msgid "Resource"
msgstr "Forrás"
#: editor/dependency_editor.cpp editor/editor_autoload_settings.cpp
-#: editor/project_settings_editor.cpp
+#: editor/project_manager.cpp editor/project_settings_editor.cpp
msgid "Path"
msgstr "Útvonal"
@@ -1504,7 +1504,8 @@ msgid "Node Name:"
msgstr "Node neve:"
#: editor/editor_autoload_settings.cpp editor/editor_help_search.cpp
-#: editor/editor_profiler.cpp editor/settings_config_dialog.cpp
+#: editor/editor_profiler.cpp editor/project_manager.cpp
+#: editor/settings_config_dialog.cpp
msgid "Name"
msgstr "Név"
@@ -9802,6 +9803,10 @@ msgid "Projects"
msgstr "Projekt"
#: editor/project_manager.cpp
+msgid "Last Modified"
+msgstr ""
+
+#: editor/project_manager.cpp
msgid "Scan"
msgstr ""
diff --git a/editor/translations/id.po b/editor/translations/id.po
index cf2c3bb271..68edb05284 100644
--- a/editor/translations/id.po
+++ b/editor/translations/id.po
@@ -987,7 +987,7 @@ msgid "Resource"
msgstr "Resource"
#: editor/dependency_editor.cpp editor/editor_autoload_settings.cpp
-#: editor/project_settings_editor.cpp
+#: editor/project_manager.cpp editor/project_settings_editor.cpp
msgid "Path"
msgstr "Path"
@@ -1459,7 +1459,8 @@ msgid "Node Name:"
msgstr "Nama Node:"
#: editor/editor_autoload_settings.cpp editor/editor_help_search.cpp
-#: editor/editor_profiler.cpp editor/settings_config_dialog.cpp
+#: editor/editor_profiler.cpp editor/project_manager.cpp
+#: editor/settings_config_dialog.cpp
msgid "Name"
msgstr "Nama"
@@ -9500,6 +9501,10 @@ msgid "Projects"
msgstr "Proyek"
#: editor/project_manager.cpp
+msgid "Last Modified"
+msgstr ""
+
+#: editor/project_manager.cpp
msgid "Scan"
msgstr "Pindai"
diff --git a/editor/translations/is.po b/editor/translations/is.po
index 6f06c5a142..50e5bfac37 100644
--- a/editor/translations/is.po
+++ b/editor/translations/is.po
@@ -974,7 +974,7 @@ msgid "Resource"
msgstr ""
#: editor/dependency_editor.cpp editor/editor_autoload_settings.cpp
-#: editor/project_settings_editor.cpp
+#: editor/project_manager.cpp editor/project_settings_editor.cpp
msgid "Path"
msgstr ""
@@ -1440,7 +1440,8 @@ msgid "Node Name:"
msgstr ""
#: editor/editor_autoload_settings.cpp editor/editor_help_search.cpp
-#: editor/editor_profiler.cpp editor/settings_config_dialog.cpp
+#: editor/editor_profiler.cpp editor/project_manager.cpp
+#: editor/settings_config_dialog.cpp
msgid "Name"
msgstr ""
@@ -9211,6 +9212,10 @@ msgid "Projects"
msgstr "Verkefna Stjóri"
#: editor/project_manager.cpp
+msgid "Last Modified"
+msgstr ""
+
+#: editor/project_manager.cpp
msgid "Scan"
msgstr ""
diff --git a/editor/translations/it.po b/editor/translations/it.po
index 642723f8bb..77b9437753 100644
--- a/editor/translations/it.po
+++ b/editor/translations/it.po
@@ -1005,7 +1005,7 @@ msgid "Resource"
msgstr "Risorsa"
#: editor/dependency_editor.cpp editor/editor_autoload_settings.cpp
-#: editor/project_settings_editor.cpp
+#: editor/project_manager.cpp editor/project_settings_editor.cpp
msgid "Path"
msgstr "Percorso"
@@ -1479,7 +1479,8 @@ msgid "Node Name:"
msgstr "Nome nodo:"
#: editor/editor_autoload_settings.cpp editor/editor_help_search.cpp
-#: editor/editor_profiler.cpp editor/settings_config_dialog.cpp
+#: editor/editor_profiler.cpp editor/project_manager.cpp
+#: editor/settings_config_dialog.cpp
msgid "Name"
msgstr "Nome"
@@ -9560,6 +9561,11 @@ msgid "Projects"
msgstr "Progetti"
#: editor/project_manager.cpp
+#, fuzzy
+msgid "Last Modified"
+msgstr "Modificato"
+
+#: editor/project_manager.cpp
msgid "Scan"
msgstr "Esamina"
diff --git a/editor/translations/ja.po b/editor/translations/ja.po
index de6d6822ca..a5697f71d9 100644
--- a/editor/translations/ja.po
+++ b/editor/translations/ja.po
@@ -993,7 +993,7 @@ msgid "Resource"
msgstr "リソース"
#: editor/dependency_editor.cpp editor/editor_autoload_settings.cpp
-#: editor/project_settings_editor.cpp
+#: editor/project_manager.cpp editor/project_settings_editor.cpp
msgid "Path"
msgstr "パス"
@@ -1465,7 +1465,8 @@ msgid "Node Name:"
msgstr "ノード名:"
#: editor/editor_autoload_settings.cpp editor/editor_help_search.cpp
-#: editor/editor_profiler.cpp editor/settings_config_dialog.cpp
+#: editor/editor_profiler.cpp editor/project_manager.cpp
+#: editor/settings_config_dialog.cpp
msgid "Name"
msgstr "名前"
@@ -9517,6 +9518,11 @@ msgid "Projects"
msgstr "プロジェクト"
#: editor/project_manager.cpp
+#, fuzzy
+msgid "Last Modified"
+msgstr "変更された箇所"
+
+#: editor/project_manager.cpp
msgid "Scan"
msgstr "スキャン"
diff --git a/editor/translations/ka.po b/editor/translations/ka.po
index 839ad533f5..d4710402f2 100644
--- a/editor/translations/ka.po
+++ b/editor/translations/ka.po
@@ -1012,7 +1012,7 @@ msgid "Resource"
msgstr "რესურსი"
#: editor/dependency_editor.cpp editor/editor_autoload_settings.cpp
-#: editor/project_settings_editor.cpp
+#: editor/project_manager.cpp editor/project_settings_editor.cpp
msgid "Path"
msgstr "გზა"
@@ -1492,7 +1492,8 @@ msgid "Node Name:"
msgstr ""
#: editor/editor_autoload_settings.cpp editor/editor_help_search.cpp
-#: editor/editor_profiler.cpp editor/settings_config_dialog.cpp
+#: editor/editor_profiler.cpp editor/project_manager.cpp
+#: editor/settings_config_dialog.cpp
msgid "Name"
msgstr ""
@@ -9389,6 +9390,10 @@ msgid "Projects"
msgstr "პროექტის დამფუძნებლები"
#: editor/project_manager.cpp
+msgid "Last Modified"
+msgstr ""
+
+#: editor/project_manager.cpp
msgid "Scan"
msgstr ""
diff --git a/editor/translations/ko.po b/editor/translations/ko.po
index 63fd0fe16c..3aac1a2e39 100644
--- a/editor/translations/ko.po
+++ b/editor/translations/ko.po
@@ -974,7 +974,7 @@ msgid "Resource"
msgstr "리소스"
#: editor/dependency_editor.cpp editor/editor_autoload_settings.cpp
-#: editor/project_settings_editor.cpp
+#: editor/project_manager.cpp editor/project_settings_editor.cpp
msgid "Path"
msgstr "경로"
@@ -1444,7 +1444,8 @@ msgid "Node Name:"
msgstr "노드 이름:"
#: editor/editor_autoload_settings.cpp editor/editor_help_search.cpp
-#: editor/editor_profiler.cpp editor/settings_config_dialog.cpp
+#: editor/editor_profiler.cpp editor/project_manager.cpp
+#: editor/settings_config_dialog.cpp
msgid "Name"
msgstr "이름"
@@ -9389,6 +9390,11 @@ msgid "Projects"
msgstr "프로젝트"
#: editor/project_manager.cpp
+#, fuzzy
+msgid "Last Modified"
+msgstr "수정됨"
+
+#: editor/project_manager.cpp
msgid "Scan"
msgstr "스캔"
diff --git a/editor/translations/lt.po b/editor/translations/lt.po
index 681bae9d5a..5971331785 100644
--- a/editor/translations/lt.po
+++ b/editor/translations/lt.po
@@ -989,7 +989,7 @@ msgid "Resource"
msgstr ""
#: editor/dependency_editor.cpp editor/editor_autoload_settings.cpp
-#: editor/project_settings_editor.cpp
+#: editor/project_manager.cpp editor/project_settings_editor.cpp
msgid "Path"
msgstr ""
@@ -1455,7 +1455,8 @@ msgid "Node Name:"
msgstr ""
#: editor/editor_autoload_settings.cpp editor/editor_help_search.cpp
-#: editor/editor_profiler.cpp editor/settings_config_dialog.cpp
+#: editor/editor_profiler.cpp editor/project_manager.cpp
+#: editor/settings_config_dialog.cpp
msgid "Name"
msgstr ""
@@ -9380,6 +9381,10 @@ msgid "Projects"
msgstr ""
#: editor/project_manager.cpp
+msgid "Last Modified"
+msgstr ""
+
+#: editor/project_manager.cpp
msgid "Scan"
msgstr ""
diff --git a/editor/translations/lv.po b/editor/translations/lv.po
index a0b68a3a64..97c80f9a22 100644
--- a/editor/translations/lv.po
+++ b/editor/translations/lv.po
@@ -976,7 +976,7 @@ msgid "Resource"
msgstr "Resurs"
#: editor/dependency_editor.cpp editor/editor_autoload_settings.cpp
-#: editor/project_settings_editor.cpp
+#: editor/project_manager.cpp editor/project_settings_editor.cpp
msgid "Path"
msgstr ""
@@ -1464,7 +1464,8 @@ msgid "Node Name:"
msgstr ""
#: editor/editor_autoload_settings.cpp editor/editor_help_search.cpp
-#: editor/editor_profiler.cpp editor/settings_config_dialog.cpp
+#: editor/editor_profiler.cpp editor/project_manager.cpp
+#: editor/settings_config_dialog.cpp
msgid "Name"
msgstr "Nosaukums"
@@ -9346,6 +9347,10 @@ msgid "Projects"
msgstr "Projekta Dibinātāji"
#: editor/project_manager.cpp
+msgid "Last Modified"
+msgstr ""
+
+#: editor/project_manager.cpp
msgid "Scan"
msgstr ""
diff --git a/editor/translations/mi.po b/editor/translations/mi.po
index dbd85cdd3a..693a0f1535 100644
--- a/editor/translations/mi.po
+++ b/editor/translations/mi.po
@@ -933,7 +933,7 @@ msgid "Resource"
msgstr ""
#: editor/dependency_editor.cpp editor/editor_autoload_settings.cpp
-#: editor/project_settings_editor.cpp
+#: editor/project_manager.cpp editor/project_settings_editor.cpp
msgid "Path"
msgstr ""
@@ -1398,7 +1398,8 @@ msgid "Node Name:"
msgstr ""
#: editor/editor_autoload_settings.cpp editor/editor_help_search.cpp
-#: editor/editor_profiler.cpp editor/settings_config_dialog.cpp
+#: editor/editor_profiler.cpp editor/project_manager.cpp
+#: editor/settings_config_dialog.cpp
msgid "Name"
msgstr ""
@@ -9090,6 +9091,10 @@ msgid "Projects"
msgstr ""
#: editor/project_manager.cpp
+msgid "Last Modified"
+msgstr ""
+
+#: editor/project_manager.cpp
msgid "Scan"
msgstr ""
diff --git a/editor/translations/ml.po b/editor/translations/ml.po
index 255a961ea7..0ea1566617 100644
--- a/editor/translations/ml.po
+++ b/editor/translations/ml.po
@@ -943,7 +943,7 @@ msgid "Resource"
msgstr ""
#: editor/dependency_editor.cpp editor/editor_autoload_settings.cpp
-#: editor/project_settings_editor.cpp
+#: editor/project_manager.cpp editor/project_settings_editor.cpp
msgid "Path"
msgstr ""
@@ -1408,7 +1408,8 @@ msgid "Node Name:"
msgstr ""
#: editor/editor_autoload_settings.cpp editor/editor_help_search.cpp
-#: editor/editor_profiler.cpp editor/settings_config_dialog.cpp
+#: editor/editor_profiler.cpp editor/project_manager.cpp
+#: editor/settings_config_dialog.cpp
msgid "Name"
msgstr ""
@@ -9103,6 +9104,10 @@ msgid "Projects"
msgstr ""
#: editor/project_manager.cpp
+msgid "Last Modified"
+msgstr ""
+
+#: editor/project_manager.cpp
msgid "Scan"
msgstr ""
diff --git a/editor/translations/ms.po b/editor/translations/ms.po
index 7ff31a456c..cef1d6dcc0 100644
--- a/editor/translations/ms.po
+++ b/editor/translations/ms.po
@@ -961,7 +961,7 @@ msgid "Resource"
msgstr ""
#: editor/dependency_editor.cpp editor/editor_autoload_settings.cpp
-#: editor/project_settings_editor.cpp
+#: editor/project_manager.cpp editor/project_settings_editor.cpp
msgid "Path"
msgstr ""
@@ -1426,7 +1426,8 @@ msgid "Node Name:"
msgstr ""
#: editor/editor_autoload_settings.cpp editor/editor_help_search.cpp
-#: editor/editor_profiler.cpp editor/settings_config_dialog.cpp
+#: editor/editor_profiler.cpp editor/project_manager.cpp
+#: editor/settings_config_dialog.cpp
msgid "Name"
msgstr ""
@@ -9159,6 +9160,10 @@ msgid "Projects"
msgstr ""
#: editor/project_manager.cpp
+msgid "Last Modified"
+msgstr ""
+
+#: editor/project_manager.cpp
msgid "Scan"
msgstr ""
diff --git a/editor/translations/nb.po b/editor/translations/nb.po
index b7422a2f92..59a2d5553d 100644
--- a/editor/translations/nb.po
+++ b/editor/translations/nb.po
@@ -1027,7 +1027,7 @@ msgid "Resource"
msgstr "Ressurs"
#: editor/dependency_editor.cpp editor/editor_autoload_settings.cpp
-#: editor/project_settings_editor.cpp
+#: editor/project_manager.cpp editor/project_settings_editor.cpp
msgid "Path"
msgstr "Bane"
@@ -1518,7 +1518,8 @@ msgid "Node Name:"
msgstr "Nodenavn:"
#: editor/editor_autoload_settings.cpp editor/editor_help_search.cpp
-#: editor/editor_profiler.cpp editor/settings_config_dialog.cpp
+#: editor/editor_profiler.cpp editor/project_manager.cpp
+#: editor/settings_config_dialog.cpp
msgid "Name"
msgstr "Navn"
@@ -9891,6 +9892,10 @@ msgid "Projects"
msgstr "Prosjekt"
#: editor/project_manager.cpp
+msgid "Last Modified"
+msgstr ""
+
+#: editor/project_manager.cpp
msgid "Scan"
msgstr "Skann"
diff --git a/editor/translations/nl.po b/editor/translations/nl.po
index 10d32da522..3f5fb5908a 100644
--- a/editor/translations/nl.po
+++ b/editor/translations/nl.po
@@ -1007,7 +1007,7 @@ msgid "Resource"
msgstr "Bron"
#: editor/dependency_editor.cpp editor/editor_autoload_settings.cpp
-#: editor/project_settings_editor.cpp
+#: editor/project_manager.cpp editor/project_settings_editor.cpp
msgid "Path"
msgstr "Pad"
@@ -1481,7 +1481,8 @@ msgid "Node Name:"
msgstr "Node Naam:"
#: editor/editor_autoload_settings.cpp editor/editor_help_search.cpp
-#: editor/editor_profiler.cpp editor/settings_config_dialog.cpp
+#: editor/editor_profiler.cpp editor/project_manager.cpp
+#: editor/settings_config_dialog.cpp
msgid "Name"
msgstr "Naam"
@@ -9777,6 +9778,10 @@ msgid "Projects"
msgstr "Project"
#: editor/project_manager.cpp
+msgid "Last Modified"
+msgstr ""
+
+#: editor/project_manager.cpp
msgid "Scan"
msgstr "Scannen"
diff --git a/editor/translations/or.po b/editor/translations/or.po
index 6b52bb709a..9585062994 100644
--- a/editor/translations/or.po
+++ b/editor/translations/or.po
@@ -939,7 +939,7 @@ msgid "Resource"
msgstr ""
#: editor/dependency_editor.cpp editor/editor_autoload_settings.cpp
-#: editor/project_settings_editor.cpp
+#: editor/project_manager.cpp editor/project_settings_editor.cpp
msgid "Path"
msgstr ""
@@ -1404,7 +1404,8 @@ msgid "Node Name:"
msgstr ""
#: editor/editor_autoload_settings.cpp editor/editor_help_search.cpp
-#: editor/editor_profiler.cpp editor/settings_config_dialog.cpp
+#: editor/editor_profiler.cpp editor/project_manager.cpp
+#: editor/settings_config_dialog.cpp
msgid "Name"
msgstr ""
@@ -9096,6 +9097,10 @@ msgid "Projects"
msgstr ""
#: editor/project_manager.cpp
+msgid "Last Modified"
+msgstr ""
+
+#: editor/project_manager.cpp
msgid "Scan"
msgstr ""
diff --git a/editor/translations/pl.po b/editor/translations/pl.po
index fc8ae9f5dc..43b4580dd8 100644
--- a/editor/translations/pl.po
+++ b/editor/translations/pl.po
@@ -1002,7 +1002,7 @@ msgid "Resource"
msgstr "Zasoby"
#: editor/dependency_editor.cpp editor/editor_autoload_settings.cpp
-#: editor/project_settings_editor.cpp
+#: editor/project_manager.cpp editor/project_settings_editor.cpp
msgid "Path"
msgstr "Ścieżka"
@@ -1473,7 +1473,8 @@ msgid "Node Name:"
msgstr "Nazwa węzła:"
#: editor/editor_autoload_settings.cpp editor/editor_help_search.cpp
-#: editor/editor_profiler.cpp editor/settings_config_dialog.cpp
+#: editor/editor_profiler.cpp editor/project_manager.cpp
+#: editor/settings_config_dialog.cpp
msgid "Name"
msgstr "Nazwa"
@@ -9498,6 +9499,11 @@ msgid "Projects"
msgstr "Projekty"
#: editor/project_manager.cpp
+#, fuzzy
+msgid "Last Modified"
+msgstr "Zmodyfikowany"
+
+#: editor/project_manager.cpp
msgid "Scan"
msgstr "Skanuj"
diff --git a/editor/translations/pr.po b/editor/translations/pr.po
index f20178f8bb..fc619b3da7 100644
--- a/editor/translations/pr.po
+++ b/editor/translations/pr.po
@@ -981,7 +981,7 @@ msgid "Resource"
msgstr ""
#: editor/dependency_editor.cpp editor/editor_autoload_settings.cpp
-#: editor/project_settings_editor.cpp
+#: editor/project_manager.cpp editor/project_settings_editor.cpp
msgid "Path"
msgstr ""
@@ -1451,7 +1451,8 @@ msgid "Node Name:"
msgstr ""
#: editor/editor_autoload_settings.cpp editor/editor_help_search.cpp
-#: editor/editor_profiler.cpp editor/settings_config_dialog.cpp
+#: editor/editor_profiler.cpp editor/project_manager.cpp
+#: editor/settings_config_dialog.cpp
msgid "Name"
msgstr ""
@@ -9400,6 +9401,10 @@ msgid "Projects"
msgstr "Rename Function"
#: editor/project_manager.cpp
+msgid "Last Modified"
+msgstr ""
+
+#: editor/project_manager.cpp
msgid "Scan"
msgstr ""
diff --git a/editor/translations/pt_BR.po b/editor/translations/pt_BR.po
index 88953ef6e5..8ec43fd0e0 100644
--- a/editor/translations/pt_BR.po
+++ b/editor/translations/pt_BR.po
@@ -76,7 +76,7 @@ msgid ""
msgstr ""
"Project-Id-Version: Godot Engine editor\n"
"POT-Creation-Date: 2016-05-30\n"
-"PO-Revision-Date: 2019-11-20 14:07+0000\n"
+"PO-Revision-Date: 2019-12-03 14:05+0000\n"
"Last-Translator: Joaquim Ferreira <joaquimferreira1996@bol.com.br>\n"
"Language-Team: Portuguese (Brazil) <https://hosted.weblate.org/projects/"
"godot-engine/godot/pt_BR/>\n"
@@ -1037,7 +1037,7 @@ msgid "Resource"
msgstr "Recurso"
#: editor/dependency_editor.cpp editor/editor_autoload_settings.cpp
-#: editor/project_settings_editor.cpp
+#: editor/project_manager.cpp editor/project_settings_editor.cpp
msgid "Path"
msgstr "Caminho"
@@ -1509,7 +1509,8 @@ msgid "Node Name:"
msgstr "Nome do nó:"
#: editor/editor_autoload_settings.cpp editor/editor_help_search.cpp
-#: editor/editor_profiler.cpp editor/settings_config_dialog.cpp
+#: editor/editor_profiler.cpp editor/project_manager.cpp
+#: editor/settings_config_dialog.cpp
msgid "Name"
msgstr "Nome"
@@ -2130,7 +2131,7 @@ msgstr "Nó"
#: editor/editor_network_profiler.cpp
msgid "Incoming RPC"
-msgstr "Incoming RPC"
+msgstr "RPC recebido"
#: editor/editor_network_profiler.cpp
msgid "Incoming RSET"
@@ -2952,7 +2953,7 @@ msgstr "Tocar"
#: editor/editor_node.cpp
msgid "Pause the scene execution for debugging."
-msgstr ""
+msgstr "Pausar a execução da cena para depuração."
#: editor/editor_node.cpp
msgid "Pause Scene"
@@ -3043,6 +3044,14 @@ msgid ""
"the \"Use Custom Build\" option should be enabled in the Android export "
"preset."
msgstr ""
+"Isso irá configurar seu projeto para compilações customizadas do Android "
+"instalando o modelo de origem para \"res://android/build\".\n"
+"Em seguida, você pode aplicar modificações e compilar seu próprio APK "
+"customizado na exportação (Adicionando módulos, alterando o AndroidManifest."
+"xml, etc.).\n"
+"Note que para fazer uma compilação customizada, em vez de usar APKs pre-"
+"compilados, a opção \"Usar compilação customizada\" deve estar ativa nas "
+"predefinições de exportação do Android."
#: editor/editor_node.cpp
#, fuzzy
@@ -4390,9 +4399,8 @@ msgid "Audio Clips"
msgstr "Clipes de Áudio:"
#: editor/plugins/animation_blend_tree_editor_plugin.cpp
-#, fuzzy
msgid "Functions"
-msgstr "Funções:"
+msgstr "Funções"
#: editor/plugins/animation_blend_tree_editor_plugin.cpp
#: editor/plugins/animation_state_machine_editor.cpp
@@ -5077,7 +5085,7 @@ msgstr "Passo de grade:"
#: editor/plugins/canvas_item_editor_plugin.cpp
msgid "Primary Line Every:"
-msgstr ""
+msgstr "Linha Primária a Cada:"
#: editor/plugins/canvas_item_editor_plugin.cpp
#, fuzzy
@@ -5188,6 +5196,8 @@ msgid ""
"Game Camera Override\n"
"Overrides game camera with editor viewport camera."
msgstr ""
+"Substituir Câmera do Jogo\n"
+"Substitui a câmera do jogo com a câmera de visualização do editor."
#: editor/plugins/canvas_item_editor_plugin.cpp
#: editor/plugins/spatial_editor_plugin.cpp
@@ -5195,6 +5205,8 @@ msgid ""
"Game Camera Override\n"
"No game instance running."
msgstr ""
+"Substituir Câmera do Jogo\n"
+"Nenhuma instância de jogo em execução."
#: editor/plugins/canvas_item_editor_plugin.cpp
#: editor/plugins/spatial_editor_plugin.cpp
@@ -7810,7 +7822,7 @@ msgstr "Filtrar Arquivos..."
#: editor/plugins/tile_map_editor_plugin.cpp
msgid "Give a TileSet resource to this TileMap to use its tiles."
-msgstr ""
+msgstr "Atribua um recurso TileSet a este TileMap para usar seus tiles."
#: editor/plugins/tile_map_editor_plugin.cpp
msgid "Paint Tile"
@@ -7948,6 +7960,8 @@ msgstr "Exibir nomes de mosaico (segure a tecla Alt)"
msgid ""
"Add or select a texture on the left panel to edit the tiles bound to it."
msgstr ""
+"Adicione ou selecione uma textura no painel esquerdo para editar os tiles "
+"vinculados."
#: editor/plugins/tile_set_editor_plugin.cpp
msgid "Remove selected texture? This will remove all tiles which use it."
@@ -8135,7 +8149,7 @@ msgstr "Nenhum nome fornecido"
#: editor/plugins/version_control_editor_plugin.cpp
msgid "No files added to stage"
-msgstr ""
+msgstr "Nenhum arquivo adicionado ao palco"
#: editor/plugins/version_control_editor_plugin.cpp
#, fuzzy
@@ -8144,11 +8158,11 @@ msgstr "Comunidade"
#: editor/plugins/version_control_editor_plugin.cpp
msgid "VCS Addon is not initialized"
-msgstr ""
+msgstr "Extensão VCS não inicializado"
#: editor/plugins/version_control_editor_plugin.cpp
msgid "Version Control System"
-msgstr ""
+msgstr "Sistema de Controle de Versionamento"
#: editor/plugins/version_control_editor_plugin.cpp
#, fuzzy
@@ -8157,7 +8171,7 @@ msgstr "Capitalizar"
#: editor/plugins/version_control_editor_plugin.cpp
msgid "Staging area"
-msgstr ""
+msgstr "Área Temporária"
#: editor/plugins/version_control_editor_plugin.cpp
#, fuzzy
@@ -8200,7 +8214,7 @@ msgstr "Salvar Tudo"
#: editor/plugins/version_control_editor_plugin.cpp
msgid "Add a commit message"
-msgstr ""
+msgstr "Adicione uma mensagem de confirmação"
#: editor/plugins/version_control_editor_plugin.cpp
#, fuzzy
@@ -8214,7 +8228,7 @@ msgstr "Estado"
#: editor/plugins/version_control_editor_plugin.cpp
msgid "View file diffs before committing them to the latest version"
-msgstr ""
+msgstr "Ver aquivos diff antes do commit para a última versão"
#: editor/plugins/version_control_editor_plugin.cpp
#, fuzzy
@@ -8223,7 +8237,7 @@ msgstr "Nenhum arquivo selecionado!"
#: editor/plugins/version_control_editor_plugin.cpp
msgid "Detect changes in file diff"
-msgstr ""
+msgstr "Detectar mudanças no arquivo diff"
#: editor/plugins/visual_shader_editor_plugin.cpp
msgid "(GLES3 only)"
@@ -8761,14 +8775,12 @@ msgid "Multiplies scalar by scalar."
msgstr "Multiplica escalar por escalar."
#: editor/plugins/visual_shader_editor_plugin.cpp
-#, fuzzy
msgid "Returns the remainder of the two scalars."
-msgstr "Retorna o resto de dois escalares."
+msgstr "Retorna o resto dos dois escalares."
#: editor/plugins/visual_shader_editor_plugin.cpp
-#, fuzzy
msgid "Subtracts scalar from scalar."
-msgstr "Subtrai escalar de escalar."
+msgstr "Subtrai o escalar do escalar."
#: editor/plugins/visual_shader_editor_plugin.cpp
#, fuzzy
@@ -8781,9 +8793,8 @@ msgid "Scalar uniform."
msgstr "Alterar Uniforme Escalar"
#: editor/plugins/visual_shader_editor_plugin.cpp
-#, fuzzy
msgid "Perform the cubic texture lookup."
-msgstr "Faça a pesquisa da textura cúbica."
+msgstr "Execute a pesquisa de textura cúbica."
#: editor/plugins/visual_shader_editor_plugin.cpp
#, fuzzy
@@ -8852,14 +8863,12 @@ msgid "Calculates the transpose of a transform."
msgstr "(Somente em GLES3) Calcula a transposta da transform."
#: editor/plugins/visual_shader_editor_plugin.cpp
-#, fuzzy
msgid "Multiplies transform by transform."
-msgstr "Multiplica transform por transform."
+msgstr "Multiplica a transformação por transformação."
#: editor/plugins/visual_shader_editor_plugin.cpp
-#, fuzzy
msgid "Multiplies vector by transform."
-msgstr "Multiplica vetor por transform."
+msgstr "Multiplica vetor por transformação."
#: editor/plugins/visual_shader_editor_plugin.cpp
#, fuzzy
@@ -9062,50 +9071,64 @@ msgid ""
"it later in the Expressions. You can also declare varyings, uniforms and "
"constants."
msgstr ""
+"Expressão customizada da Godot Shader Language, que é colocada em cima do "
+"shader resultante. Você pode colocar várias definições de funções dentro e "
+"chamá-lo posteriormente nas Expressões. Você também pode declarar variações, "
+"uniformes e constantes."
#: editor/plugins/visual_shader_editor_plugin.cpp
msgid "(Fragment/Light mode only) Scalar derivative function."
-msgstr ""
+msgstr "(Apenas modo Fragmento/Luz) Função derivada escalar."
#: editor/plugins/visual_shader_editor_plugin.cpp
msgid "(Fragment/Light mode only) Vector derivative function."
-msgstr ""
+msgstr "(Apenas modo Fragmento/Luz) Função derivada de vetor."
#: editor/plugins/visual_shader_editor_plugin.cpp
msgid ""
"(Fragment/Light mode only) (Vector) Derivative in 'x' using local "
"differencing."
msgstr ""
+"(Apenas modo Fragmento/Luz) (Vetor) Derivada em 'x' usando diferenciação "
+"local."
#: editor/plugins/visual_shader_editor_plugin.cpp
msgid ""
"(Fragment/Light mode only) (Scalar) Derivative in 'x' using local "
"differencing."
msgstr ""
+"(Apenas modo Fragmento/Luz) (Escalar) Derivada em 'x' usando diferenciação "
+"local."
#: editor/plugins/visual_shader_editor_plugin.cpp
msgid ""
"(Fragment/Light mode only) (Vector) Derivative in 'y' using local "
"differencing."
msgstr ""
+"(Apenas modo Fragmento/Luz) (Vetor) Derivada em 'y' usando diferenciação "
+"local."
#: editor/plugins/visual_shader_editor_plugin.cpp
msgid ""
"(Fragment/Light mode only) (Scalar) Derivative in 'y' using local "
"differencing."
msgstr ""
+"(Apenas modo Fragmento/Luz) (Escalar) Derivada em 'y' usando diferenciação "
+"local."
#: editor/plugins/visual_shader_editor_plugin.cpp
msgid ""
"(Fragment/Light mode only) (Vector) Sum of absolute derivative in 'x' and "
"'y'."
msgstr ""
+"(Apenas modo Fragmento/Luz) (Vetor) Soma da derivada absoluta em 'x' e 'y'."
#: editor/plugins/visual_shader_editor_plugin.cpp
msgid ""
"(Fragment/Light mode only) (Scalar) Sum of absolute derivative in 'x' and "
"'y'."
msgstr ""
+"(Apenas modo Fragmento/Luz) (Escalar) Soma da derivada absoluta em 'x' e 'y'."
#: editor/plugins/visual_shader_editor_plugin.cpp
msgid "VisualShader"
@@ -9180,6 +9203,9 @@ msgid ""
"If checked, the preset will be available for use in one-click deploy.\n"
"Only one preset per platform may be marked as runnable."
msgstr ""
+"Se marcada, a predefinição estará disponível para uso na implantação em um "
+"clique.\n"
+"Somente uma predefinição por plataforma pode ser marcada como executável."
#: editor/project_export.cpp
msgid "Export Path"
@@ -9461,7 +9487,7 @@ msgstr "Importar Projeto Existente"
#: editor/project_manager.cpp
msgid "Error: Project is missing on the filesystem."
-msgstr ""
+msgstr "Erro: O Projeto está ausente no sistema de arquivos."
#: editor/project_manager.cpp
msgid "Can't open project at '%s'."
@@ -9595,6 +9621,11 @@ msgid "Projects"
msgstr "Projeto"
#: editor/project_manager.cpp
+#, fuzzy
+msgid "Last Modified"
+msgstr "Modificado"
+
+#: editor/project_manager.cpp
msgid "Scan"
msgstr "Escanear"
@@ -9950,7 +9981,7 @@ msgstr "Idiomas:"
#: editor/project_settings_editor.cpp
msgid "AutoLoad"
-msgstr "AutoLoad"
+msgstr "Carregamento Automático"
#: editor/project_settings_editor.cpp
msgid "Plugins"
@@ -10244,7 +10275,7 @@ msgstr "Deletar Nó(s) de Shader Graph(s)"
#: editor/scene_tree_dock.cpp
msgid "Delete node \"%s\" and its children?"
-msgstr ""
+msgstr "Deletar nó \"%s\" e seus filhos?"
#: editor/scene_tree_dock.cpp
#, fuzzy
@@ -10746,9 +10777,8 @@ msgid "Profiler"
msgstr "Profilador"
#: editor/script_editor_debugger.cpp
-#, fuzzy
msgid "Network Profiler"
-msgstr "Exportar Perfil"
+msgstr "Perfis de rede"
#: editor/script_editor_debugger.cpp
msgid "Monitor"
@@ -10951,9 +10981,8 @@ msgid "GDNativeLibrary"
msgstr "GDNativeLibrary"
#: modules/gdnative/gdnative_library_singleton_editor.cpp
-#, fuzzy
msgid "Enabled GDNative Singleton"
-msgstr "Singleton GDBNative ativado"
+msgstr "Singleton GDNative ativado"
#: modules/gdnative/gdnative_library_singleton_editor.cpp
#, fuzzy
@@ -10974,7 +11003,7 @@ msgstr "GDNative"
#: modules/gdscript/gdscript_functions.cpp
msgid "Expected a string of length 1 (a character)."
-msgstr ""
+msgstr "Esperado string de comprimento 1 (a caractere)."
#: modules/gdscript/gdscript_functions.cpp
msgid "Step argument is zero!"
@@ -11138,7 +11167,7 @@ msgstr "Métodos de filtragem"
#: modules/gridmap/grid_map_editor_plugin.cpp
msgid "Give a MeshLibrary resource to this GridMap to use its meshes."
-msgstr ""
+msgstr "Atribua um recurso MeshLibrary a este GridMap para usar seus meshes."
#: modules/mono/csharp_script.cpp
msgid "Class name can't be a reserved keyword"
@@ -11396,6 +11425,7 @@ msgstr "Adicionar Nó de Pré-carregamento"
#: modules/visual_script/visual_script_editor.cpp
msgid "Can't drop nodes because script '%s' is not used in this scene."
msgstr ""
+"Não é possível descartar nós porque o script '% s' não é usado nesta cena."
#: modules/visual_script/visual_script_editor.cpp
msgid "Add Node(s) From Tree"
@@ -11406,6 +11436,9 @@ msgid ""
"Can't drop properties because script '%s' is not used in this scene.\n"
"Drop holding 'Shift' to just copy the signature."
msgstr ""
+"Não é possível descartar as propriedades porque o script '% s' não é usado "
+"nesta cena.\n"
+"Solte segurando 'Shift' para copiar apenas a assinatura."
#: modules/visual_script/visual_script_editor.cpp
msgid "Add Getter Property"
@@ -11476,14 +11509,15 @@ msgstr "Não é possível copiar o nó de função."
#: modules/visual_script/visual_script_editor.cpp
msgid "Can't create function of nodes from nodes of multiple functions."
msgstr ""
+"Não é possível criar uma função de nós a partir de nós de múltiplas funções."
#: modules/visual_script/visual_script_editor.cpp
msgid "Select at least one node with sequence port."
-msgstr ""
+msgstr "Selecione pelo menos um nó com porta de sequência."
#: modules/visual_script/visual_script_editor.cpp
msgid "Try to only have one sequence input in selection."
-msgstr ""
+msgstr "Tente ter apenas uma entrada de sequência na seleção."
#: modules/visual_script/visual_script_editor.cpp
#, fuzzy
@@ -11677,10 +11711,14 @@ msgstr ""
#: platform/android/export/export.cpp
msgid "Custom build requires a valid Android SDK path in Editor Settings."
msgstr ""
+"Compilação personalizada requer um caminho do Android SDK válido para as "
+"Configurações do Editor."
#: platform/android/export/export.cpp
msgid "Invalid Android SDK path for custom build in Editor Settings."
msgstr ""
+"Caminho SDK do Android inválido para a compilação personalizada nas "
+"Configurações do Editor."
#: platform/android/export/export.cpp
#, fuzzy
@@ -11704,6 +11742,9 @@ msgid ""
"Trying to build from a custom built template, but no version info for it "
"exists. Please reinstall from the 'Project' menu."
msgstr ""
+"Tentando compilar a partir de um modelo compilado personalizado, mas nenhuma "
+"informação de versão para ele existe. Por favor, reinstale pelo menu "
+"'Projeto'."
#: platform/android/export/export.cpp
msgid ""
@@ -11712,6 +11753,10 @@ msgid ""
" Godot Version: %s\n"
"Please reinstall Android build template from 'Project' menu."
msgstr ""
+"Diferença de versão da compilação do Android:\n"
+" Modelo instalado: %s\n"
+" Versão do Godot: %s\n"
+"Por favor reinstale o modelo de compilação do Android pelo menu 'Projeto'."
#: platform/android/export/export.cpp
msgid "Building Android Project (gradle)"
@@ -12406,6 +12451,9 @@ msgid ""
"The Hint Tooltip won't be displayed as the control's Mouse Filter is set to "
"\"Ignore\". To solve this, set the Mouse Filter to \"Stop\" or \"Pass\"."
msgstr ""
+"A Dica não será exibida quando o controle de Filtro do Mouse estiver "
+"definido como \"Ignorar\". Para resolver, defina o Filtro do Mouse como "
+"\"Parar\" ou \"Continuar\"."
#: scene/gui/dialogs.cpp
msgid "Alert!"
diff --git a/editor/translations/pt_PT.po b/editor/translations/pt_PT.po
index 03976ebf0c..f739893486 100644
--- a/editor/translations/pt_PT.po
+++ b/editor/translations/pt_PT.po
@@ -979,7 +979,7 @@ msgid "Resource"
msgstr "Recurso"
#: editor/dependency_editor.cpp editor/editor_autoload_settings.cpp
-#: editor/project_settings_editor.cpp
+#: editor/project_manager.cpp editor/project_settings_editor.cpp
msgid "Path"
msgstr "Caminho"
@@ -1452,7 +1452,8 @@ msgid "Node Name:"
msgstr "Nome do Nó:"
#: editor/editor_autoload_settings.cpp editor/editor_help_search.cpp
-#: editor/editor_profiler.cpp editor/settings_config_dialog.cpp
+#: editor/editor_profiler.cpp editor/project_manager.cpp
+#: editor/settings_config_dialog.cpp
msgid "Name"
msgstr "Nome"
@@ -9467,6 +9468,11 @@ msgid "Projects"
msgstr "Projetos"
#: editor/project_manager.cpp
+#, fuzzy
+msgid "Last Modified"
+msgstr "Modificado"
+
+#: editor/project_manager.cpp
msgid "Scan"
msgstr "Analisar"
diff --git a/editor/translations/ro.po b/editor/translations/ro.po
index 266f95691e..f16520008f 100644
--- a/editor/translations/ro.po
+++ b/editor/translations/ro.po
@@ -1012,7 +1012,7 @@ msgid "Resource"
msgstr "Resursă"
#: editor/dependency_editor.cpp editor/editor_autoload_settings.cpp
-#: editor/project_settings_editor.cpp
+#: editor/project_manager.cpp editor/project_settings_editor.cpp
msgid "Path"
msgstr "Cale"
@@ -1502,7 +1502,8 @@ msgid "Node Name:"
msgstr "Nume Nod:"
#: editor/editor_autoload_settings.cpp editor/editor_help_search.cpp
-#: editor/editor_profiler.cpp editor/settings_config_dialog.cpp
+#: editor/editor_profiler.cpp editor/project_manager.cpp
+#: editor/settings_config_dialog.cpp
msgid "Name"
msgstr "Nume"
@@ -9773,6 +9774,10 @@ msgid "Projects"
msgstr "Proiect"
#: editor/project_manager.cpp
+msgid "Last Modified"
+msgstr ""
+
+#: editor/project_manager.cpp
msgid "Scan"
msgstr ""
diff --git a/editor/translations/ru.po b/editor/translations/ru.po
index 0f8b7da452..3cfe0f6353 100644
--- a/editor/translations/ru.po
+++ b/editor/translations/ru.po
@@ -1028,7 +1028,7 @@ msgid "Resource"
msgstr "Ресурс"
#: editor/dependency_editor.cpp editor/editor_autoload_settings.cpp
-#: editor/project_settings_editor.cpp
+#: editor/project_manager.cpp editor/project_settings_editor.cpp
msgid "Path"
msgstr "Путь"
@@ -1499,7 +1499,8 @@ msgid "Node Name:"
msgstr "Имя Узла:"
#: editor/editor_autoload_settings.cpp editor/editor_help_search.cpp
-#: editor/editor_profiler.cpp editor/settings_config_dialog.cpp
+#: editor/editor_profiler.cpp editor/project_manager.cpp
+#: editor/settings_config_dialog.cpp
msgid "Name"
msgstr "Название"
@@ -9544,6 +9545,11 @@ msgid "Projects"
msgstr "Проекты"
#: editor/project_manager.cpp
+#, fuzzy
+msgid "Last Modified"
+msgstr "Изменён"
+
+#: editor/project_manager.cpp
msgid "Scan"
msgstr "Сканировать"
diff --git a/editor/translations/si.po b/editor/translations/si.po
index 85973b455c..357ae506ad 100644
--- a/editor/translations/si.po
+++ b/editor/translations/si.po
@@ -962,7 +962,7 @@ msgid "Resource"
msgstr ""
#: editor/dependency_editor.cpp editor/editor_autoload_settings.cpp
-#: editor/project_settings_editor.cpp
+#: editor/project_manager.cpp editor/project_settings_editor.cpp
msgid "Path"
msgstr ""
@@ -1427,7 +1427,8 @@ msgid "Node Name:"
msgstr ""
#: editor/editor_autoload_settings.cpp editor/editor_help_search.cpp
-#: editor/editor_profiler.cpp editor/settings_config_dialog.cpp
+#: editor/editor_profiler.cpp editor/project_manager.cpp
+#: editor/settings_config_dialog.cpp
msgid "Name"
msgstr ""
@@ -9162,6 +9163,10 @@ msgid "Projects"
msgstr ""
#: editor/project_manager.cpp
+msgid "Last Modified"
+msgstr ""
+
+#: editor/project_manager.cpp
msgid "Scan"
msgstr ""
diff --git a/editor/translations/sk.po b/editor/translations/sk.po
index 62811488f9..ec290311e0 100644
--- a/editor/translations/sk.po
+++ b/editor/translations/sk.po
@@ -985,7 +985,7 @@ msgid "Resource"
msgstr "Prostriedok"
#: editor/dependency_editor.cpp editor/editor_autoload_settings.cpp
-#: editor/project_settings_editor.cpp
+#: editor/project_manager.cpp editor/project_settings_editor.cpp
msgid "Path"
msgstr "Cesta"
@@ -1461,7 +1461,8 @@ msgid "Node Name:"
msgstr ""
#: editor/editor_autoload_settings.cpp editor/editor_help_search.cpp
-#: editor/editor_profiler.cpp editor/settings_config_dialog.cpp
+#: editor/editor_profiler.cpp editor/project_manager.cpp
+#: editor/settings_config_dialog.cpp
msgid "Name"
msgstr ""
@@ -9430,6 +9431,10 @@ msgid "Projects"
msgstr "Zakladatelia Projektu"
#: editor/project_manager.cpp
+msgid "Last Modified"
+msgstr ""
+
+#: editor/project_manager.cpp
msgid "Scan"
msgstr ""
diff --git a/editor/translations/sl.po b/editor/translations/sl.po
index 238d4da365..ad23f0c63b 100644
--- a/editor/translations/sl.po
+++ b/editor/translations/sl.po
@@ -1023,7 +1023,7 @@ msgid "Resource"
msgstr "Viri"
#: editor/dependency_editor.cpp editor/editor_autoload_settings.cpp
-#: editor/project_settings_editor.cpp
+#: editor/project_manager.cpp editor/project_settings_editor.cpp
msgid "Path"
msgstr "Pot"
@@ -1509,7 +1509,8 @@ msgid "Node Name:"
msgstr "Ime Gradnika:"
#: editor/editor_autoload_settings.cpp editor/editor_help_search.cpp
-#: editor/editor_profiler.cpp editor/settings_config_dialog.cpp
+#: editor/editor_profiler.cpp editor/project_manager.cpp
+#: editor/settings_config_dialog.cpp
msgid "Name"
msgstr "Ime"
@@ -9747,6 +9748,10 @@ msgid "Projects"
msgstr "Projekt"
#: editor/project_manager.cpp
+msgid "Last Modified"
+msgstr ""
+
+#: editor/project_manager.cpp
msgid "Scan"
msgstr "Preglej"
diff --git a/editor/translations/sq.po b/editor/translations/sq.po
index 49b45241ed..1c78705413 100644
--- a/editor/translations/sq.po
+++ b/editor/translations/sq.po
@@ -962,7 +962,7 @@ msgid "Resource"
msgstr "Resursi"
#: editor/dependency_editor.cpp editor/editor_autoload_settings.cpp
-#: editor/project_settings_editor.cpp
+#: editor/project_manager.cpp editor/project_settings_editor.cpp
msgid "Path"
msgstr "Rrugë"
@@ -1446,7 +1446,8 @@ msgid "Node Name:"
msgstr "Emri i Nyjes:"
#: editor/editor_autoload_settings.cpp editor/editor_help_search.cpp
-#: editor/editor_profiler.cpp editor/settings_config_dialog.cpp
+#: editor/editor_profiler.cpp editor/project_manager.cpp
+#: editor/settings_config_dialog.cpp
msgid "Name"
msgstr "Emri"
@@ -9411,6 +9412,10 @@ msgid "Projects"
msgstr "Projekti"
#: editor/project_manager.cpp
+msgid "Last Modified"
+msgstr ""
+
+#: editor/project_manager.cpp
msgid "Scan"
msgstr ""
diff --git a/editor/translations/sr_Cyrl.po b/editor/translations/sr_Cyrl.po
index e868067d39..24eb88b805 100644
--- a/editor/translations/sr_Cyrl.po
+++ b/editor/translations/sr_Cyrl.po
@@ -1023,7 +1023,7 @@ msgid "Resource"
msgstr "Ресурс"
#: editor/dependency_editor.cpp editor/editor_autoload_settings.cpp
-#: editor/project_settings_editor.cpp
+#: editor/project_manager.cpp editor/project_settings_editor.cpp
msgid "Path"
msgstr "Пут"
@@ -1510,7 +1510,8 @@ msgid "Node Name:"
msgstr "Име чвора:"
#: editor/editor_autoload_settings.cpp editor/editor_help_search.cpp
-#: editor/editor_profiler.cpp editor/settings_config_dialog.cpp
+#: editor/editor_profiler.cpp editor/project_manager.cpp
+#: editor/settings_config_dialog.cpp
msgid "Name"
msgstr "Име"
@@ -9866,6 +9867,10 @@ msgid "Projects"
msgstr "Пројекат"
#: editor/project_manager.cpp
+msgid "Last Modified"
+msgstr ""
+
+#: editor/project_manager.cpp
msgid "Scan"
msgstr ""
diff --git a/editor/translations/sr_Latn.po b/editor/translations/sr_Latn.po
index e4298b2aa5..22b3059a68 100644
--- a/editor/translations/sr_Latn.po
+++ b/editor/translations/sr_Latn.po
@@ -971,7 +971,7 @@ msgid "Resource"
msgstr ""
#: editor/dependency_editor.cpp editor/editor_autoload_settings.cpp
-#: editor/project_settings_editor.cpp
+#: editor/project_manager.cpp editor/project_settings_editor.cpp
msgid "Path"
msgstr ""
@@ -1436,7 +1436,8 @@ msgid "Node Name:"
msgstr ""
#: editor/editor_autoload_settings.cpp editor/editor_help_search.cpp
-#: editor/editor_profiler.cpp editor/settings_config_dialog.cpp
+#: editor/editor_profiler.cpp editor/project_manager.cpp
+#: editor/settings_config_dialog.cpp
msgid "Name"
msgstr ""
@@ -9234,6 +9235,10 @@ msgid "Projects"
msgstr ""
#: editor/project_manager.cpp
+msgid "Last Modified"
+msgstr ""
+
+#: editor/project_manager.cpp
msgid "Scan"
msgstr ""
diff --git a/editor/translations/sv.po b/editor/translations/sv.po
index c1cc6a8a62..02197303ce 100644
--- a/editor/translations/sv.po
+++ b/editor/translations/sv.po
@@ -1010,7 +1010,7 @@ msgid "Resource"
msgstr "Resurs"
#: editor/dependency_editor.cpp editor/editor_autoload_settings.cpp
-#: editor/project_settings_editor.cpp
+#: editor/project_manager.cpp editor/project_settings_editor.cpp
msgid "Path"
msgstr "Sökväg"
@@ -1501,7 +1501,8 @@ msgid "Node Name:"
msgstr "Node Namn:"
#: editor/editor_autoload_settings.cpp editor/editor_help_search.cpp
-#: editor/editor_profiler.cpp editor/settings_config_dialog.cpp
+#: editor/editor_profiler.cpp editor/project_manager.cpp
+#: editor/settings_config_dialog.cpp
msgid "Name"
msgstr "Namn"
@@ -9690,6 +9691,10 @@ msgid "Projects"
msgstr "Projekt"
#: editor/project_manager.cpp
+msgid "Last Modified"
+msgstr ""
+
+#: editor/project_manager.cpp
msgid "Scan"
msgstr "Skanna"
diff --git a/editor/translations/ta.po b/editor/translations/ta.po
index 5035e886c5..7015199f0c 100644
--- a/editor/translations/ta.po
+++ b/editor/translations/ta.po
@@ -963,7 +963,7 @@ msgid "Resource"
msgstr ""
#: editor/dependency_editor.cpp editor/editor_autoload_settings.cpp
-#: editor/project_settings_editor.cpp
+#: editor/project_manager.cpp editor/project_settings_editor.cpp
msgid "Path"
msgstr ""
@@ -1428,7 +1428,8 @@ msgid "Node Name:"
msgstr ""
#: editor/editor_autoload_settings.cpp editor/editor_help_search.cpp
-#: editor/editor_profiler.cpp editor/settings_config_dialog.cpp
+#: editor/editor_profiler.cpp editor/project_manager.cpp
+#: editor/settings_config_dialog.cpp
msgid "Name"
msgstr ""
@@ -9166,6 +9167,10 @@ msgid "Projects"
msgstr ""
#: editor/project_manager.cpp
+msgid "Last Modified"
+msgstr ""
+
+#: editor/project_manager.cpp
msgid "Scan"
msgstr ""
diff --git a/editor/translations/te.po b/editor/translations/te.po
index 4ad5ae8777..d9136f04b0 100644
--- a/editor/translations/te.po
+++ b/editor/translations/te.po
@@ -941,7 +941,7 @@ msgid "Resource"
msgstr ""
#: editor/dependency_editor.cpp editor/editor_autoload_settings.cpp
-#: editor/project_settings_editor.cpp
+#: editor/project_manager.cpp editor/project_settings_editor.cpp
msgid "Path"
msgstr ""
@@ -1406,7 +1406,8 @@ msgid "Node Name:"
msgstr ""
#: editor/editor_autoload_settings.cpp editor/editor_help_search.cpp
-#: editor/editor_profiler.cpp editor/settings_config_dialog.cpp
+#: editor/editor_profiler.cpp editor/project_manager.cpp
+#: editor/settings_config_dialog.cpp
msgid "Name"
msgstr ""
@@ -9099,6 +9100,10 @@ msgid "Projects"
msgstr ""
#: editor/project_manager.cpp
+msgid "Last Modified"
+msgstr ""
+
+#: editor/project_manager.cpp
msgid "Scan"
msgstr ""
diff --git a/editor/translations/th.po b/editor/translations/th.po
index af1bb53b9e..db9cd3f577 100644
--- a/editor/translations/th.po
+++ b/editor/translations/th.po
@@ -1025,7 +1025,7 @@ msgid "Resource"
msgstr "รีซอร์ส"
#: editor/dependency_editor.cpp editor/editor_autoload_settings.cpp
-#: editor/project_settings_editor.cpp
+#: editor/project_manager.cpp editor/project_settings_editor.cpp
msgid "Path"
msgstr "ตำแหน่ง"
@@ -1508,7 +1508,8 @@ msgid "Node Name:"
msgstr "ชื่อโหนด:"
#: editor/editor_autoload_settings.cpp editor/editor_help_search.cpp
-#: editor/editor_profiler.cpp editor/settings_config_dialog.cpp
+#: editor/editor_profiler.cpp editor/project_manager.cpp
+#: editor/settings_config_dialog.cpp
msgid "Name"
msgstr "ชื่อ"
@@ -9820,6 +9821,10 @@ msgid "Projects"
msgstr "โปรเจกต์"
#: editor/project_manager.cpp
+msgid "Last Modified"
+msgstr ""
+
+#: editor/project_manager.cpp
msgid "Scan"
msgstr "สแกน"
diff --git a/editor/translations/tr.po b/editor/translations/tr.po
index 6ef831b3be..1cbce49f6d 100644
--- a/editor/translations/tr.po
+++ b/editor/translations/tr.po
@@ -1005,7 +1005,7 @@ msgid "Resource"
msgstr "Kaynak"
#: editor/dependency_editor.cpp editor/editor_autoload_settings.cpp
-#: editor/project_settings_editor.cpp
+#: editor/project_manager.cpp editor/project_settings_editor.cpp
msgid "Path"
msgstr "Yol"
@@ -1477,7 +1477,8 @@ msgid "Node Name:"
msgstr "Düğüm adı:"
#: editor/editor_autoload_settings.cpp editor/editor_help_search.cpp
-#: editor/editor_profiler.cpp editor/settings_config_dialog.cpp
+#: editor/editor_profiler.cpp editor/project_manager.cpp
+#: editor/settings_config_dialog.cpp
msgid "Name"
msgstr "İsim"
@@ -9460,6 +9461,11 @@ msgid "Projects"
msgstr "Proje"
#: editor/project_manager.cpp
+#, fuzzy
+msgid "Last Modified"
+msgstr "Değişti"
+
+#: editor/project_manager.cpp
msgid "Scan"
msgstr "Tara"
diff --git a/editor/translations/uk.po b/editor/translations/uk.po
index 881e8f1911..1b8d883ca1 100644
--- a/editor/translations/uk.po
+++ b/editor/translations/uk.po
@@ -981,7 +981,7 @@ msgid "Resource"
msgstr "Ресурс"
#: editor/dependency_editor.cpp editor/editor_autoload_settings.cpp
-#: editor/project_settings_editor.cpp
+#: editor/project_manager.cpp editor/project_settings_editor.cpp
msgid "Path"
msgstr "Шлях"
@@ -1454,7 +1454,8 @@ msgid "Node Name:"
msgstr "Ім'я Вузла:"
#: editor/editor_autoload_settings.cpp editor/editor_help_search.cpp
-#: editor/editor_profiler.cpp editor/settings_config_dialog.cpp
+#: editor/editor_profiler.cpp editor/project_manager.cpp
+#: editor/settings_config_dialog.cpp
msgid "Name"
msgstr "Назва"
@@ -9497,6 +9498,11 @@ msgid "Projects"
msgstr "Проєкти"
#: editor/project_manager.cpp
+#, fuzzy
+msgid "Last Modified"
+msgstr "Змінено"
+
+#: editor/project_manager.cpp
msgid "Scan"
msgstr "Сканувати"
diff --git a/editor/translations/ur_PK.po b/editor/translations/ur_PK.po
index 74a0013d39..e0c20b597a 100644
--- a/editor/translations/ur_PK.po
+++ b/editor/translations/ur_PK.po
@@ -959,7 +959,7 @@ msgid "Resource"
msgstr ""
#: editor/dependency_editor.cpp editor/editor_autoload_settings.cpp
-#: editor/project_settings_editor.cpp
+#: editor/project_manager.cpp editor/project_settings_editor.cpp
msgid "Path"
msgstr ""
@@ -1429,7 +1429,8 @@ msgid "Node Name:"
msgstr ""
#: editor/editor_autoload_settings.cpp editor/editor_help_search.cpp
-#: editor/editor_profiler.cpp editor/settings_config_dialog.cpp
+#: editor/editor_profiler.cpp editor/project_manager.cpp
+#: editor/settings_config_dialog.cpp
msgid "Name"
msgstr ""
@@ -9317,6 +9318,10 @@ msgid "Projects"
msgstr ".تمام کا انتخاب"
#: editor/project_manager.cpp
+msgid "Last Modified"
+msgstr ""
+
+#: editor/project_manager.cpp
msgid "Scan"
msgstr ""
diff --git a/editor/translations/vi.po b/editor/translations/vi.po
index d92251b862..c20e09409b 100644
--- a/editor/translations/vi.po
+++ b/editor/translations/vi.po
@@ -978,7 +978,7 @@ msgid "Resource"
msgstr "Tài nguyên"
#: editor/dependency_editor.cpp editor/editor_autoload_settings.cpp
-#: editor/project_settings_editor.cpp
+#: editor/project_manager.cpp editor/project_settings_editor.cpp
msgid "Path"
msgstr "Đường dẫn"
@@ -1452,7 +1452,8 @@ msgid "Node Name:"
msgstr "Tên Node:"
#: editor/editor_autoload_settings.cpp editor/editor_help_search.cpp
-#: editor/editor_profiler.cpp editor/settings_config_dialog.cpp
+#: editor/editor_profiler.cpp editor/project_manager.cpp
+#: editor/settings_config_dialog.cpp
msgid "Name"
msgstr "Tên"
@@ -9419,6 +9420,10 @@ msgid "Projects"
msgstr "Dự án"
#: editor/project_manager.cpp
+msgid "Last Modified"
+msgstr ""
+
+#: editor/project_manager.cpp
msgid "Scan"
msgstr "Quét"
diff --git a/editor/translations/zh_CN.po b/editor/translations/zh_CN.po
index 0436963e5a..397f17a1cd 100644
--- a/editor/translations/zh_CN.po
+++ b/editor/translations/zh_CN.po
@@ -1008,7 +1008,7 @@ msgid "Resource"
msgstr "资源"
#: editor/dependency_editor.cpp editor/editor_autoload_settings.cpp
-#: editor/project_settings_editor.cpp
+#: editor/project_manager.cpp editor/project_settings_editor.cpp
msgid "Path"
msgstr "路径"
@@ -1475,7 +1475,8 @@ msgid "Node Name:"
msgstr "节点名称:"
#: editor/editor_autoload_settings.cpp editor/editor_help_search.cpp
-#: editor/editor_profiler.cpp editor/settings_config_dialog.cpp
+#: editor/editor_profiler.cpp editor/project_manager.cpp
+#: editor/settings_config_dialog.cpp
msgid "Name"
msgstr "名称"
@@ -9327,6 +9328,11 @@ msgid "Projects"
msgstr "工程"
#: editor/project_manager.cpp
+#, fuzzy
+msgid "Last Modified"
+msgstr "已修改"
+
+#: editor/project_manager.cpp
msgid "Scan"
msgstr "扫描"
diff --git a/editor/translations/zh_HK.po b/editor/translations/zh_HK.po
index c05494212b..59b5a5b7a2 100644
--- a/editor/translations/zh_HK.po
+++ b/editor/translations/zh_HK.po
@@ -1026,7 +1026,7 @@ msgid "Resource"
msgstr "資源"
#: editor/dependency_editor.cpp editor/editor_autoload_settings.cpp
-#: editor/project_settings_editor.cpp
+#: editor/project_manager.cpp editor/project_settings_editor.cpp
msgid "Path"
msgstr "路徑"
@@ -1532,7 +1532,8 @@ msgid "Node Name:"
msgstr ""
#: editor/editor_autoload_settings.cpp editor/editor_help_search.cpp
-#: editor/editor_profiler.cpp editor/settings_config_dialog.cpp
+#: editor/editor_profiler.cpp editor/project_manager.cpp
+#: editor/settings_config_dialog.cpp
msgid "Name"
msgstr "名稱"
@@ -9773,6 +9774,10 @@ msgid "Projects"
msgstr "專案"
#: editor/project_manager.cpp
+msgid "Last Modified"
+msgstr ""
+
+#: editor/project_manager.cpp
msgid "Scan"
msgstr ""
diff --git a/editor/translations/zh_TW.po b/editor/translations/zh_TW.po
index 622e04b34f..5b360169e1 100644
--- a/editor/translations/zh_TW.po
+++ b/editor/translations/zh_TW.po
@@ -1022,7 +1022,7 @@ msgid "Resource"
msgstr "資源"
#: editor/dependency_editor.cpp editor/editor_autoload_settings.cpp
-#: editor/project_settings_editor.cpp
+#: editor/project_manager.cpp editor/project_settings_editor.cpp
msgid "Path"
msgstr "路徑"
@@ -1523,7 +1523,8 @@ msgid "Node Name:"
msgstr "節點名稱:"
#: editor/editor_autoload_settings.cpp editor/editor_help_search.cpp
-#: editor/editor_profiler.cpp editor/settings_config_dialog.cpp
+#: editor/editor_profiler.cpp editor/project_manager.cpp
+#: editor/settings_config_dialog.cpp
msgid "Name"
msgstr "名稱"
@@ -9742,6 +9743,10 @@ msgid "Projects"
msgstr "專案"
#: editor/project_manager.cpp
+msgid "Last Modified"
+msgstr ""
+
+#: editor/project_manager.cpp
msgid "Scan"
msgstr ""
diff --git a/main/main.cpp b/main/main.cpp
index 724f8206d0..cdaee06135 100644
--- a/main/main.cpp
+++ b/main/main.cpp
@@ -259,6 +259,8 @@ void Main::print_help(const char *p_binary) {
OS::get_singleton()->print(" --position <X>,<Y> Request window position.\n");
OS::get_singleton()->print(" --low-dpi Force low-DPI mode (macOS and Windows only).\n");
OS::get_singleton()->print(" --no-window Disable window creation (Windows only). Useful together with --script.\n");
+ OS::get_singleton()->print(" --enable-vsync-via-compositor When vsync is enabled, vsync via the OS' window compositor (Windows only).\n");
+ OS::get_singleton()->print(" --disable-vsync-via-compositor Disable vsync via the OS' window compositor (Windows only).\n");
OS::get_singleton()->print("\n");
#endif
@@ -399,6 +401,7 @@ Error Main::setup(const char *execpath, int argc, char *argv[], bool p_second_ph
Vector<String> breakpoints;
bool use_custom_res = true;
bool force_res = false;
+ bool saw_vsync_via_compositor_override = false;
#ifdef TOOLS_ENABLED
bool found_project = false;
#endif
@@ -590,6 +593,14 @@ Error Main::setup(const char *execpath, int argc, char *argv[], bool p_second_ph
} else if (I->get() == "--no-window") { // disable window creation (Windows only)
OS::get_singleton()->set_no_window_mode(true);
+ } else if (I->get() == "--enable-vsync-via-compositor") {
+
+ video_mode.vsync_via_compositor = true;
+ saw_vsync_via_compositor_override = true;
+ } else if (I->get() == "--disable-vsync-via-compositor") {
+
+ video_mode.vsync_via_compositor = false;
+ saw_vsync_via_compositor_override = true;
#endif
} else if (I->get() == "--profiling") { // enable profiling
@@ -1009,6 +1020,16 @@ Error Main::setup(const char *execpath, int argc, char *argv[], bool p_second_ph
video_mode.use_vsync = GLOBAL_DEF_RST("display/window/vsync/use_vsync", true);
OS::get_singleton()->_use_vsync = video_mode.use_vsync;
+ if (!saw_vsync_via_compositor_override) {
+ // If one of the command line options to enable/disable vsync via the
+ // window compositor ("--enable-vsync-via-compositor" or
+ // "--disable-vsync-via-compositor") was present then it overrides the
+ // project setting.
+ video_mode.vsync_via_compositor = GLOBAL_DEF("display/window/vsync/vsync_via_compositor", false);
+ }
+
+ OS::get_singleton()->_vsync_via_compositor = video_mode.vsync_via_compositor;
+
OS::get_singleton()->_allow_layered = GLOBAL_DEF("display/window/per_pixel_transparency/allowed", false);
video_mode.layered = GLOBAL_DEF("display/window/per_pixel_transparency/enabled", false);
diff --git a/modules/camera/SCSub b/modules/camera/SCsub
index 23f031f06e..23f031f06e 100644
--- a/modules/camera/SCSub
+++ b/modules/camera/SCsub
diff --git a/modules/gdscript/gdscript_parser.cpp b/modules/gdscript/gdscript_parser.cpp
index 6ef3ab67ae..ef1a282e51 100644
--- a/modules/gdscript/gdscript_parser.cpp
+++ b/modules/gdscript/gdscript_parser.cpp
@@ -3349,7 +3349,12 @@ void GDScriptParser::_parse_block(BlockNode *p_block, bool p_static) {
}
p_block->statements.push_back(expression);
if (!_end_statement()) {
- _set_error("Expected end of statement after expression.");
+ // Attempt to guess a better error message if the user "retypes" a variable
+ if (tokenizer->get_token() == GDScriptTokenizer::TK_COLON && tokenizer->get_token(1) == GDScriptTokenizer::TK_OP_ASSIGN) {
+ _set_error("Unexpected ':=', use '=' instead. Expected end of statement after expression.");
+ } else {
+ _set_error(String() + "Expected end of statement after expression, got " + tokenizer->get_token_name(tokenizer->get_token()) + " instead");
+ }
return;
}
diff --git a/modules/mono/build_scripts/mono_android_config.xml b/modules/mono/build_scripts/mono_android_config.xml
new file mode 100644
index 0000000000..e79670afd2
--- /dev/null
+++ b/modules/mono/build_scripts/mono_android_config.xml
@@ -0,0 +1,28 @@
+<configuration>
+ <dllmap wordsize="32" dll="i:cygwin1.dll" target="/system/lib/libc.so" />
+ <dllmap wordsize="64" dll="i:cygwin1.dll" target="/system/lib64/libc.so" />
+ <dllmap wordsize="32" dll="libc" target="/system/lib/libc.so" />
+ <dllmap wordsize="64" dll="libc" target="/system/lib64/libc.so" />
+ <dllmap wordsize="32" dll="intl" target="/system/lib/libc.so" />
+ <dllmap wordsize="64" dll="intl" target="/system/lib64/libc.so" />
+ <dllmap wordsize="32" dll="libintl" target="/system/lib/libc.so" />
+ <dllmap wordsize="64" dll="libintl" target="/system/lib64/libc.so" />
+ <dllmap dll="MonoPosixHelper" target="libMonoPosixHelper.so" />
+ <dllmap dll="System.Native" target="libmono-native.so" />
+ <dllmap wordsize="32" dll="i:msvcrt" target="/system/lib/libc.so" />
+ <dllmap wordsize="64" dll="i:msvcrt" target="/system/lib64/libc.so" />
+ <dllmap wordsize="32" dll="i:msvcrt.dll" target="/system/lib/libc.so" />
+ <dllmap wordsize="64" dll="i:msvcrt.dll" target="/system/lib64/libc.so" />
+ <dllmap wordsize="32" dll="sqlite" target="/system/lib/libsqlite.so" />
+ <dllmap wordsize="64" dll="sqlite" target="/system/lib64/libsqlite.so" />
+ <dllmap wordsize="32" dll="sqlite3" target="/system/lib/libsqlite.so" />
+ <dllmap wordsize="64" dll="sqlite3" target="/system/lib64/libsqlite.so" />
+ <dllmap wordsize="32" dll="liblog" target="/system/lib/liblog.so" />
+ <dllmap wordsize="64" dll="liblog" target="/system/lib64/liblog.so" />
+ <dllmap dll="i:kernel32.dll">
+ <dllentry dll="__Internal" name="CopyMemory" target="mono_win32_compat_CopyMemory"/>
+ <dllentry dll="__Internal" name="FillMemory" target="mono_win32_compat_FillMemory"/>
+ <dllentry dll="__Internal" name="MoveMemory" target="mono_win32_compat_MoveMemory"/>
+ <dllentry dll="__Internal" name="ZeroMemory" target="mono_win32_compat_ZeroMemory"/>
+ </dllmap>
+</configuration>
diff --git a/modules/mono/build_scripts/mono_configure.py b/modules/mono/build_scripts/mono_configure.py
index c09690ba6d..89d56def7d 100644
--- a/modules/mono/build_scripts/mono_configure.py
+++ b/modules/mono/build_scripts/mono_configure.py
@@ -206,6 +206,8 @@ def configure(env, env_mono):
env_mono.Append(CPPDEFINES=['_REENTRANT'])
if mono_static:
+ env.Append(LINKFLAGS=['-rdynamic'])
+
mono_lib_file = os.path.join(mono_lib_path, 'lib' + mono_lib + '.a')
if is_apple:
@@ -281,8 +283,6 @@ def configure(env, env_mono):
libs_output_dir = get_android_out_dir(env) if is_android else '#bin'
copy_file(mono_lib_path, libs_output_dir, 'lib' + mono_so_name + sharedlib_ext)
- env.Append(LINKFLAGS='-rdynamic')
-
if not tools_enabled:
if is_desktop(env['platform']):
if not mono_root:
@@ -292,7 +292,8 @@ def configure(env, env_mono):
elif is_android:
# Compress Android Mono Config
from . import make_android_mono_config
- config_file_path = os.path.join(mono_root, 'etc', 'mono', 'config')
+ module_dir = os.getcwd()
+ config_file_path = os.path.join(module_dir, 'build_scripts', 'mono_android_config.xml')
make_android_mono_config.generate_compressed_config(config_file_path, 'mono_gd/')
# Copy the required shared libraries
diff --git a/modules/mono/editor/GodotTools/GodotTools/Export/ExportPlugin.cs b/modules/mono/editor/GodotTools/GodotTools/Export/ExportPlugin.cs
index aed25f5ac5..c7e8ea511a 100644
--- a/modules/mono/editor/GodotTools/GodotTools/Export/ExportPlugin.cs
+++ b/modules/mono/editor/GodotTools/GodotTools/Export/ExportPlugin.cs
@@ -125,12 +125,20 @@ namespace GodotTools.Export
dependencies[projectDllName] = projectDllSrcPath;
+ if (platform == OS.Platforms.Android)
{
- string platformBclDir = DeterminePlatformBclDir(platform);
+ string godotAndroidExtProfileDir = GetBclProfileDir("godot_android_ext");
+ string monoAndroidAssemblyPath = Path.Combine(godotAndroidExtProfileDir, "Mono.Android.dll");
+
+ if (!File.Exists(monoAndroidAssemblyPath))
+ throw new FileNotFoundException("Assembly not found: 'Mono.Android'", monoAndroidAssemblyPath);
- internal_GetExportedAssemblyDependencies(projectDllName, projectDllSrcPath, buildConfig, platformBclDir, dependencies);
+ dependencies["Mono.Android"] = monoAndroidAssemblyPath;
}
+ var initialDependencies = dependencies.Duplicate();
+ internal_GetExportedAssemblyDependencies(initialDependencies, buildConfig, DeterminePlatformBclDir(platform), dependencies);
+
string outputDataDir = null;
if (PlatformHasTemplateDir(platform))
@@ -201,23 +209,25 @@ namespace GodotTools.Export
string TemplateDirName() => $"data.mono.{platform}.{bits}.{target}";
string templateDirPath = Path.Combine(Internal.FullTemplatesDir, TemplateDirName());
+ bool validTemplatePathFound = true;
if (!Directory.Exists(templateDirPath))
{
- templateDirPath = null;
+ validTemplatePathFound = false;
if (isDebug)
{
target = "debug"; // Support both 'release_debug' and 'debug' for the template data directory name
templateDirPath = Path.Combine(Internal.FullTemplatesDir, TemplateDirName());
+ validTemplatePathFound = true;
if (!Directory.Exists(templateDirPath))
- templateDirPath = null;
+ validTemplatePathFound = false;
}
}
- if (templateDirPath == null)
- throw new FileNotFoundException("Data template directory not found");
+ if (!validTemplatePathFound)
+ throw new FileNotFoundException("Data template directory not found", templateDirPath);
string outputDataDir = Path.Combine(outputDir, DataDirName);
@@ -579,6 +589,12 @@ namespace GodotTools.Export
return null;
}
+ private static string GetBclProfileDir(string profile)
+ {
+ string templatesDir = Internal.FullTemplatesDir;
+ return Path.Combine(templatesDir, "bcl", profile);
+ }
+
private static string DeterminePlatformBclDir(string platform)
{
string templatesDir = Internal.FullTemplatesDir;
@@ -590,18 +606,45 @@ namespace GodotTools.Export
platformBclDir = Path.Combine(templatesDir, "bcl", profile);
if (!File.Exists(Path.Combine(platformBclDir, "mscorlib.dll")))
+ {
+ if (PlatformRequiresCustomBcl(platform))
+ throw new FileNotFoundException($"Missing BCL (Base Class Library) for platform: {platform}");
+
platformBclDir = null; // Use the one we're running on
+ }
}
return platformBclDir;
}
+ /// <summary>
+ /// Determines whether the BCL bundled with the Godot editor can be used for the target platform,
+ /// or if it requires a custom BCL that must be distributed with the export templates.
+ /// </summary>
+ private static bool PlatformRequiresCustomBcl(string platform)
+ {
+ if (new[] {OS.Platforms.Android, OS.Platforms.HTML5}.Contains(platform))
+ return true;
+
+ // The 'net_4_x' BCL is not compatible between Windows and the other platforms.
+ // We use the names 'net_4_x_win' and 'net_4_x' to differentiate between the two.
+
+ bool isWinOrUwp = new[]
+ {
+ OS.Platforms.Windows,
+ OS.Platforms.UWP
+ }.Contains(platform);
+
+ return OS.IsWindows ? !isWinOrUwp : isWinOrUwp;
+ }
+
private static string DeterminePlatformBclProfile(string platform)
{
switch (platform)
{
case OS.Platforms.Windows:
case OS.Platforms.UWP:
+ return "net_4_x_win";
case OS.Platforms.OSX:
case OS.Platforms.X11:
case OS.Platforms.Server:
@@ -627,7 +670,7 @@ namespace GodotTools.Export
}
[MethodImpl(MethodImplOptions.InternalCall)]
- private static extern void internal_GetExportedAssemblyDependencies(string projectDllName, string projectDllSrcPath,
+ private static extern void internal_GetExportedAssemblyDependencies(Godot.Collections.Dictionary<string, string> initialDependencies,
string buildConfig, string customBclDir, Godot.Collections.Dictionary<string, string> dependencies);
}
}
diff --git a/modules/mono/editor/GodotTools/GodotTools/Utils/OS.cs b/modules/mono/editor/GodotTools/GodotTools/Utils/OS.cs
index 1a8c26acd7..e89ea0c476 100644
--- a/modules/mono/editor/GodotTools/GodotTools/Utils/OS.cs
+++ b/modules/mono/editor/GodotTools/GodotTools/Utils/OS.cs
@@ -65,7 +65,7 @@ namespace GodotTools.Utils
private static readonly Lazy<bool> _isAndroid = new Lazy<bool>(() => IsOS(Names.Android));
private static readonly Lazy<bool> _isHTML5 = new Lazy<bool>(() => IsOS(Names.HTML5));
- public static bool IsWindows => _isWindows.Value;
+ public static bool IsWindows => _isWindows.Value || IsUWP;
public static bool IsOSX => _isOSX.Value;
public static bool IsX11 => _isX11.Value;
public static bool IsServer => _isServer.Value;
diff --git a/modules/mono/editor/editor_internal_calls.cpp b/modules/mono/editor/editor_internal_calls.cpp
index 4055ec005a..443b4ba841 100644
--- a/modules/mono/editor/editor_internal_calls.cpp
+++ b/modules/mono/editor/editor_internal_calls.cpp
@@ -219,15 +219,14 @@ int32_t godot_icall_ScriptClassParser_ParseFile(MonoString *p_filepath, MonoObje
return err;
}
-uint32_t godot_icall_ExportPlugin_GetExportedAssemblyDependencies(MonoString *p_project_dll_name, MonoString *p_project_dll_src_path,
+uint32_t godot_icall_ExportPlugin_GetExportedAssemblyDependencies(MonoObject *p_initial_dependencies,
MonoString *p_build_config, MonoString *p_custom_bcl_dir, MonoObject *r_dependencies) {
- String project_dll_name = GDMonoMarshal::mono_string_to_godot(p_project_dll_name);
- String project_dll_src_path = GDMonoMarshal::mono_string_to_godot(p_project_dll_src_path);
+ Dictionary initial_dependencies = GDMonoMarshal::mono_object_to_variant(p_initial_dependencies);
String build_config = GDMonoMarshal::mono_string_to_godot(p_build_config);
String custom_bcl_dir = GDMonoMarshal::mono_string_to_godot(p_custom_bcl_dir);
Dictionary dependencies = GDMonoMarshal::mono_object_to_variant(r_dependencies);
- return GodotSharpExport::get_exported_assembly_dependencies(project_dll_name, project_dll_src_path, build_config, custom_bcl_dir, dependencies);
+ return GodotSharpExport::get_exported_assembly_dependencies(initial_dependencies, build_config, custom_bcl_dir, dependencies);
}
MonoString *godot_icall_Internal_UpdateApiAssembliesFromPrebuilt(MonoString *p_config) {
diff --git a/modules/mono/editor/godotsharp_export.cpp b/modules/mono/editor/godotsharp_export.cpp
index 9ae9399e1d..e02bd3be58 100644
--- a/modules/mono/editor/godotsharp_export.cpp
+++ b/modules/mono/editor/godotsharp_export.cpp
@@ -101,23 +101,32 @@ Error get_assembly_dependencies(GDMonoAssembly *p_assembly, const Vector<String>
return OK;
}
-Error get_exported_assembly_dependencies(const String &p_project_dll_name, const String &p_project_dll_src_path, const String &p_build_config, const String &p_custom_bcl_dir, Dictionary &r_dependencies) {
+Error get_exported_assembly_dependencies(const Dictionary &p_initial_dependencies,
+ const String &p_build_config, const String &p_custom_bcl_dir, Dictionary &r_dependencies) {
MonoDomain *export_domain = GDMonoUtils::create_domain("GodotEngine.Domain.ProjectExport");
ERR_FAIL_NULL_V(export_domain, FAILED);
_GDMONO_SCOPE_EXIT_DOMAIN_UNLOAD_(export_domain);
_GDMONO_SCOPE_DOMAIN_(export_domain);
- GDMonoAssembly *scripts_assembly = NULL;
- bool load_success = GDMono::get_singleton()->load_assembly_from(p_project_dll_name,
- p_project_dll_src_path, &scripts_assembly, /* refonly: */ true);
-
- ERR_FAIL_COND_V_MSG(!load_success, ERR_CANT_RESOLVE, "Cannot load assembly (refonly): '" + p_project_dll_name + "'.");
-
Vector<String> search_dirs;
GDMonoAssembly::fill_search_dirs(search_dirs, p_build_config, p_custom_bcl_dir);
- return get_assembly_dependencies(scripts_assembly, search_dirs, r_dependencies);
+ for (const Variant *key = p_initial_dependencies.next(); key; key = p_initial_dependencies.next(key)) {
+ String assembly_name = *key;
+ String assembly_path = p_initial_dependencies[*key];
+
+ GDMonoAssembly *assembly = NULL;
+ bool load_success = GDMono::get_singleton()->load_assembly_from(assembly_name, assembly_path, &assembly, /* refonly: */ true);
+
+ ERR_FAIL_COND_V_MSG(!load_success, ERR_CANT_RESOLVE, "Cannot load assembly (refonly): '" + assembly_name + "'.");
+
+ Error err = get_assembly_dependencies(assembly, search_dirs, r_dependencies);
+ if (err != OK)
+ return err;
+ }
+
+ return OK;
}
} // namespace GodotSharpExport
diff --git a/modules/mono/editor/godotsharp_export.h b/modules/mono/editor/godotsharp_export.h
index 58e46e2f2d..8eb5a4d9dc 100644
--- a/modules/mono/editor/godotsharp_export.h
+++ b/modules/mono/editor/godotsharp_export.h
@@ -41,9 +41,8 @@ namespace GodotSharpExport {
Error get_assembly_dependencies(GDMonoAssembly *p_assembly, const Vector<String> &p_search_dirs, Dictionary &r_dependencies);
-Error get_exported_assembly_dependencies(const String &p_project_dll_name,
- const String &p_project_dll_src_path, const String &p_build_config,
- const String &p_custom_lib_dir, Dictionary &r_dependencies);
+Error get_exported_assembly_dependencies(const Dictionary &p_initial_dependencies,
+ const String &p_build_config, const String &p_custom_lib_dir, Dictionary &r_dependencies);
} // namespace GodotSharpExport
diff --git a/modules/mono/glue/Managed/Files/Array.cs b/modules/mono/glue/Managed/Files/Array.cs
index 0e7b0362e0..aba1065498 100644
--- a/modules/mono/glue/Managed/Files/Array.cs
+++ b/modules/mono/glue/Managed/Files/Array.cs
@@ -64,6 +64,11 @@ namespace Godot.Collections
return safeHandle.DangerousGetHandle();
}
+ public Array Duplicate(bool deep = false)
+ {
+ return new Array(godot_icall_Array_Duplicate(GetPtr(), deep));
+ }
+
public Error Resize(int newSize)
{
return godot_icall_Array_Resize(GetPtr(), newSize);
@@ -179,6 +184,9 @@ namespace Godot.Collections
internal extern static void godot_icall_Array_CopyTo(IntPtr ptr, System.Array array, int arrayIndex);
[MethodImpl(MethodImplOptions.InternalCall)]
+ internal extern static IntPtr godot_icall_Array_Duplicate(IntPtr ptr, bool deep);
+
+ [MethodImpl(MethodImplOptions.InternalCall)]
internal extern static int godot_icall_Array_IndexOf(IntPtr ptr, object item);
[MethodImpl(MethodImplOptions.InternalCall)]
@@ -250,6 +258,11 @@ namespace Godot.Collections
return from.objectArray;
}
+ public Array<T> Duplicate(bool deep = false)
+ {
+ return new Array<T>(objectArray.Duplicate(deep));
+ }
+
public Error Resize(int newSize)
{
return objectArray.Resize(newSize);
diff --git a/modules/mono/glue/Managed/Files/Dictionary.cs b/modules/mono/glue/Managed/Files/Dictionary.cs
index 6ab8549a01..d72109de92 100644
--- a/modules/mono/glue/Managed/Files/Dictionary.cs
+++ b/modules/mono/glue/Managed/Files/Dictionary.cs
@@ -80,6 +80,11 @@ namespace Godot.Collections
disposed = true;
}
+ public Dictionary Duplicate(bool deep = false)
+ {
+ return new Dictionary(godot_icall_Dictionary_Duplicate(GetPtr(), deep));
+ }
+
// IDictionary
public ICollection Keys
@@ -235,6 +240,9 @@ namespace Godot.Collections
internal extern static bool godot_icall_Dictionary_ContainsKey(IntPtr ptr, object key);
[MethodImpl(MethodImplOptions.InternalCall)]
+ internal extern static IntPtr godot_icall_Dictionary_Duplicate(IntPtr ptr, bool deep);
+
+ [MethodImpl(MethodImplOptions.InternalCall)]
internal extern static bool godot_icall_Dictionary_RemoveKey(IntPtr ptr, object key);
[MethodImpl(MethodImplOptions.InternalCall)]
@@ -313,6 +321,11 @@ namespace Godot.Collections
return objectDict.GetPtr();
}
+ public Dictionary<TKey, TValue> Duplicate(bool deep = false)
+ {
+ return new Dictionary<TKey, TValue>(objectDict.Duplicate(deep));
+ }
+
// IDictionary<TKey, TValue>
public TValue this[TKey key]
diff --git a/modules/mono/glue/Managed/Files/GD.cs b/modules/mono/glue/Managed/Files/GD.cs
index 2068099ac6..19962d418a 100644
--- a/modules/mono/glue/Managed/Files/GD.cs
+++ b/modules/mono/glue/Managed/Files/GD.cs
@@ -93,22 +93,22 @@ namespace Godot
public static void PrintErr(params object[] what)
{
- godot_icall_GD_printerr(Array.ConvertAll(what, x => x.ToString()));
+ godot_icall_GD_printerr(Array.ConvertAll(what, x => x?.ToString()));
}
public static void PrintRaw(params object[] what)
{
- godot_icall_GD_printraw(Array.ConvertAll(what, x => x.ToString()));
+ godot_icall_GD_printraw(Array.ConvertAll(what, x => x?.ToString()));
}
public static void PrintS(params object[] what)
{
- godot_icall_GD_prints(Array.ConvertAll(what, x => x.ToString()));
+ godot_icall_GD_prints(Array.ConvertAll(what, x => x?.ToString()));
}
public static void PrintT(params object[] what)
{
- godot_icall_GD_printt(Array.ConvertAll(what, x => x.ToString()));
+ godot_icall_GD_printt(Array.ConvertAll(what, x => x?.ToString()));
}
public static float Randf()
diff --git a/modules/mono/glue/collections_glue.cpp b/modules/mono/glue/collections_glue.cpp
index bfb7b0f775..e84a5becd6 100644
--- a/modules/mono/glue/collections_glue.cpp
+++ b/modules/mono/glue/collections_glue.cpp
@@ -103,6 +103,10 @@ void godot_icall_Array_CopyTo(Array *ptr, MonoArray *array, int array_index) {
}
}
+Array *godot_icall_Array_Duplicate(Array *ptr, MonoBoolean deep) {
+ return memnew(Array(ptr->duplicate(deep)));
+}
+
int godot_icall_Array_IndexOf(Array *ptr, MonoObject *item) {
return ptr->find(GDMonoMarshal::mono_object_to_variant(item));
}
@@ -224,6 +228,10 @@ MonoBoolean godot_icall_Dictionary_ContainsKey(Dictionary *ptr, MonoObject *key)
return ptr->has(GDMonoMarshal::mono_object_to_variant(key));
}
+Dictionary *godot_icall_Dictionary_Duplicate(Dictionary *ptr, MonoBoolean deep) {
+ return memnew(Dictionary(ptr->duplicate(deep)));
+}
+
MonoBoolean godot_icall_Dictionary_RemoveKey(Dictionary *ptr, MonoObject *key) {
return ptr->erase(GDMonoMarshal::mono_object_to_variant(key));
}
@@ -284,6 +292,7 @@ void godot_register_collections_icalls() {
mono_add_internal_call("Godot.Collections.Array::godot_icall_Array_Clear", (void *)godot_icall_Array_Clear);
mono_add_internal_call("Godot.Collections.Array::godot_icall_Array_Contains", (void *)godot_icall_Array_Contains);
mono_add_internal_call("Godot.Collections.Array::godot_icall_Array_CopyTo", (void *)godot_icall_Array_CopyTo);
+ mono_add_internal_call("Godot.Collections.Array::godot_icall_Array_Duplicate", (void *)godot_icall_Array_Duplicate);
mono_add_internal_call("Godot.Collections.Array::godot_icall_Array_IndexOf", (void *)godot_icall_Array_IndexOf);
mono_add_internal_call("Godot.Collections.Array::godot_icall_Array_Insert", (void *)godot_icall_Array_Insert);
mono_add_internal_call("Godot.Collections.Array::godot_icall_Array_Remove", (void *)godot_icall_Array_Remove);
@@ -304,6 +313,7 @@ void godot_register_collections_icalls() {
mono_add_internal_call("Godot.Collections.Dictionary::godot_icall_Dictionary_Clear", (void *)godot_icall_Dictionary_Clear);
mono_add_internal_call("Godot.Collections.Dictionary::godot_icall_Dictionary_Contains", (void *)godot_icall_Dictionary_Contains);
mono_add_internal_call("Godot.Collections.Dictionary::godot_icall_Dictionary_ContainsKey", (void *)godot_icall_Dictionary_ContainsKey);
+ mono_add_internal_call("Godot.Collections.Dictionary::godot_icall_Dictionary_Duplicate", (void *)godot_icall_Dictionary_Duplicate);
mono_add_internal_call("Godot.Collections.Dictionary::godot_icall_Dictionary_RemoveKey", (void *)godot_icall_Dictionary_RemoveKey);
mono_add_internal_call("Godot.Collections.Dictionary::godot_icall_Dictionary_Remove", (void *)godot_icall_Dictionary_Remove);
mono_add_internal_call("Godot.Collections.Dictionary::godot_icall_Dictionary_TryGetValue", (void *)godot_icall_Dictionary_TryGetValue);
diff --git a/modules/mono/glue/collections_glue.h b/modules/mono/glue/collections_glue.h
index 54ed42c3b6..a79a651fcd 100644
--- a/modules/mono/glue/collections_glue.h
+++ b/modules/mono/glue/collections_glue.h
@@ -59,6 +59,8 @@ MonoBoolean godot_icall_Array_Contains(Array *ptr, MonoObject *item);
void godot_icall_Array_CopyTo(Array *ptr, MonoArray *array, int array_index);
+Array *godot_icall_Array_Duplicate(Array *ptr, MonoBoolean deep);
+
int godot_icall_Array_IndexOf(Array *ptr, MonoObject *item);
void godot_icall_Array_Insert(Array *ptr, int index, MonoObject *item);
@@ -99,6 +101,8 @@ MonoBoolean godot_icall_Dictionary_Contains(Dictionary *ptr, MonoObject *key, Mo
MonoBoolean godot_icall_Dictionary_ContainsKey(Dictionary *ptr, MonoObject *key);
+Dictionary *godot_icall_Dictionary_Duplicate(Dictionary *ptr, MonoBoolean deep);
+
MonoBoolean godot_icall_Dictionary_RemoveKey(Dictionary *ptr, MonoObject *key);
MonoBoolean godot_icall_Dictionary_Remove(Dictionary *ptr, MonoObject *key, MonoObject *value);
diff --git a/modules/mono/mono_gd/gd_mono.cpp b/modules/mono/mono_gd/gd_mono.cpp
index a43311d281..33ba877352 100644
--- a/modules/mono/mono_gd/gd_mono.cpp
+++ b/modules/mono/mono_gd/gd_mono.cpp
@@ -330,7 +330,7 @@ void GDMono::initialize() {
#endif
#if defined(ANDROID_ENABLED)
- GDMonoAndroid::register_android_dl_fallback();
+ GDMonoAndroid::initialize();
#endif
GDMonoAssembly::initialize();
@@ -363,6 +363,9 @@ void GDMono::initialize() {
}
#endif
+ // NOTE: Internal calls must be registered after the Mono runtime initialization.
+ // Otherwise registration fails with the error: 'assertion 'hash != NULL' failed'.
+
root_domain = gd_initialize_mono_runtime();
ERR_FAIL_NULL_MSG(root_domain, "Mono: Failed to initialize runtime.");
@@ -376,6 +379,10 @@ void GDMono::initialize() {
print_verbose("Mono: Runtime initialized");
+#if defined(ANDROID_ENABLED)
+ GDMonoAndroid::register_internal_calls();
+#endif
+
// mscorlib assembly MUST be present at initialization
bool corlib_loaded = _load_corlib_assembly();
ERR_FAIL_COND_MSG(!corlib_loaded, "Mono: Failed to load mscorlib assembly.");
@@ -1253,6 +1260,10 @@ GDMono::~GDMono() {
mono_jit_cleanup(root_domain);
+#if defined(ANDROID_ENABLED)
+ GDMonoAndroid::cleanup();
+#endif
+
print_verbose("Mono: Finalized");
runtime_initialized = false;
diff --git a/modules/mono/mono_gd/gd_mono_android.cpp b/modules/mono/mono_gd/gd_mono_android.cpp
index 1ee035589d..86af8d1812 100644
--- a/modules/mono/mono_gd/gd_mono_android.cpp
+++ b/modules/mono/mono_gd/gd_mono_android.cpp
@@ -34,38 +34,97 @@
#include <dlfcn.h> // dlopen, dlsym
#include <mono/utils/mono-dl-fallback.h>
+#include <sys/system_properties.h>
+#include <cstddef>
+
+#if __ANDROID_API__ < 24
+#include "thirdparty/misc/ifaddrs-android.h"
+#else
+#include <ifaddrs.h>
+#endif
#include "core/os/os.h"
#include "core/ustring.h"
+#include "platform/android/java_godot_wrapper.h"
+#include "platform/android/os_android.h"
#include "platform/android/thread_jandroid.h"
#include "../utils/path_utils.h"
#include "../utils/string_utils.h"
+#include "gd_mono_cache.h"
+#include "gd_mono_marshal.h"
+
+// Warning: JNI boilerplate ahead... continue at your own risk
namespace GDMonoAndroid {
+template <typename T>
+struct ScopedLocalRef {
+ JNIEnv *env;
+ T local_ref;
+
+ _FORCE_INLINE_ T get() const { return local_ref; }
+ _FORCE_INLINE_ operator T() const { return local_ref; }
+ _FORCE_INLINE_ operator jvalue() const { return (jvalue)local_ref; }
+
+ _FORCE_INLINE_ operator bool() const { return local_ref != NULL; }
+
+ _FORCE_INLINE_ bool operator==(std::nullptr_t) const {
+ return local_ref == nullptr;
+ }
+
+ _FORCE_INLINE_ bool operator!=(std::nullptr_t) const {
+ return local_ref != nullptr;
+ }
+
+ ScopedLocalRef(const ScopedLocalRef &) = delete;
+ ScopedLocalRef &operator=(const ScopedLocalRef &) = delete;
+
+ ScopedLocalRef(JNIEnv *p_env, T p_local_ref) :
+ env(p_env), local_ref(p_local_ref) {
+ }
+
+ ~ScopedLocalRef() {
+ if (local_ref) {
+ env->DeleteLocalRef(local_ref);
+ }
+ }
+};
+
+bool jni_exception_check(JNIEnv *p_env) {
+ if (p_env->ExceptionCheck()) {
+ // Print the exception to logcat
+ p_env->ExceptionDescribe();
+
+ p_env->ExceptionClear();
+ return true;
+ }
+
+ return false;
+}
+
String app_native_lib_dir_cache;
String determine_app_native_lib_dir() {
JNIEnv *env = ThreadAndroid::get_env();
- jclass activityThreadClass = env->FindClass("android/app/ActivityThread");
+ ScopedLocalRef<jclass> activityThreadClass(env, env->FindClass("android/app/ActivityThread"));
jmethodID currentActivityThread = env->GetStaticMethodID(activityThreadClass, "currentActivityThread", "()Landroid/app/ActivityThread;");
- jobject activityThread = env->CallStaticObjectMethod(activityThreadClass, currentActivityThread);
+ ScopedLocalRef<jobject> activityThread(env, env->CallStaticObjectMethod(activityThreadClass, currentActivityThread));
jmethodID getApplication = env->GetMethodID(activityThreadClass, "getApplication", "()Landroid/app/Application;");
- jobject ctx = env->CallObjectMethod(activityThread, getApplication);
+ ScopedLocalRef<jobject> ctx(env, env->CallObjectMethod(activityThread, getApplication));
jmethodID getApplicationInfo = env->GetMethodID(env->GetObjectClass(ctx), "getApplicationInfo", "()Landroid/content/pm/ApplicationInfo;");
- jobject applicationInfo = env->CallObjectMethod(ctx, getApplicationInfo);
+ ScopedLocalRef<jobject> applicationInfo(env, env->CallObjectMethod(ctx, getApplicationInfo));
jfieldID nativeLibraryDirField = env->GetFieldID(env->GetObjectClass(applicationInfo), "nativeLibraryDir", "Ljava/lang/String;");
- jstring nativeLibraryDir = (jstring)env->GetObjectField(applicationInfo, nativeLibraryDirField);
+ ScopedLocalRef<jstring> nativeLibraryDir(env, (jstring)env->GetObjectField(applicationInfo, nativeLibraryDirField));
String result;
- const char *const nativeLibraryDir_utf8 = env->GetStringUTFChars(nativeLibraryDir, NULL);
- if (nativeLibraryDir_utf8) {
- result.parse_utf8(nativeLibraryDir_utf8);
- env->ReleaseStringUTFChars(nativeLibraryDir, nativeLibraryDir_utf8);
+ const char *const nativeLibraryDirUtf8 = env->GetStringUTFChars(nativeLibraryDir, NULL);
+ if (nativeLibraryDirUtf8) {
+ result.parse_utf8(nativeLibraryDirUtf8);
+ env->ReleaseStringUTFChars(nativeLibraryDir, nativeLibraryDirUtf8);
}
return result;
@@ -90,7 +149,53 @@ int gd_mono_convert_dl_flags(int flags) {
return lflags;
}
+#ifndef GD_MONO_ANDROID_SO_NAME
+#define GD_MONO_ANDROID_SO_NAME "libmonosgen-2.0.so"
+#endif
+
+const char *mono_so_name = GD_MONO_ANDROID_SO_NAME;
+const char *godot_so_name = "libgodot_android.so";
+
+void *mono_dl_handle = NULL;
+void *godot_dl_handle = NULL;
+
+void *try_dlopen(const String &p_so_path, int p_flags) {
+ if (!FileAccess::exists(p_so_path)) {
+ if (OS::get_singleton()->is_stdout_verbose())
+ OS::get_singleton()->print("Cannot find shared library: '%s'\n", p_so_path.utf8().get_data());
+ return NULL;
+ }
+
+ int lflags = gd_mono_convert_dl_flags(p_flags);
+
+ void *handle = dlopen(p_so_path.utf8().get_data(), lflags);
+
+ if (!handle) {
+ if (OS::get_singleton()->is_stdout_verbose())
+ OS::get_singleton()->print("Failed to open shared library: '%s'. Error: '%s'\n", p_so_path.utf8().get_data(), dlerror());
+ return NULL;
+ }
+
+ if (OS::get_singleton()->is_stdout_verbose())
+ OS::get_singleton()->print("Successfully loaded shared library: '%s'\n", p_so_path.utf8().get_data());
+
+ return handle;
+}
+
void *gd_mono_android_dlopen(const char *p_name, int p_flags, char **r_err, void *p_user_data) {
+ if (p_name == NULL) {
+ // __Internal
+
+ if (!mono_dl_handle) {
+ String app_native_lib_dir = get_app_native_lib_dir();
+ String so_path = path::join(app_native_lib_dir, mono_so_name);
+
+ mono_dl_handle = try_dlopen(so_path, p_flags);
+ }
+
+ return mono_dl_handle;
+ }
+
String name = String::utf8(p_name);
if (name.ends_with(".dll.so") || name.ends_with(".exe.so")) {
@@ -100,26 +205,7 @@ void *gd_mono_android_dlopen(const char *p_name, int p_flags, char **r_err, void
String so_name = "lib-aot-" + orig_so_name;
String so_path = path::join(app_native_lib_dir, so_name);
- if (!FileAccess::exists(so_path)) {
- if (OS::get_singleton()->is_stdout_verbose())
- OS::get_singleton()->print("Cannot find shared library: '%s'\n", so_path.utf8().get_data());
- return NULL;
- }
-
- int lflags = gd_mono_convert_dl_flags(p_flags);
-
- void *handle = dlopen(so_path.utf8().get_data(), lflags);
-
- if (!handle) {
- if (OS::get_singleton()->is_stdout_verbose())
- OS::get_singleton()->print("Failed to open shared library: '%s'. Error: '%s'\n", so_path.utf8().get_data(), dlerror());
- return NULL;
- }
-
- if (OS::get_singleton()->is_stdout_verbose())
- OS::get_singleton()->print("Successfully loaded AOT shared library: '%s'\n", so_path.utf8().get_data());
-
- return handle;
+ return try_dlopen(so_path, p_flags);
}
return NULL;
@@ -131,16 +217,469 @@ void *gd_mono_android_dlsym(void *p_handle, const char *p_name, char **r_err, vo
if (sym_addr)
return sym_addr;
+ if (p_handle == mono_dl_handle && godot_dl_handle) {
+ // Looking up for '__Internal' P/Invoke. We want to search in both the Mono and Godot shared libraries.
+ // This is needed to resolve the monodroid P/Invoke functions that are defined at the bottom of the file.
+ sym_addr = dlsym(godot_dl_handle, p_name);
+
+ if (sym_addr)
+ return sym_addr;
+ }
+
if (r_err)
*r_err = str_format_new("%s\n", dlerror());
return NULL;
}
-void register_android_dl_fallback() {
- mono_dl_fallback_register(gd_mono_android_dlopen, gd_mono_android_dlsym, NULL, NULL);
+void *gd_mono_android_dlclose(void *p_handle, void *p_user_data) {
+ dlclose(p_handle);
+
+ // Not sure if this ever happens. Does Mono close the handle for the main module?
+ if (p_handle == mono_dl_handle)
+ mono_dl_handle = NULL;
+
+ return NULL;
+}
+
+int32_t build_version_sdk_int = 0;
+
+int32_t get_build_version_sdk_int() {
+ // The JNI code is the equivalent of:
+ //
+ // android.os.Build.VERSION.SDK_INT
+
+ if (build_version_sdk_int == 0) {
+ JNIEnv *env = ThreadAndroid::get_env();
+
+ jclass versionClass = env->FindClass("android/os/Build$VERSION");
+ ERR_FAIL_NULL_V(versionClass, 0);
+
+ jfieldID sdkIntField = env->GetStaticFieldID(versionClass, "SDK_INT", "I");
+ ERR_FAIL_NULL_V(sdkIntField, 0);
+
+ build_version_sdk_int = (int32_t)env->GetStaticIntField(versionClass, sdkIntField);
+ }
+
+ return build_version_sdk_int;
+}
+
+jobject certStore = NULL; // KeyStore
+
+MonoBoolean _gd_mono_init_cert_store() {
+ // The JNI code is the equivalent of:
+ //
+ // try {
+ // certStoreLocal = KeyStore.getInstance("AndroidCAStore");
+ // certStoreLocal.load(null);
+ // certStore = certStoreLocal;
+ // return true;
+ // } catch (Exception e) {
+ // return false;
+ // }
+
+ JNIEnv *env = ThreadAndroid::get_env();
+
+ ScopedLocalRef<jclass> keyStoreClass(env, env->FindClass("java/security/KeyStore"));
+
+ jmethodID getInstance = env->GetStaticMethodID(keyStoreClass, "getInstance", "(Ljava/lang/String;)Ljava/security/KeyStore;");
+ jmethodID load = env->GetMethodID(keyStoreClass, "load", "(Ljava/security/KeyStore$LoadStoreParameter;)V");
+
+ ScopedLocalRef<jstring> androidCAStoreString(env, env->NewStringUTF("AndroidCAStore"));
+
+ ScopedLocalRef<jobject> certStoreLocal(env, env->CallStaticObjectMethod(keyStoreClass, getInstance, androidCAStoreString.get()));
+
+ if (jni_exception_check(env))
+ return 0;
+
+ env->CallVoidMethod(certStoreLocal, load, NULL);
+
+ if (jni_exception_check(env))
+ return 0;
+
+ certStore = env->NewGlobalRef(certStoreLocal);
+
+ return 1;
+}
+
+MonoArray *_gd_mono_android_cert_store_lookup(MonoString *p_alias) {
+ // The JNI code is the equivalent of:
+ //
+ // Certificate certificate = certStore.getCertificate(alias);
+ // if (certificate == null)
+ // return null;
+ // return certificate.getEncoded();
+
+ MonoError mono_error;
+ char *alias_utf8 = mono_string_to_utf8_checked(p_alias, &mono_error);
+
+ if (!mono_error_ok(&mono_error)) {
+ ERR_PRINTS(String() + "Failed to convert MonoString* to UTF-8: '" + mono_error_get_message(&mono_error) + "'.");
+ mono_error_cleanup(&mono_error);
+ return NULL;
+ }
+
+ JNIEnv *env = ThreadAndroid::get_env();
+
+ ScopedLocalRef<jstring> js_alias(env, env->NewStringUTF(alias_utf8));
+ mono_free(alias_utf8);
+
+ ScopedLocalRef<jclass> keyStoreClass(env, env->FindClass("java/security/KeyStore"));
+ ERR_FAIL_NULL_V(keyStoreClass, NULL);
+ ScopedLocalRef<jclass> certificateClass(env, env->FindClass("java/security/cert/Certificate"));
+ ERR_FAIL_NULL_V(certificateClass, NULL);
+
+ jmethodID getCertificate = env->GetMethodID(keyStoreClass, "getCertificate", "(Ljava/lang/String;)Ljava/security/cert/Certificate;");
+ ERR_FAIL_NULL_V(getCertificate, NULL);
+
+ jmethodID getEncoded = env->GetMethodID(certificateClass, "getEncoded", "()[B");
+ ERR_FAIL_NULL_V(getEncoded, NULL);
+
+ ScopedLocalRef<jobject> certificate(env, env->CallObjectMethod(certStore, getCertificate, js_alias.get()));
+
+ if (!certificate)
+ return NULL;
+
+ ScopedLocalRef<jbyteArray> encoded(env, (jbyteArray)env->CallObjectMethod(certificate, getEncoded));
+ jsize encodedLength = env->GetArrayLength(encoded);
+
+ MonoArray *encoded_ret = mono_array_new(mono_domain_get(), CACHED_CLASS_RAW(uint8_t), encodedLength);
+ uint8_t *dest = (uint8_t *)mono_array_addr(encoded_ret, uint8_t, 0);
+
+ env->GetByteArrayRegion(encoded, 0, encodedLength, reinterpret_cast<jbyte *>(dest));
+
+ return encoded_ret;
+}
+
+void initialize() {
+ // We need to set this environment variable to make the monodroid BCL use btls instead of legacy as the default provider
+ OS::get_singleton()->set_environment("XA_TLS_PROVIDER", "btls");
+
+ mono_dl_fallback_register(gd_mono_android_dlopen, gd_mono_android_dlsym, gd_mono_android_dlclose, NULL);
+
+ String app_native_lib_dir = get_app_native_lib_dir();
+ String so_path = path::join(app_native_lib_dir, godot_so_name);
+
+ godot_dl_handle = try_dlopen(so_path, gd_mono_convert_dl_flags(MONO_DL_LAZY));
+}
+
+void register_internal_calls() {
+ mono_add_internal_call("Android.Runtime.AndroidEnvironment::_gd_mono_init_cert_store", (void *)_gd_mono_init_cert_store);
+ mono_add_internal_call("Android.Runtime.AndroidEnvironment::_gd_mono_android_cert_store_lookup", (void *)_gd_mono_android_cert_store_lookup);
+}
+
+void cleanup() {
+ // This is called after shutting down the Mono runtime
+
+ if (mono_dl_handle)
+ gd_mono_android_dlclose(mono_dl_handle, NULL);
+
+ if (godot_dl_handle)
+ gd_mono_android_dlclose(godot_dl_handle, NULL);
+
+ JNIEnv *env = ThreadAndroid::get_env();
+
+ if (certStore) {
+ env->DeleteGlobalRef(certStore);
+ certStore = NULL;
+ }
}
} // namespace GDMonoAndroid
+using namespace GDMonoAndroid;
+
+// The following are P/Invoke functions required by the monodroid profile of the BCL.
+// These are P/Invoke functions and not internal calls, hence why they use
+// 'mono_bool' and 'const char*' instead of 'MonoBoolean' and 'MonoString*'.
+
+#define GD_PINVOKE_EXPORT extern "C" __attribute__((visibility("default")))
+
+GD_PINVOKE_EXPORT int32_t _monodroid_get_android_api_level() {
+ return get_build_version_sdk_int();
+}
+
+GD_PINVOKE_EXPORT void monodroid_free(void *ptr) {
+ free(ptr);
+}
+
+GD_PINVOKE_EXPORT int32_t monodroid_get_system_property(const char *p_name, char **r_value) {
+ char prop_value_str[PROP_VALUE_MAX + 1] = { 0 };
+
+ int len = __system_property_get(p_name, prop_value_str);
+
+ if (r_value) {
+ if (len >= 0) {
+ *r_value = (char *)malloc(len + 1);
+ if (!*r_value)
+ return -1;
+ memcpy(*r_value, prop_value_str, len);
+ (*r_value)[len] = '\0';
+ } else {
+ *r_value = NULL;
+ }
+ }
+
+ return len;
+}
+
+GD_PINVOKE_EXPORT mono_bool _monodroid_get_network_interface_up_state(const char *p_ifname, mono_bool *r_is_up) {
+ // The JNI code is the equivalent of:
+ //
+ // NetworkInterface.getByName(p_ifname).isUp()
+
+ if (!r_is_up || !p_ifname || strlen(p_ifname) == 0)
+ return 0;
+
+ *r_is_up = 0;
+
+ JNIEnv *env = ThreadAndroid::get_env();
+
+ jclass networkInterfaceClass = env->FindClass("java/net/NetworkInterface");
+ ERR_FAIL_NULL_V(networkInterfaceClass, 0);
+
+ jmethodID getByName = env->GetStaticMethodID(networkInterfaceClass, "getByName", "(Ljava/lang/String;)Ljava/net/NetworkInterface;");
+ ERR_FAIL_NULL_V(getByName, 0);
+
+ jmethodID isUp = env->GetMethodID(networkInterfaceClass, "isUp", "()Z");
+ ERR_FAIL_NULL_V(isUp, 0);
+
+ ScopedLocalRef<jstring> js_ifname(env, env->NewStringUTF(p_ifname));
+ ScopedLocalRef<jobject> networkInterface(env, env->CallStaticObjectMethod(networkInterfaceClass, getByName, js_ifname.get()));
+
+ if (!networkInterface)
+ return 0;
+
+ *r_is_up = (mono_bool)env->CallBooleanMethod(networkInterface, isUp);
+
+ return 1;
+}
+
+GD_PINVOKE_EXPORT mono_bool _monodroid_get_network_interface_supports_multicast(const char *p_ifname, mono_bool *r_supports_multicast) {
+ // The JNI code is the equivalent of:
+ //
+ // NetworkInterface.getByName(p_ifname).supportsMulticast()
+
+ if (!r_supports_multicast || !p_ifname || strlen(p_ifname) == 0)
+ return 0;
+
+ *r_supports_multicast = 0;
+
+ JNIEnv *env = ThreadAndroid::get_env();
+
+ jclass networkInterfaceClass = env->FindClass("java/net/NetworkInterface");
+ ERR_FAIL_NULL_V(networkInterfaceClass, 0);
+
+ jmethodID getByName = env->GetStaticMethodID(networkInterfaceClass, "getByName", "(Ljava/lang/String;)Ljava/net/NetworkInterface;");
+ ERR_FAIL_NULL_V(getByName, 0);
+
+ jmethodID supportsMulticast = env->GetMethodID(networkInterfaceClass, "supportsMulticast", "()Z");
+ ERR_FAIL_NULL_V(supportsMulticast, 0);
+
+ ScopedLocalRef<jstring> js_ifname(env, env->NewStringUTF(p_ifname));
+ ScopedLocalRef<jobject> networkInterface(env, env->CallStaticObjectMethod(networkInterfaceClass, getByName, js_ifname.get()));
+
+ if (!networkInterface)
+ return 0;
+
+ *r_supports_multicast = (mono_bool)env->CallBooleanMethod(networkInterface, supportsMulticast);
+
+ return 1;
+}
+
+static const int dns_servers_len = 8;
+
+static void interop_get_active_network_dns_servers(char **r_dns_servers, int *dns_servers_count) {
+ // The JNI code is the equivalent of:
+ //
+ // ConnectivityManager connectivityManager = (ConnectivityManager)getApplicationContext()
+ // .getSystemService(Context.CONNECTIVITY_SERVICE);
+ // Network activeNerwork = connectivityManager.getActiveNetwork();
+ // LinkProperties linkProperties = connectivityManager.getLinkProperties(activeNerwork);
+ // List<String> dnsServers = linkProperties.getDnsServers().stream()
+ // .map(inetAddress -> inetAddress.getHostAddress()).collect(Collectors.toList());
+
+#ifdef DEBUG_ENABLED
+ CRASH_COND(get_build_version_sdk_int() < 23);
+#endif
+
+ JNIEnv *env = ThreadAndroid::get_env();
+
+ GodotJavaWrapper *godot_java = ((OS_Android *)OS::get_singleton())->get_godot_java();
+ jobject activity = godot_java->get_activity();
+
+ ScopedLocalRef<jclass> activityClass(env, env->GetObjectClass(activity));
+ ERR_FAIL_NULL(activityClass);
+
+ jmethodID getApplicationContext = env->GetMethodID(activityClass, "getApplicationContext", "()Landroid/content/Context;");
+
+ ScopedLocalRef<jobject> applicationContext(env, env->CallObjectMethod(activity, getApplicationContext));
+
+ ScopedLocalRef<jclass> contextClass(env, env->FindClass("android/content/Context"));
+ ERR_FAIL_NULL(contextClass);
+
+ jfieldID connectivityServiceField = env->GetStaticFieldID(contextClass, "CONNECTIVITY_SERVICE", "Ljava/lang/String;");
+ ScopedLocalRef<jstring> connectivityServiceString(env, (jstring)env->GetStaticObjectField(contextClass, connectivityServiceField));
+
+ jmethodID getSystemService = env->GetMethodID(contextClass, "getSystemService", "(Ljava/lang/String;)Ljava/lang/Object;");
+
+ ScopedLocalRef<jobject> connectivityManager(env, env->CallObjectMethod(applicationContext, getSystemService, connectivityServiceString.get()));
+
+ if (!connectivityManager)
+ return;
+
+ ScopedLocalRef<jclass> connectivityManagerClass(env, env->FindClass("android/net/ConnectivityManager"));
+ ERR_FAIL_NULL(connectivityManagerClass);
+
+ jmethodID getActiveNetwork = env->GetMethodID(connectivityManagerClass, "getActiveNetwork", "()Landroid/net/Network;");
+ ERR_FAIL_NULL(getActiveNetwork);
+
+ ScopedLocalRef<jobject> activeNetwork(env, env->CallObjectMethod(connectivityManager, getActiveNetwork));
+
+ if (!activeNetwork)
+ return;
+
+ jmethodID getLinkProperties = env->GetMethodID(connectivityManagerClass,
+ "getLinkProperties", "(Landroid/net/Network;)Landroid/net/LinkProperties;");
+ ERR_FAIL_NULL(getLinkProperties);
+
+ ScopedLocalRef<jobject> linkProperties(env, env->CallObjectMethod(connectivityManager, getLinkProperties, activeNetwork.get()));
+
+ if (!linkProperties)
+ return;
+
+ ScopedLocalRef<jclass> linkPropertiesClass(env, env->FindClass("android/net/LinkProperties"));
+ ERR_FAIL_NULL(linkPropertiesClass);
+
+ jmethodID getDnsServers = env->GetMethodID(linkPropertiesClass, "getDnsServers", "()Ljava/util/List;");
+ ERR_FAIL_NULL(getDnsServers);
+
+ ScopedLocalRef<jobject> dnsServers(env, env->CallObjectMethod(linkProperties, getDnsServers));
+
+ if (!dnsServers)
+ return;
+
+ ScopedLocalRef<jclass> listClass(env, env->FindClass("java/util/List"));
+ ERR_FAIL_NULL(listClass);
+
+ jmethodID listSize = env->GetMethodID(listClass, "size", "()I");
+ ERR_FAIL_NULL(listSize);
+
+ int dnsServersCount = env->CallIntMethod(dnsServers, listSize);
+
+ if (dnsServersCount > dns_servers_len)
+ dnsServersCount = dns_servers_len;
+
+ if (dnsServersCount <= 0)
+ return;
+
+ jmethodID listGet = env->GetMethodID(listClass, "get", "(I)Ljava/lang/Object;");
+ ERR_FAIL_NULL(listGet);
+
+ ScopedLocalRef<jclass> inetAddressClass(env, env->FindClass("java/net/InetAddress"));
+ ERR_FAIL_NULL(inetAddressClass);
+
+ jmethodID getHostAddress = env->GetMethodID(inetAddressClass, "getHostAddress", "()Ljava/lang/String;");
+ ERR_FAIL_NULL(getHostAddress);
+
+ for (int i = 0; i < dnsServersCount; i++) {
+ ScopedLocalRef<jobject> dnsServer(env, env->CallObjectMethod(dnsServers, listGet, (jint)i));
+ if (!dnsServer)
+ continue;
+
+ ScopedLocalRef<jstring> hostAddress(env, (jstring)env->CallObjectMethod(dnsServer, getHostAddress));
+ const char *host_address = env->GetStringUTFChars(hostAddress, 0);
+
+ r_dns_servers[i] = strdup(host_address); // freed by the BCL
+ (*dns_servers_count)++;
+
+ env->ReleaseStringUTFChars(hostAddress, host_address);
+ }
+
+ // jesus...
+}
+
+GD_PINVOKE_EXPORT int32_t _monodroid_get_dns_servers(void **r_dns_servers_array) {
+ if (!r_dns_servers_array)
+ return -1;
+
+ *r_dns_servers_array = NULL;
+
+ char *dns_servers[dns_servers_len];
+ int dns_servers_count = 0;
+
+ if (_monodroid_get_android_api_level() < 26) {
+ // The 'net.dns*' system properties are no longer available in Android 8.0 (API level 26) and greater:
+ // https://developer.android.com/about/versions/oreo/android-8.0-changes.html#o-pri
+
+ char prop_name[] = "net.dns*";
+
+ for (int i = 0; i < dns_servers_len; i++) {
+ prop_name[7] = (char)(i + 0x31);
+ char *prop_value;
+ int32_t len = monodroid_get_system_property(prop_name, &prop_value);
+
+ if (len > 0) {
+ dns_servers[dns_servers_count] = strndup(prop_value, (size_t)len); // freed by the BCL
+ dns_servers_count++;
+ free(prop_value);
+ }
+ }
+ } else {
+ // Alternative for Oreo and greater
+ interop_get_active_network_dns_servers(dns_servers, &dns_servers_count);
+ }
+
+ if (dns_servers_count > 0) {
+ size_t ret_size = sizeof(char *) * (size_t)dns_servers_count;
+ *r_dns_servers_array = malloc(ret_size); // freed by the BCL
+ memcpy(*r_dns_servers_array, dns_servers, ret_size);
+ }
+
+ return dns_servers_count;
+}
+
+GD_PINVOKE_EXPORT const char *_monodroid_timezone_get_default_id() {
+ // The JNI code is the equivalent of:
+ //
+ // TimeZone.getDefault().getID()
+
+ JNIEnv *env = ThreadAndroid::get_env();
+
+ ScopedLocalRef<jclass> timeZoneClass(env, env->FindClass("java/util/TimeZone"));
+ ERR_FAIL_NULL_V(timeZoneClass, NULL);
+
+ jmethodID getDefault = env->GetStaticMethodID(timeZoneClass, "getDefault", "()Ljava/util/TimeZone;");
+ ERR_FAIL_NULL_V(getDefault, NULL);
+
+ jmethodID getID = env->GetMethodID(timeZoneClass, "getID", "()Ljava/lang/String;");
+ ERR_FAIL_NULL_V(getID, NULL);
+
+ ScopedLocalRef<jobject> defaultTimeZone(env, env->CallStaticObjectMethod(timeZoneClass, getDefault));
+
+ if (!defaultTimeZone)
+ return NULL;
+
+ ScopedLocalRef<jstring> defaultTimeZoneID(env, (jstring)env->CallObjectMethod(defaultTimeZone, getID));
+
+ if (!defaultTimeZoneID)
+ return NULL;
+
+ const char *default_time_zone_id = env->GetStringUTFChars(defaultTimeZoneID, 0);
+
+ char *result = strdup(default_time_zone_id); // freed by the BCL
+
+ env->ReleaseStringUTFChars(defaultTimeZoneID, default_time_zone_id);
+
+ return result;
+}
+
+GD_PINVOKE_EXPORT int32_t _monodroid_getifaddrs(struct ifaddrs **p_ifap) {
+ return getifaddrs(p_ifap);
+}
+
+GD_PINVOKE_EXPORT void _monodroid_freeifaddrs(struct ifaddrs *p_ifap) {
+ freeifaddrs(p_ifap);
+}
+
#endif
diff --git a/modules/mono/mono_gd/gd_mono_android.h b/modules/mono/mono_gd/gd_mono_android.h
index 72bc799bfd..20ca266428 100644
--- a/modules/mono/mono_gd/gd_mono_android.h
+++ b/modules/mono/mono_gd/gd_mono_android.h
@@ -39,7 +39,11 @@ namespace GDMonoAndroid {
String get_app_native_lib_dir();
-void register_android_dl_fallback();
+void initialize();
+
+void register_internal_calls();
+
+void cleanup();
} // namespace GDMonoAndroid
diff --git a/modules/mono/mono_gd/gd_mono_cache.h b/modules/mono/mono_gd/gd_mono_cache.h
index b21f92cdd8..a6d6da4f2b 100644
--- a/modules/mono/mono_gd/gd_mono_cache.h
+++ b/modules/mono/mono_gd/gd_mono_cache.h
@@ -42,20 +42,20 @@ struct CachedData {
// corlib classes
// Let's use the no-namespace format for these too
- GDMonoClass *class_MonoObject;
- GDMonoClass *class_bool;
- GDMonoClass *class_int8_t;
- GDMonoClass *class_int16_t;
- GDMonoClass *class_int32_t;
- GDMonoClass *class_int64_t;
- GDMonoClass *class_uint8_t;
- GDMonoClass *class_uint16_t;
- GDMonoClass *class_uint32_t;
- GDMonoClass *class_uint64_t;
- GDMonoClass *class_float;
- GDMonoClass *class_double;
- GDMonoClass *class_String;
- GDMonoClass *class_IntPtr;
+ GDMonoClass *class_MonoObject; // object
+ GDMonoClass *class_bool; // bool
+ GDMonoClass *class_int8_t; // sbyte
+ GDMonoClass *class_int16_t; // short
+ GDMonoClass *class_int32_t; // int
+ GDMonoClass *class_int64_t; // long
+ GDMonoClass *class_uint8_t; // byte
+ GDMonoClass *class_uint16_t; // ushort
+ GDMonoClass *class_uint32_t; // uint
+ GDMonoClass *class_uint64_t; // ulong
+ GDMonoClass *class_float; // float
+ GDMonoClass *class_double; // double
+ GDMonoClass *class_String; // string
+ GDMonoClass *class_IntPtr; // System.IntPtr
GDMonoClass *class_System_Collections_IEnumerable;
GDMonoClass *class_System_Collections_IDictionary;
diff --git a/modules/mono/mono_gd/gd_mono_marshal.cpp b/modules/mono/mono_gd/gd_mono_marshal.cpp
index 3827960e6b..f74fe5715c 100644
--- a/modules/mono/mono_gd/gd_mono_marshal.cpp
+++ b/modules/mono/mono_gd/gd_mono_marshal.cpp
@@ -935,6 +935,8 @@ Array mono_array_to_Array(MonoArray *p_array) {
return ret;
}
+// TODO: Use memcpy where possible
+
MonoArray *PoolIntArray_to_mono_array(const PoolIntArray &p_array) {
PoolIntArray::Read r = p_array.read();
diff --git a/modules/visual_script/visual_script_editor.cpp b/modules/visual_script/visual_script_editor.cpp
index b2791cfc8b..bf353d287f 100644
--- a/modules/visual_script/visual_script_editor.cpp
+++ b/modules/visual_script/visual_script_editor.cpp
@@ -3464,6 +3464,7 @@ void VisualScriptEditor::_selected_connect_node(const String &p_text, const Stri
ofs = ofs.snapped(Vector2(snap, snap));
}
ofs /= EDSCALE;
+ ofs /= graph->get_zoom();
Set<int> vn;
diff --git a/platform/iphone/export/export.cpp b/platform/iphone/export/export.cpp
index 82c9508fdb..4f4439bc60 100644
--- a/platform/iphone/export/export.cpp
+++ b/platform/iphone/export/export.cpp
@@ -219,7 +219,7 @@ void EditorExportPlatformIOS::get_preset_features(const Ref<EditorExportPreset>
Vector<EditorExportPlatformIOS::ExportArchitecture> EditorExportPlatformIOS::_get_supported_architectures() {
Vector<ExportArchitecture> archs;
- archs.push_back(ExportArchitecture("armv7", true));
+ archs.push_back(ExportArchitecture("armv7", false)); // Disabled by default, not included in official templates.
archs.push_back(ExportArchitecture("arm64", true));
return archs;
}
diff --git a/platform/javascript/detect.py b/platform/javascript/detect.py
index c05b765c5e..7bf3e1bc1d 100644
--- a/platform/javascript/detect.py
+++ b/platform/javascript/detect.py
@@ -131,6 +131,13 @@ def configure(env):
env.Append(LINKFLAGS=['-s', 'BINARYEN=1'])
+ # This needs to be defined for Emscripten using 'fastcomp' (default pre-1.39.0)
+ # and undefined if using 'upstream'. And to make things simple, earlier
+ # Emscripten versions didn't include 'fastcomp' in their path, so we check
+ # against the presence of 'upstream' to conditionally add the flag.
+ if not "upstream" in em_config['EMSCRIPTEN_ROOT']:
+ env.Append(LINKFLAGS=['-s', 'BINARYEN_TRAP_MODE=\'clamp\''])
+
# Allow increasing memory buffer size during runtime. This is efficient
# when using WebAssembly (in comparison to asm.js) and works well for
# us since we don't know requirements at compile-time.
diff --git a/platform/windows/context_gl_windows.cpp b/platform/windows/context_gl_windows.cpp
index e715999378..34a5698394 100644
--- a/platform/windows/context_gl_windows.cpp
+++ b/platform/windows/context_gl_windows.cpp
@@ -34,6 +34,8 @@
#include "context_gl_windows.h"
+#include <dwmapi.h>
+
#define WGL_CONTEXT_MAJOR_VERSION_ARB 0x2091
#define WGL_CONTEXT_MINOR_VERSION_ARB 0x2092
#define WGL_CONTEXT_FLAGS_ARB 0x2094
@@ -63,16 +65,52 @@ int ContextGL_Windows::get_window_height() {
return OS::get_singleton()->get_video_mode().height;
}
+bool ContextGL_Windows::should_vsync_via_compositor() {
+
+ if (OS::get_singleton()->is_window_fullscreen() || !OS::get_singleton()->is_vsync_via_compositor_enabled()) {
+ return false;
+ }
+
+ // Note: All Windows versions supported by Godot have a compositor.
+ // It can be disabled on earlier Windows versions.
+ BOOL dwm_enabled;
+
+ if (SUCCEEDED(DwmIsCompositionEnabled(&dwm_enabled))) {
+ return dwm_enabled;
+ }
+
+ return false;
+}
+
void ContextGL_Windows::swap_buffers() {
SwapBuffers(hDC);
+
+ if (use_vsync) {
+ bool vsync_via_compositor_now = should_vsync_via_compositor();
+
+ if (vsync_via_compositor_now) {
+ DwmFlush();
+ }
+
+ if (vsync_via_compositor_now != vsync_via_compositor) {
+ // The previous frame had a different operating mode than this
+ // frame. Set the 'vsync_via_compositor' member variable and the
+ // OpenGL swap interval to their proper values.
+ set_use_vsync(true);
+ }
+ }
}
void ContextGL_Windows::set_use_vsync(bool p_use) {
+ vsync_via_compositor = p_use && should_vsync_via_compositor();
+
if (wglSwapIntervalEXT) {
- wglSwapIntervalEXT(p_use ? 1 : 0);
+ int swap_interval = (p_use && !vsync_via_compositor) ? 1 : 0;
+ wglSwapIntervalEXT(swap_interval);
}
+
use_vsync = p_use;
}
@@ -177,6 +215,7 @@ ContextGL_Windows::ContextGL_Windows(HWND hwnd, bool p_opengl_3_context) {
opengl_3_context = p_opengl_3_context;
hWnd = hwnd;
use_vsync = false;
+ vsync_via_compositor = false;
}
ContextGL_Windows::~ContextGL_Windows() {
diff --git a/platform/windows/context_gl_windows.h b/platform/windows/context_gl_windows.h
index d23fba50e1..e65ea1928f 100644
--- a/platform/windows/context_gl_windows.h
+++ b/platform/windows/context_gl_windows.h
@@ -50,9 +50,12 @@ class ContextGL_Windows {
HWND hWnd;
bool opengl_3_context;
bool use_vsync;
+ bool vsync_via_compositor;
PFNWGLSWAPINTERVALEXTPROC wglSwapIntervalEXT;
+ static bool should_vsync_via_compositor();
+
public:
void release_current();
diff --git a/platform/windows/detect.py b/platform/windows/detect.py
index 9a2b2bcb98..b37a21f37f 100644
--- a/platform/windows/detect.py
+++ b/platform/windows/detect.py
@@ -221,7 +221,8 @@ def configure_msvc(env, manual_msvc_config):
LIBS = ['winmm', 'opengl32', 'dsound', 'kernel32', 'ole32', 'oleaut32',
'user32', 'gdi32', 'IPHLPAPI', 'Shlwapi', 'wsock32', 'Ws2_32',
- 'shell32', 'advapi32', 'dinput8', 'dxguid', 'imm32', 'bcrypt','Avrt']
+ 'shell32', 'advapi32', 'dinput8', 'dxguid', 'imm32', 'bcrypt','Avrt',
+ 'dwmapi']
env.Append(LINKFLAGS=[p + env["LIBSUFFIX"] for p in LIBS])
if manual_msvc_config:
@@ -348,7 +349,7 @@ def configure_mingw(env):
env.Append(CCFLAGS=['-mwindows'])
env.Append(CPPDEFINES=['WINDOWS_ENABLED', 'OPENGL_ENABLED', 'WASAPI_ENABLED', 'WINMIDI_ENABLED'])
env.Append(CPPDEFINES=[('WINVER', env['target_win_version']), ('_WIN32_WINNT', env['target_win_version'])])
- env.Append(LIBS=['mingw32', 'opengl32', 'dsound', 'ole32', 'd3d9', 'winmm', 'gdi32', 'iphlpapi', 'shlwapi', 'wsock32', 'ws2_32', 'kernel32', 'oleaut32', 'dinput8', 'dxguid', 'ksuser', 'imm32', 'bcrypt', 'avrt', 'uuid'])
+ env.Append(LIBS=['mingw32', 'opengl32', 'dsound', 'ole32', 'd3d9', 'winmm', 'gdi32', 'iphlpapi', 'shlwapi', 'wsock32', 'ws2_32', 'kernel32', 'oleaut32', 'dinput8', 'dxguid', 'ksuser', 'imm32', 'bcrypt', 'avrt', 'uuid', 'dwmapi'])
env.Append(CPPDEFINES=['MINGW_ENABLED', ('MINGW_HAS_SECURE_API', 1)])
diff --git a/platform/windows/export/export.cpp b/platform/windows/export/export.cpp
index 3abb05b494..858453ddfd 100644
--- a/platform/windows/export/export.cpp
+++ b/platform/windows/export/export.cpp
@@ -39,6 +39,7 @@ static Error fixup_embedded_pck(const String &p_path, int64_t p_embedded_start,
class EditorExportPlatformWindows : public EditorExportPlatformPC {
+ void _rcedit_add_data(const Ref<EditorExportPreset> &p_preset, const String &p_path);
Error _code_sign(const Ref<EditorExportPreset> &p_preset, const String &p_path);
public:
@@ -62,15 +63,50 @@ Error EditorExportPlatformWindows::export_project(const Ref<EditorExportPreset>
return err;
}
+ _rcedit_add_data(p_preset, p_path);
+
+ if (p_preset->get("codesign/enable") && err == OK) {
+ err = _code_sign(p_preset, p_path);
+ }
+
+ return err;
+}
+
+void EditorExportPlatformWindows::get_export_options(List<ExportOption> *r_options) {
+ EditorExportPlatformPC::get_export_options(r_options);
+
+ r_options->push_back(ExportOption(PropertyInfo(Variant::BOOL, "codesign/enable"), false));
+#ifdef WINDOWS_ENABLED
+ r_options->push_back(ExportOption(PropertyInfo(Variant::INT, "codesign/identity_type", PROPERTY_HINT_ENUM, "Select automatically,Use PKCS12 file (specify *.PFX/*.P12 file),Use certificate store (specify SHA1 hash)"), 0));
+#endif
+ r_options->push_back(ExportOption(PropertyInfo(Variant::STRING, "codesign/identity", PROPERTY_HINT_GLOBAL_FILE, "*.pfx,*.p12"), ""));
+ r_options->push_back(ExportOption(PropertyInfo(Variant::STRING, "codesign/password"), ""));
+ r_options->push_back(ExportOption(PropertyInfo(Variant::BOOL, "codesign/timestamp"), true));
+ r_options->push_back(ExportOption(PropertyInfo(Variant::STRING, "codesign/timestamp_server_url"), ""));
+ r_options->push_back(ExportOption(PropertyInfo(Variant::INT, "codesign/digest_algorithm", PROPERTY_HINT_ENUM, "SHA1,SHA256"), 1));
+ r_options->push_back(ExportOption(PropertyInfo(Variant::STRING, "codesign/description"), ""));
+ r_options->push_back(ExportOption(PropertyInfo(Variant::POOL_STRING_ARRAY, "codesign/custom_options"), PoolStringArray()));
+
+ r_options->push_back(ExportOption(PropertyInfo(Variant::STRING, "application/icon", PROPERTY_HINT_FILE, "*.ico"), ""));
+ r_options->push_back(ExportOption(PropertyInfo(Variant::STRING, "application/file_version", PROPERTY_HINT_PLACEHOLDER_TEXT, "1.0.0"), ""));
+ r_options->push_back(ExportOption(PropertyInfo(Variant::STRING, "application/product_version", PROPERTY_HINT_PLACEHOLDER_TEXT, "1.0.0"), ""));
+ r_options->push_back(ExportOption(PropertyInfo(Variant::STRING, "application/company_name", PROPERTY_HINT_PLACEHOLDER_TEXT, "Company Name"), ""));
+ r_options->push_back(ExportOption(PropertyInfo(Variant::STRING, "application/product_name", PROPERTY_HINT_PLACEHOLDER_TEXT, "Game Name"), ""));
+ r_options->push_back(ExportOption(PropertyInfo(Variant::STRING, "application/file_description"), ""));
+ r_options->push_back(ExportOption(PropertyInfo(Variant::STRING, "application/copyright"), ""));
+ r_options->push_back(ExportOption(PropertyInfo(Variant::STRING, "application/trademarks"), ""));
+}
+
+void EditorExportPlatformWindows::_rcedit_add_data(const Ref<EditorExportPreset> &p_preset, const String &p_path) {
String rcedit_path = EditorSettings::get_singleton()->get("export/windows/rcedit");
if (rcedit_path == String()) {
- return OK;
+ return;
}
if (!FileAccess::exists(rcedit_path)) {
- ERR_PRINTS("Could not find rcedit executable at " + rcedit_path + ", aborting.");
- return ERR_FILE_NOT_FOUND;
+ ERR_PRINTS("Could not find rcedit executable at " + rcedit_path + ", no icon or app information data will be included.");
+ return;
}
#ifndef WINDOWS_ENABLED
@@ -78,8 +114,8 @@ Error EditorExportPlatformWindows::export_project(const Ref<EditorExportPreset>
String wine_path = EditorSettings::get_singleton()->get("export/windows/wine");
if (wine_path != String() && !FileAccess::exists(wine_path)) {
- ERR_PRINTS("Could not find wine executable at " + wine_path + ", aborting.");
- return ERR_FILE_NOT_FOUND;
+ ERR_PRINTS("Could not find wine executable at " + wine_path + ", no icon or app information data will be included.");
+ return;
}
if (wine_path == String()) {
@@ -144,37 +180,6 @@ Error EditorExportPlatformWindows::export_project(const Ref<EditorExportPreset>
args.push_front(rcedit_path);
OS::get_singleton()->execute(wine_path, args, true);
#endif
-
- if (p_preset->get("codesign/enable") && err == OK) {
- err = _code_sign(p_preset, p_path);
- }
-
- return err;
-}
-
-void EditorExportPlatformWindows::get_export_options(List<ExportOption> *r_options) {
- EditorExportPlatformPC::get_export_options(r_options);
-
- r_options->push_back(ExportOption(PropertyInfo(Variant::BOOL, "codesign/enable"), false));
-#ifdef WINDOWS_ENABLED
- r_options->push_back(ExportOption(PropertyInfo(Variant::INT, "codesign/identity_type", PROPERTY_HINT_ENUM, "Select automatically,Use PKCS12 file (specify *.PFX/*.P12 file),Use certificate store (specify SHA1 hash)"), 0));
-#endif
- r_options->push_back(ExportOption(PropertyInfo(Variant::STRING, "codesign/identity", PROPERTY_HINT_GLOBAL_FILE, "*.pfx,*.p12"), ""));
- r_options->push_back(ExportOption(PropertyInfo(Variant::STRING, "codesign/password"), ""));
- r_options->push_back(ExportOption(PropertyInfo(Variant::BOOL, "codesign/timestamp"), true));
- r_options->push_back(ExportOption(PropertyInfo(Variant::STRING, "codesign/timestamp_server_url"), ""));
- r_options->push_back(ExportOption(PropertyInfo(Variant::INT, "codesign/digest_algorithm", PROPERTY_HINT_ENUM, "SHA1,SHA256"), 1));
- r_options->push_back(ExportOption(PropertyInfo(Variant::STRING, "codesign/description"), ""));
- r_options->push_back(ExportOption(PropertyInfo(Variant::POOL_STRING_ARRAY, "codesign/custom_options"), PoolStringArray()));
-
- r_options->push_back(ExportOption(PropertyInfo(Variant::STRING, "application/icon", PROPERTY_HINT_FILE, "*.ico"), ""));
- r_options->push_back(ExportOption(PropertyInfo(Variant::STRING, "application/file_version", PROPERTY_HINT_PLACEHOLDER_TEXT, "1.0.0"), ""));
- r_options->push_back(ExportOption(PropertyInfo(Variant::STRING, "application/product_version", PROPERTY_HINT_PLACEHOLDER_TEXT, "1.0.0"), ""));
- r_options->push_back(ExportOption(PropertyInfo(Variant::STRING, "application/company_name", PROPERTY_HINT_PLACEHOLDER_TEXT, "Company Name"), ""));
- r_options->push_back(ExportOption(PropertyInfo(Variant::STRING, "application/product_name", PROPERTY_HINT_PLACEHOLDER_TEXT, "Game Name"), ""));
- r_options->push_back(ExportOption(PropertyInfo(Variant::STRING, "application/file_description"), ""));
- r_options->push_back(ExportOption(PropertyInfo(Variant::STRING, "application/copyright"), ""));
- r_options->push_back(ExportOption(PropertyInfo(Variant::STRING, "application/trademarks"), ""));
}
Error EditorExportPlatformWindows::_code_sign(const Ref<EditorExportPreset> &p_preset, const String &p_path) {
diff --git a/platform/windows/os_windows.cpp b/platform/windows/os_windows.cpp
index 9c1514f541..f749134f3c 100755
--- a/platform/windows/os_windows.cpp
+++ b/platform/windows/os_windows.cpp
@@ -1480,6 +1480,7 @@ Error OS_Windows::initialize(const VideoMode &p_desired, int p_video_driver, int
video_driver_index = p_video_driver;
gl_context->set_use_vsync(video_mode.use_vsync);
+ set_vsync_via_compositor(video_mode.vsync_via_compositor);
#endif
visual_server = memnew(VisualServerRaster);
diff --git a/scene/gui/file_dialog.cpp b/scene/gui/file_dialog.cpp
index 6400061309..a76e99f304 100644
--- a/scene/gui/file_dialog.cpp
+++ b/scene/gui/file_dialog.cpp
@@ -567,16 +567,16 @@ void FileDialog::update_filters() {
if (max_filters < filters.size())
all_filters += ", ...";
- filter->add_item(RTR("All Recognized") + " ( " + all_filters + " )");
+ filter->add_item(RTR("All Recognized") + " (" + all_filters + ")");
}
for (int i = 0; i < filters.size(); i++) {
String flt = filters[i].get_slice(";", 0).strip_edges();
String desc = filters[i].get_slice(";", 1).strip_edges();
if (desc.length())
- filter->add_item(String(tr(desc)) + " ( " + flt + " )");
+ filter->add_item(String(tr(desc)) + " (" + flt + ")");
else
- filter->add_item("( " + flt + " )");
+ filter->add_item("(" + flt + ")");
}
filter->add_item(RTR("All Files (*)"));
diff --git a/scene/resources/packed_scene.cpp b/scene/resources/packed_scene.cpp
index 7d62873bbd..5ce269fff9 100644
--- a/scene/resources/packed_scene.cpp
+++ b/scene/resources/packed_scene.cpp
@@ -397,6 +397,9 @@ Error SceneState::_parse_node(Node *p_owner, Node *p_node, int p_parent_idx, Map
if (p_owner->get_scene_inherited_state().is_null() && (p_node == p_owner || (p_node->get_owner() == p_owner && (p_node->get_parent() == p_owner || p_node->get_parent()->get_owner() == p_owner)))) {
//do not save index, because it belongs to saved scene and scene is not inherited
nd.index = -1;
+ } else if (p_node == p_owner) {
+ //This (hopefully) happens if the node is a scene root, so its index is irrelevant.
+ nd.index = -1;
} else {
//part of an inherited scene, or parent is from an instanced scene
nd.index = p_node->get_index();
diff --git a/servers/visual_server.cpp b/servers/visual_server.cpp
index ce83b6d4ec..2c1d28e32c 100644
--- a/servers/visual_server.cpp
+++ b/servers/visual_server.cpp
@@ -1717,6 +1717,7 @@ void VisualServer::_bind_methods() {
ClassDB::bind_method(D_METHOD("mesh_get_custom_aabb", "mesh"), &VisualServer::mesh_get_custom_aabb);
ClassDB::bind_method(D_METHOD("mesh_clear", "mesh"), &VisualServer::mesh_clear);
+ ClassDB::bind_method(D_METHOD("multimesh_create"), &VisualServer::multimesh_create);
ClassDB::bind_method(D_METHOD("multimesh_allocate", "multimesh", "instances", "transform_format", "color_format", "custom_data_format"), &VisualServer::multimesh_allocate, DEFVAL(MULTIMESH_CUSTOM_DATA_NONE));
ClassDB::bind_method(D_METHOD("multimesh_get_instance_count", "multimesh"), &VisualServer::multimesh_get_instance_count);
ClassDB::bind_method(D_METHOD("multimesh_set_mesh", "multimesh", "mesh"), &VisualServer::multimesh_set_mesh);
diff --git a/thirdparty/misc/ifaddrs-android.h b/thirdparty/misc/ifaddrs-android.h
index 6e204af26f..8de94324b8 100644
--- a/thirdparty/misc/ifaddrs-android.h
+++ b/thirdparty/misc/ifaddrs-android.h
@@ -32,6 +32,11 @@
// Fills out a list of ifaddr structs (see below) which contain information
// about every network interface available on the host.
// See 'man getifaddrs' on Linux or OS X (nb: it is not a POSIX function).
+// -- GODOT start --
+#ifdef __cplusplus
+extern "C" {
+#endif
+// -- GODOT end --
struct ifaddrs {
struct ifaddrs* ifa_next;
char* ifa_name;
@@ -40,7 +45,21 @@ struct ifaddrs {
struct sockaddr* ifa_netmask;
// Real ifaddrs has broadcast, point to point and data members.
// We don't need them (yet?).
+ // -- GODOT start --
+ // We never initialize the following members. We only define them to match the ifaddrs struct.
+ union
+ {
+ struct sockaddr *ifu_broadaddr;
+ struct sockaddr *ifu_dstaddr;
+ } ifa_ifu;
+ void *ifa_data;
+ // -- GODOT end --
};
+// -- GODOT start --
+#ifdef __cplusplus
+}
+#endif
+// -- GODOT end --
int getifaddrs(struct ifaddrs** result);
void freeifaddrs(struct ifaddrs* addrs);
#endif // TALK_BASE_IFADDRS_ANDROID_H_