summaryrefslogtreecommitdiff
path: root/core
diff options
context:
space:
mode:
Diffstat (limited to 'core')
-rw-r--r--core/array.cpp14
-rw-r--r--core/array.h1
-rw-r--r--core/bind/core_bind.cpp21
-rw-r--r--core/bind/core_bind.h4
-rw-r--r--core/class_db.cpp41
-rw-r--r--core/class_db.h2
-rw-r--r--core/color.cpp49
-rw-r--r--core/color.h1
-rw-r--r--core/io/file_access_network.cpp2
-rw-r--r--core/io/resource_format_binary.cpp2
-rw-r--r--core/io/stream_peer.cpp2
-rw-r--r--core/io/stream_peer.h2
-rw-r--r--core/io/stream_peer_ssl.cpp1
-rw-r--r--core/io/stream_peer_ssl.h1
-rw-r--r--core/make_binders.py2
-rw-r--r--core/os/os.cpp11
-rw-r--r--core/os/os.h8
-rw-r--r--core/project_settings.cpp76
-rw-r--r--core/project_settings.h3
-rw-r--r--core/translation.cpp19
-rw-r--r--core/variant_call.cpp4
21 files changed, 231 insertions, 35 deletions
diff --git a/core/array.cpp b/core/array.cpp
index c53fea1f28..0ddac1662c 100644
--- a/core/array.cpp
+++ b/core/array.cpp
@@ -266,6 +266,20 @@ Array &Array::sort_custom(Object *p_obj, const StringName &p_function) {
return *this;
}
+void Array::shuffle() {
+
+ const int n = _p->array.size();
+ if (n < 2)
+ return;
+ Variant *data = _p->array.ptrw();
+ for (int i = n - 1; i >= 1; i--) {
+ const int j = Math::rand() % (i + 1);
+ const Variant tmp = data[j];
+ data[j] = data[i];
+ data[i] = tmp;
+ }
+}
+
template <typename Less>
_FORCE_INLINE_ int bisect(const Vector<Variant> &p_array, const Variant &p_value, bool p_before, const Less &p_less) {
diff --git a/core/array.h b/core/array.h
index 7c6fc59048..684a8e265d 100644
--- a/core/array.h
+++ b/core/array.h
@@ -71,6 +71,7 @@ public:
Array &sort();
Array &sort_custom(Object *p_obj, const StringName &p_function);
+ void shuffle();
int bsearch(const Variant &p_value, bool p_before = true);
int bsearch_custom(const Variant &p_value, Object *p_obj, const StringName &p_function, bool p_before = true);
Array &invert();
diff --git a/core/bind/core_bind.cpp b/core/bind/core_bind.cpp
index 32b94b9b02..b57b24ee7d 100644
--- a/core/bind/core_bind.cpp
+++ b/core/bind/core_bind.cpp
@@ -264,6 +264,10 @@ Size2 _OS::get_window_size() const {
return OS::get_singleton()->get_window_size();
}
+Size2 _OS::get_real_window_size() const {
+ return OS::get_singleton()->get_real_window_size();
+}
+
void _OS::set_window_size(const Size2 &p_size) {
OS::get_singleton()->set_window_size(p_size);
}
@@ -300,6 +304,14 @@ bool _OS::is_window_maximized() const {
return OS::get_singleton()->is_window_maximized();
}
+void _OS::set_window_always_on_top(bool p_enabled) {
+ OS::get_singleton()->set_window_always_on_top(p_enabled);
+}
+
+bool _OS::is_window_always_on_top() const {
+ return OS::get_singleton()->is_window_always_on_top();
+}
+
void _OS::set_borderless_window(bool p_borderless) {
OS::get_singleton()->set_borderless_window(p_borderless);
}
@@ -929,6 +941,11 @@ void _OS::request_attention() {
OS::get_singleton()->request_attention();
}
+void _OS::center_window() {
+
+ OS::get_singleton()->center_window();
+}
+
bool _OS::is_debug_build() const {
#ifdef DEBUG_ENABLED
@@ -1016,7 +1033,11 @@ void _OS::_bind_methods() {
ClassDB::bind_method(D_METHOD("is_window_minimized"), &_OS::is_window_minimized);
ClassDB::bind_method(D_METHOD("set_window_maximized", "enabled"), &_OS::set_window_maximized);
ClassDB::bind_method(D_METHOD("is_window_maximized"), &_OS::is_window_maximized);
+ ClassDB::bind_method(D_METHOD("set_window_always_on_top", "enabled"), &_OS::set_window_always_on_top);
+ ClassDB::bind_method(D_METHOD("is_window_always_on_top"), &_OS::is_window_always_on_top);
ClassDB::bind_method(D_METHOD("request_attention"), &_OS::request_attention);
+ ClassDB::bind_method(D_METHOD("get_real_window_size"), &_OS::get_real_window_size);
+ ClassDB::bind_method(D_METHOD("center_window"), &_OS::center_window);
ClassDB::bind_method(D_METHOD("set_borderless_window", "borderless"), &_OS::set_borderless_window);
ClassDB::bind_method(D_METHOD("get_borderless_window"), &_OS::get_borderless_window);
diff --git a/core/bind/core_bind.h b/core/bind/core_bind.h
index 2353b6d09f..734b57937a 100644
--- a/core/bind/core_bind.h
+++ b/core/bind/core_bind.h
@@ -155,6 +155,7 @@ public:
virtual Point2 get_window_position() const;
virtual void set_window_position(const Point2 &p_position);
virtual Size2 get_window_size() const;
+ virtual Size2 get_real_window_size() const;
virtual void set_window_size(const Size2 &p_size);
virtual void set_window_fullscreen(bool p_enabled);
virtual bool is_window_fullscreen() const;
@@ -164,7 +165,10 @@ public:
virtual bool is_window_minimized() const;
virtual void set_window_maximized(bool p_enabled);
virtual bool is_window_maximized() const;
+ virtual void set_window_always_on_top(bool p_enabled);
+ virtual bool is_window_always_on_top() const;
virtual void request_attention();
+ virtual void center_window();
virtual void set_borderless_window(bool p_borderless);
virtual bool get_borderless_window() const;
diff --git a/core/class_db.cpp b/core/class_db.cpp
index d2cd362792..afcc8de0f2 100644
--- a/core/class_db.cpp
+++ b/core/class_db.cpp
@@ -207,6 +207,47 @@ MethodDefinition D_METHOD(const char *p_name, const char *p_arg1, const char *p_
return md;
}
+MethodDefinition D_METHOD(const char *p_name, const char *p_arg1, const char *p_arg2, const char *p_arg3, const char *p_arg4, const char *p_arg5, const char *p_arg6, const char *p_arg7, const char *p_arg8, const char *p_arg9, const char *p_arg10, const char *p_arg11, const char *p_arg12) {
+
+ MethodDefinition md;
+ md.name = StaticCString::create(p_name);
+ md.args.resize(12);
+ md.args[0] = StaticCString::create(p_arg1);
+ md.args[1] = StaticCString::create(p_arg2);
+ md.args[2] = StaticCString::create(p_arg3);
+ md.args[3] = StaticCString::create(p_arg4);
+ md.args[4] = StaticCString::create(p_arg5);
+ md.args[5] = StaticCString::create(p_arg6);
+ md.args[6] = StaticCString::create(p_arg7);
+ md.args[7] = StaticCString::create(p_arg8);
+ md.args[8] = StaticCString::create(p_arg9);
+ md.args[9] = StaticCString::create(p_arg10);
+ md.args[10] = StaticCString::create(p_arg11);
+ md.args[11] = StaticCString::create(p_arg12);
+ return md;
+}
+
+MethodDefinition D_METHOD(const char *p_name, const char *p_arg1, const char *p_arg2, const char *p_arg3, const char *p_arg4, const char *p_arg5, const char *p_arg6, const char *p_arg7, const char *p_arg8, const char *p_arg9, const char *p_arg10, const char *p_arg11, const char *p_arg12, const char *p_arg13) {
+
+ MethodDefinition md;
+ md.name = StaticCString::create(p_name);
+ md.args.resize(13);
+ md.args[0] = StaticCString::create(p_arg1);
+ md.args[1] = StaticCString::create(p_arg2);
+ md.args[2] = StaticCString::create(p_arg3);
+ md.args[3] = StaticCString::create(p_arg4);
+ md.args[4] = StaticCString::create(p_arg5);
+ md.args[5] = StaticCString::create(p_arg6);
+ md.args[6] = StaticCString::create(p_arg7);
+ md.args[7] = StaticCString::create(p_arg8);
+ md.args[8] = StaticCString::create(p_arg9);
+ md.args[9] = StaticCString::create(p_arg10);
+ md.args[10] = StaticCString::create(p_arg11);
+ md.args[11] = StaticCString::create(p_arg12);
+ md.args[12] = StaticCString::create(p_arg13);
+ return md;
+}
+
#endif
ClassDB::APIType ClassDB::current_api = API_CORE;
diff --git a/core/class_db.h b/core/class_db.h
index 14e36e459b..d74317239b 100644
--- a/core/class_db.h
+++ b/core/class_db.h
@@ -68,6 +68,8 @@ MethodDefinition D_METHOD(const char *p_name, const char *p_arg1, const char *p_
MethodDefinition D_METHOD(const char *p_name, const char *p_arg1, const char *p_arg2, const char *p_arg3, const char *p_arg4, const char *p_arg5, const char *p_arg6, const char *p_arg7, const char *p_arg8, const char *p_arg9);
MethodDefinition D_METHOD(const char *p_name, const char *p_arg1, const char *p_arg2, const char *p_arg3, const char *p_arg4, const char *p_arg5, const char *p_arg6, const char *p_arg7, const char *p_arg8, const char *p_arg9, const char *p_arg10);
MethodDefinition D_METHOD(const char *p_name, const char *p_arg1, const char *p_arg2, const char *p_arg3, const char *p_arg4, const char *p_arg5, const char *p_arg6, const char *p_arg7, const char *p_arg8, const char *p_arg9, const char *p_arg10, const char *p_arg11);
+MethodDefinition D_METHOD(const char *p_name, const char *p_arg1, const char *p_arg2, const char *p_arg3, const char *p_arg4, const char *p_arg5, const char *p_arg6, const char *p_arg7, const char *p_arg8, const char *p_arg9, const char *p_arg10, const char *p_arg11, const char *p_arg12);
+MethodDefinition D_METHOD(const char *p_name, const char *p_arg1, const char *p_arg2, const char *p_arg3, const char *p_arg4, const char *p_arg5, const char *p_arg6, const char *p_arg7, const char *p_arg8, const char *p_arg9, const char *p_arg10, const char *p_arg11, const char *p_arg12, const char *p_arg13);
#else
diff --git a/core/color.cpp b/core/color.cpp
index a0568d26ed..27d8e9b891 100644
--- a/core/color.cpp
+++ b/core/color.cpp
@@ -400,6 +400,55 @@ String Color::to_html(bool p_alpha) const {
return txt;
}
+Color Color::from_hsv(float p_h, float p_s, float p_v, float p_a) {
+
+ const float h_ = p_h / 60.0f;
+ const float c = p_v * p_s;
+ const float x = c * (1.0f - Math::abs(Math::fmod(h_, 2.0f) - 1.0f));
+ float r, g, b;
+
+ switch ((int)h_) {
+ case 0: {
+ r = c;
+ g = x;
+ b = 0;
+ } break;
+ case 1: {
+ r = x;
+ g = c;
+ b = 0;
+ } break;
+ case 2: {
+ r = 0;
+ g = c;
+ b = x;
+ } break;
+ case 3: {
+ r = 0;
+ g = x;
+ b = c;
+ } break;
+ case 4: {
+ r = x;
+ g = 0;
+ b = c;
+ } break;
+ case 5: {
+ r = c;
+ g = 0;
+ b = x;
+ } break;
+ default: {
+ r = 0;
+ g = 0;
+ b = 0;
+ } break;
+ }
+
+ const float m = p_v - c;
+ return Color(m + r, m + g, m + b, p_a);
+}
+
float Color::gray() const {
return (r + g + b) / 3.0;
diff --git a/core/color.h b/core/color.h
index 9af8fb0a78..a2015a34d6 100644
--- a/core/color.h
+++ b/core/color.h
@@ -190,6 +190,7 @@ struct Color {
static bool html_is_valid(const String &p_color);
static Color named(const String &p_name);
String to_html(bool p_alpha = true) const;
+ Color from_hsv(float p_h, float p_s, float p_v, float p_a);
_FORCE_INLINE_ bool operator<(const Color &p_color) const; //used in set keys
operator String() const;
diff --git a/core/io/file_access_network.cpp b/core/io/file_access_network.cpp
index ef886cdb3c..21e3a4172b 100644
--- a/core/io/file_access_network.cpp
+++ b/core/io/file_access_network.cpp
@@ -418,8 +418,6 @@ int FileAccessNetwork::get_buffer(uint8_t *p_dst, int p_length) const {
if (page != last_page) {
buffer_mutex->lock();
if (pages[page].buffer.empty()) {
- //fuck
-
waiting_on_page = page;
for (int j = 0; j < read_ahead; j++) {
diff --git a/core/io/resource_format_binary.cpp b/core/io/resource_format_binary.cpp
index 15c4835dc6..5dfe067902 100644
--- a/core/io/resource_format_binary.cpp
+++ b/core/io/resource_format_binary.cpp
@@ -1124,7 +1124,7 @@ Error ResourceFormatLoaderBinary::rename_dependencies(const String &p_path, cons
DirAccess *da = DirAccess::create(DirAccess::ACCESS_FILESYSTEM);
da->remove(p_path + ".depren");
memdelete(da);
- //fuck it, use the old approach;
+ //use the old approach
WARN_PRINT(("This file is old, so it can't refactor dependencies, opening and resaving: " + p_path).utf8().get_data());
diff --git a/core/io/stream_peer.cpp b/core/io/stream_peer.cpp
index f6c4948fc3..927b9f6366 100644
--- a/core/io/stream_peer.cpp
+++ b/core/io/stream_peer.cpp
@@ -310,7 +310,7 @@ float StreamPeer::get_float() {
return decode_float(buf);
}
-float StreamPeer::get_double() {
+double StreamPeer::get_double() {
uint8_t buf[8];
get_data(buf, 8);
diff --git a/core/io/stream_peer.h b/core/io/stream_peer.h
index ff9ae788ec..605b0a7980 100644
--- a/core/io/stream_peer.h
+++ b/core/io/stream_peer.h
@@ -83,7 +83,7 @@ public:
uint64_t get_u64();
int64_t get_64();
float get_float();
- float get_double();
+ double get_double();
String get_string(int p_bytes);
String get_utf8_string(int p_bytes);
Variant get_var();
diff --git a/core/io/stream_peer_ssl.cpp b/core/io/stream_peer_ssl.cpp
index 633b353102..07a01ff99f 100644
--- a/core/io/stream_peer_ssl.cpp
+++ b/core/io/stream_peer_ssl.cpp
@@ -52,6 +52,7 @@ bool StreamPeerSSL::is_available() {
void StreamPeerSSL::_bind_methods() {
+ ClassDB::bind_method(D_METHOD("poll"), &StreamPeerSSL::poll);
ClassDB::bind_method(D_METHOD("accept_stream", "stream"), &StreamPeerSSL::accept_stream);
ClassDB::bind_method(D_METHOD("connect_to_stream", "stream", "validate_certs", "for_hostname"), &StreamPeerSSL::connect_to_stream, DEFVAL(false), DEFVAL(String()));
ClassDB::bind_method(D_METHOD("get_status"), &StreamPeerSSL::get_status);
diff --git a/core/io/stream_peer_ssl.h b/core/io/stream_peer_ssl.h
index e4d14ebdfd..f903438c28 100644
--- a/core/io/stream_peer_ssl.h
+++ b/core/io/stream_peer_ssl.h
@@ -57,6 +57,7 @@ public:
STATUS_ERROR_HOSTNAME_MISMATCH
};
+ virtual void poll() = 0;
virtual Error accept_stream(Ref<StreamPeer> p_base) = 0;
virtual Error connect_to_stream(Ref<StreamPeer> p_base, bool p_validate_certs = false, const String &p_for_hostname = String()) = 0;
virtual Status get_status() const = 0;
diff --git a/core/make_binders.py b/core/make_binders.py
index 6f42c6e8eb..1e581f8ce3 100644
--- a/core/make_binders.py
+++ b/core/make_binders.py
@@ -244,7 +244,7 @@ def make_version(template, nargs, argmax, const, ret):
def run(target, source, env):
- versions = 11
+ versions = 13
versions_ext = 6
text = ""
text_ext = ""
diff --git a/core/os/os.cpp b/core/os/os.cpp
index c6e5de703c..422acf95dc 100644
--- a/core/os/os.cpp
+++ b/core/os/os.cpp
@@ -616,6 +616,17 @@ bool OS::has_feature(const String &p_feature) {
return false;
}
+void OS::center_window() {
+
+ if (is_window_fullscreen()) return;
+
+ Size2 scr = get_screen_size(get_current_screen());
+ Size2 wnd = get_real_window_size();
+ int x = scr.width / 2 - wnd.width / 2;
+ int y = scr.height / 2 - wnd.height / 2;
+ set_window_position(Vector2(x, y));
+}
+
OS::OS() {
void *volatile stack_bottom;
diff --git a/core/os/os.h b/core/os/os.h
index 248e1dbefa..38e55fa3b7 100644
--- a/core/os/os.h
+++ b/core/os/os.h
@@ -94,15 +94,17 @@ public:
bool resizable;
bool borderless_window;
bool maximized;
+ bool always_on_top;
bool use_vsync;
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_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) {
width = p_width;
height = p_height;
fullscreen = p_fullscreen;
resizable = p_resizable;
borderless_window = p_borderless_window;
maximized = p_maximized;
+ always_on_top = p_always_on_top;
use_vsync = p_use_vsync;
}
};
@@ -182,6 +184,7 @@ public:
virtual Point2 get_window_position() const { return Vector2(); }
virtual void set_window_position(const Point2 &p_position) {}
virtual Size2 get_window_size() const = 0;
+ virtual Size2 get_real_window_size() const { return get_window_size(); }
virtual void set_window_size(const Size2 p_size) {}
virtual void set_window_fullscreen(bool p_enabled) {}
virtual bool is_window_fullscreen() const { return true; }
@@ -191,7 +194,10 @@ public:
virtual bool is_window_minimized() const { return false; }
virtual void set_window_maximized(bool p_enabled) {}
virtual bool is_window_maximized() const { return true; }
+ virtual void set_window_always_on_top(bool p_enabled) {}
+ virtual bool is_window_always_on_top() const { return false; }
virtual void request_attention() {}
+ virtual void center_window();
virtual void set_borderless_window(bool p_borderless) {}
virtual bool get_borderless_window() { return 0; }
diff --git a/core/project_settings.cpp b/core/project_settings.cpp
index 0991c0df68..b7fd6d7318 100644
--- a/core/project_settings.cpp
+++ b/core/project_settings.cpp
@@ -268,12 +268,12 @@ Error ProjectSettings::setup(const String &p_path, const String &p_main_pack, bo
if (FileAccessNetworkClient::get_singleton()) {
- if (_load_settings("res://project.godot") == OK || _load_settings_binary("res://project.binary") == OK) {
-
- _load_settings("res://override.cfg");
+ Error err = _load_settings_text_or_binary("res://project.godot", "res://project.binary");
+ if (err == OK) {
+ // Optional, we don't mind if it fails
+ _load_settings_text("res://override.cfg");
}
-
- return OK;
+ return err;
}
String exec_path = OS::get_singleton()->get_executable_path();
@@ -285,12 +285,13 @@ Error ProjectSettings::setup(const String &p_path, const String &p_main_pack, bo
bool ok = _load_resource_pack(p_main_pack);
ERR_FAIL_COND_V(!ok, ERR_CANT_OPEN);
- if (_load_settings("res://project.godot") == OK || _load_settings_binary("res://project.binary") == OK) {
- //load override from location of the main pack
- _load_settings(p_main_pack.get_base_dir().plus_file("override.cfg"));
+ Error err = _load_settings_text_or_binary("res://project.godot", "res://project.binary");
+ if (err == OK) {
+ // Load override from location of the main pack
+ // Optional, we don't mind if it fails
+ _load_settings_text(p_main_pack.get_base_dir().plus_file("override.cfg"));
}
-
- return OK;
+ return err;
}
//Attempt with execname.pck
@@ -313,12 +314,13 @@ Error ProjectSettings::setup(const String &p_path, const String &p_main_pack, bo
// if we opened our package, try and load our project...
if (found) {
- if (_load_settings("res://project.godot") == OK || _load_settings_binary("res://project.binary") == OK) {
- // load override from location of executable
- _load_settings(exec_path.get_base_dir().plus_file("override.cfg"));
+ Error err = _load_settings_text_or_binary("res://project.godot", "res://project.binary");
+ if (err == OK) {
+ // Load override from location of executable
+ // Optional, we don't mind if it fails
+ _load_settings_text(exec_path.get_base_dir().plus_file("override.cfg"));
}
-
- return OK;
+ return err;
}
}
@@ -334,11 +336,13 @@ Error ProjectSettings::setup(const String &p_path, const String &p_main_pack, bo
// data.pck and data.zip are deprecated and no longer supported, apologies.
// make sure this is loaded from the resource path
- if (_load_settings("res://project.godot") == OK || _load_settings_binary("res://project.binary") == OK) {
- _load_settings("res://override.cfg");
+ Error err = _load_settings_text_or_binary("res://project.godot", "res://project.binary");
+ if (err == OK) {
+ // Optional, we don't mind if it fails
+ _load_settings_text("res://override.cfg");
}
- return OK;
+ return err;
}
//Nothing was found, try to find a project.godot somewhere!
@@ -350,20 +354,23 @@ Error ProjectSettings::setup(const String &p_path, const String &p_main_pack, bo
String candidate = d->get_current_dir();
String current_dir = d->get_current_dir();
+
bool found = false;
+ Error err;
while (true) {
- //try to load settings in ascending through dirs shape!
-
- if (_load_settings(current_dir + "/project.godot") == OK || _load_settings_binary(current_dir + "/project.binary") == OK) {
- _load_settings(current_dir + "/override.cfg");
+ err = _load_settings_text_or_binary(current_dir.plus_file("project.godot"), current_dir.plus_file("project.binary"));
+ if (err == OK) {
+ // Optional, we don't mind if it fails
+ _load_settings_text(current_dir.plus_file("override.cfg"));
candidate = current_dir;
found = true;
break;
}
if (p_upwards) {
+ // Try to load settings ascending through dirs shape!
d->change_dir("..");
if (d->get_current_dir() == current_dir)
break; //not doing anything useful
@@ -378,7 +385,7 @@ Error ProjectSettings::setup(const String &p_path, const String &p_main_pack, bo
memdelete(d);
if (!found)
- return ERR_FILE_NOT_FOUND;
+ return err;
if (resource_path.length() && resource_path[resource_path.length() - 1] == '/')
resource_path = resource_path.substr(0, resource_path.length() - 1); // chop end
@@ -440,7 +447,8 @@ Error ProjectSettings::_load_settings_binary(const String p_path) {
return OK;
}
-Error ProjectSettings::_load_settings(const String p_path) {
+
+Error ProjectSettings::_load_settings_text(const String p_path) {
Error err;
FileAccess *f = FileAccess::open(p_path, FileAccess::READ, &err);
@@ -471,7 +479,7 @@ Error ProjectSettings::_load_settings(const String p_path) {
memdelete(f);
return OK;
} else if (err != OK) {
- ERR_PRINTS("ProjectSettings::load - " + p_path + ":" + itos(lines) + " error: " + error_text);
+ ERR_PRINTS("Error parsing " + p_path + " at line " + itos(lines) + ": " + error_text + " File might be corrupted.");
memdelete(f);
return err;
}
@@ -497,6 +505,22 @@ Error ProjectSettings::_load_settings(const String p_path) {
return OK;
}
+Error ProjectSettings::_load_settings_text_or_binary(const String p_text_path, const String p_bin_path) {
+
+ // Attempt first to load the text-based project.godot file
+ Error err_text = _load_settings_text(p_text_path);
+ if (err_text == OK) {
+ return OK;
+ } else if (err_text != ERR_FILE_NOT_FOUND) {
+ // If the text-based file exists but can't be loaded, we want to know it
+ return err_text;
+ }
+
+ // Fallback to binary project.binary file if text-based was not found
+ Error err_bin = _load_settings_binary(p_bin_path);
+ return err_bin;
+}
+
int ProjectSettings::get_order(const String &p_name) const {
ERR_FAIL_COND_V(!props.has(p_name), -1);
@@ -525,7 +549,7 @@ void ProjectSettings::clear(const String &p_name) {
Error ProjectSettings::save() {
- return save_custom(get_resource_path() + "/project.godot");
+ return save_custom(get_resource_path().plus_file("project.godot"));
}
Error ProjectSettings::_save_settings_binary(const String &p_file, const Map<String, List<String> > &props, const CustomMap &p_custom, const String &p_custom_features) {
diff --git a/core/project_settings.h b/core/project_settings.h
index eba53441cf..9b51bc3ac3 100644
--- a/core/project_settings.h
+++ b/core/project_settings.h
@@ -93,8 +93,9 @@ protected:
static ProjectSettings *singleton;
- Error _load_settings(const String p_path);
+ Error _load_settings_text(const String p_path);
Error _load_settings_binary(const String p_path);
+ Error _load_settings_text_or_binary(const String p_text_path, const String p_bin_path);
Error _save_settings_text(const String &p_file, const Map<String, List<String> > &props, const CustomMap &p_custom = CustomMap(), const String &p_custom_features = String());
Error _save_settings_binary(const String &p_file, const Map<String, List<String> > &props, const CustomMap &p_custom = CustomMap(), const String &p_custom_features = String());
diff --git a/core/translation.cpp b/core/translation.cpp
index 32096d2eab..aaa4de5912 100644
--- a/core/translation.cpp
+++ b/core/translation.cpp
@@ -34,6 +34,14 @@
#include "os/os.h"
#include "project_settings.h"
+// ISO 639-1 language codes, with the addition of glibc locales with their
+// regional identifiers. This list must match the language names (in English)
+// of locale_names.
+//
+// References:
+// - https://en.wikipedia.org/wiki/List_of_ISO_639-1_codes
+// - https://lh.2xlibre.net/locales/
+
static const char *locale_list[] = {
"aa", // Afar
"aa_DJ", // Afar (Djibouti)
@@ -756,8 +764,17 @@ static const char *locale_names[] = {
0
};
+// Windows has some weird locale identifiers which do not honor the ISO 639-1
+// standardized nomenclature. Whenever those don't conflict with existing ISO
+// identifiers, we override them.
+//
+// Reference:
+// - https://msdn.microsoft.com/en-us/library/windows/desktop/ms693062(v=vs.85).aspx
+
static const char *locale_renames[][2] = {
- { "no", "nb" },
+ { "in", "id" }, // Indonesian
+ { "iw", "he" }, // Hebrew
+ { "no", "nb" }, // Norwegian Bokmål
{ NULL, NULL }
};
diff --git a/core/variant_call.cpp b/core/variant_call.cpp
index 5607751a27..d1d45f0e7c 100644
--- a/core/variant_call.cpp
+++ b/core/variant_call.cpp
@@ -443,6 +443,7 @@ struct _VariantCall {
VCALL_LOCALMEM1R(Color, lightened);
VCALL_LOCALMEM1R(Color, darkened);
VCALL_LOCALMEM1R(Color, to_html);
+ VCALL_LOCALMEM4R(Color, from_hsv);
VCALL_LOCALMEM0R(RID, get_id);
@@ -490,6 +491,7 @@ struct _VariantCall {
VCALL_LOCALMEM1(Array, erase);
VCALL_LOCALMEM0(Array, sort);
VCALL_LOCALMEM2(Array, sort_custom);
+ VCALL_LOCALMEM0(Array, shuffle);
VCALL_LOCALMEM2R(Array, bsearch);
VCALL_LOCALMEM4R(Array, bsearch_custom);
VCALL_LOCALMEM0R(Array, duplicate);
@@ -1589,6 +1591,7 @@ void register_variant_methods() {
ADDFUNC1R(COLOR, COLOR, Color, lightened, REAL, "amount", varray());
ADDFUNC1R(COLOR, COLOR, Color, darkened, REAL, "amount", varray());
ADDFUNC1R(COLOR, STRING, Color, to_html, BOOL, "with_alpha", varray(true));
+ ADDFUNC4R(COLOR, COLOR, Color, from_hsv, REAL, "h", REAL, "s", REAL, "v", REAL, "a", varray(1.0));
ADDFUNC0R(_RID, INT, RID, get_id, varray());
@@ -1634,6 +1637,7 @@ void register_variant_methods() {
ADDFUNC0RNC(ARRAY, NIL, Array, pop_front, varray());
ADDFUNC0NC(ARRAY, NIL, Array, sort, varray());
ADDFUNC2NC(ARRAY, NIL, Array, sort_custom, OBJECT, "obj", STRING, "func", varray());
+ ADDFUNC0NC(ARRAY, NIL, Array, shuffle, varray());
ADDFUNC2R(ARRAY, INT, Array, bsearch, NIL, "value", BOOL, "before", varray(true));
ADDFUNC4R(ARRAY, INT, Array, bsearch_custom, NIL, "value", OBJECT, "obj", STRING, "func", BOOL, "before", varray(true));
ADDFUNC0NC(ARRAY, NIL, Array, invert, varray());