diff options
174 files changed, 2901 insertions, 1652 deletions
diff --git a/.travis.yml b/.travis.yml index c11a21aeef..0dfeaf16e1 100644 --- a/.travis.yml +++ b/.travis.yml @@ -48,14 +48,14 @@ addons: - pkg-config - libx11-dev - libxcursor-dev - - libasound2-dev - - libfreetype6-dev + - libxi-dev + - libxinerama-dev + - libxrandr-dev - libgl1-mesa-dev - libglu1-mesa-dev + - libasound2-dev + - libfreetype6-dev - libssl-dev - - libxinerama-dev - - libxrandr-dev - - libxi-dev # For cross-compiling to Windows. #- binutils-mingw-w64-i686 @@ -90,5 +90,5 @@ script: - if [ "$STATIC_CHECKS" = "yes" ]; then sh ./misc/travis/clang-format.sh; else - scons -j2 CC=$CC CXX=$CXX platform=$GODOT_TARGET TOOLS=$TOOLS verbose=yes progress=no; + scons -j2 CC=$CC CXX=$CXX platform=$GODOT_TARGET TOOLS=$TOOLS verbose=yes progress=no openmp=no; fi diff --git a/SConstruct b/SConstruct index 4f2df947c6..ad6b6ee445 100644 --- a/SConstruct +++ b/SConstruct @@ -169,7 +169,7 @@ opts.Add(EnumVariable('warnings', "Set the level of warnings emitted during comp opts.Add(BoolVariable('progress', "Show a progress indicator during build", True)) opts.Add(BoolVariable('dev', "If yes, alias for verbose=yes warnings=all", False)) opts.Add(BoolVariable('openmp', "If yes, enable OpenMP", True)) -opts.Add(BoolVariable('macports_clang', "Build using clang-5.0 from MacPorts", False)) +opts.Add(EnumVariable('macports_clang', "Build using clang from MacPorts", 'no', ('no', '5.0', 'devel'))) # Thirdparty libraries opts.Add(BoolVariable('builtin_enet', "Use the builtin enet library", True)) @@ -188,6 +188,7 @@ opts.Add(BoolVariable('builtin_squish', "Use the builtin squish library", True)) opts.Add(BoolVariable('builtin_thekla_atlas', "Use the builtin thekla_altas library", True)) opts.Add(BoolVariable('builtin_zlib', "Use the builtin zlib library", True)) opts.Add(BoolVariable('builtin_zstd', "Use the builtin zstd library", True)) +opts.Add(BoolVariable('no_editor_splash', "Don't use the custom splash screen for the editor", False)) # Environment setup opts.Add("CXX", "C++ compiler") @@ -239,6 +240,9 @@ if (env_base['target'] == 'debug'): env_base.Append(CPPFLAGS=['-DDEBUG_MEMORY_ALLOC']) env_base.Append(CPPFLAGS=['-DSCI_NAMESPACE']) +if (env_base['no_editor_splash']): + env_base.Append(CPPFLAGS=['-DNO_EDITOR_SPLASH']) + if not env_base['deprecated']: env_base.Append(CPPFLAGS=['-DDISABLE_DEPRECATED']) diff --git a/core/class_db.cpp b/core/class_db.cpp index edd49fe95f..b18e3d2b65 100644 --- a/core/class_db.cpp +++ b/core/class_db.cpp @@ -348,10 +348,11 @@ uint64_t ClassDB::get_api_hash(APIType p_api) { hash = hash_djb2_one_64(mb->get_argument_type(-1), hash); //return for (int i = 0; i < mb->get_argument_count(); i++) { - hash = hash_djb2_one_64(mb->get_argument_info(i).type, hash); - hash = hash_djb2_one_64(mb->get_argument_info(i).name.hash(), hash); - hash = hash_djb2_one_64(mb->get_argument_info(i).hint, hash); - hash = hash_djb2_one_64(mb->get_argument_info(i).hint_string.hash(), hash); + const PropertyInfo info = mb->get_argument_info(i); + hash = hash_djb2_one_64(info.type, hash); + hash = hash_djb2_one_64(info.name.hash(), hash); + hash = hash_djb2_one_64(info.hint, hash); + hash = hash_djb2_one_64(info.hint_string.hash(), hash); } hash = hash_djb2_one_64(mb->get_default_argument_count(), hash); diff --git a/core/io/http_client.cpp b/core/io/http_client.cpp index 9d89baafb1..e457a4ac1e 100644 --- a/core/io/http_client.cpp +++ b/core/io/http_client.cpp @@ -30,27 +30,53 @@ #include "http_client.h" #include "io/stream_peer_ssl.h" +const char *HTTPClient::_methods[METHOD_MAX] = { + "GET", + "HEAD", + "POST", + "PUT", + "DELETE", + "OPTIONS", + "TRACE", + "CONNECT", + "PATCH" +}; + #ifndef JAVASCRIPT_ENABLED Error HTTPClient::connect_to_host(const String &p_host, int p_port, bool p_ssl, bool p_verify_host) { close(); + conn_port = p_port; conn_host = p_host; - if (conn_host.begins_with("http://")) { + ssl = p_ssl; + ssl_verify_host = p_verify_host; + + String host_lower = conn_host.to_lower(); + if (host_lower.begins_with("http://")) { - conn_host = conn_host.replace_first("http://", ""); - } else if (conn_host.begins_with("https://")) { - //use https - conn_host = conn_host.replace_first("https://", ""); + conn_host = conn_host.substr(7, conn_host.length() - 7); + } else if (host_lower.begins_with("https://")) { + + ssl = true; + conn_host = conn_host.substr(8, conn_host.length() - 8); + } + + ERR_FAIL_COND_V(conn_host.length() < HOST_MIN_LEN, ERR_INVALID_PARAMETER); + + if (conn_port < 0) { + if (ssl) { + conn_port = PORT_HTTPS; + } else { + conn_port = PORT_HTTP; + } } - ssl = p_ssl; - ssl_verify_host = p_verify_host; connection = tcp_connection; if (conn_host.is_valid_ip_address()) { - //is ip + // Host contains valid IP Error err = tcp_connection->connect_to_host(IP_Address(conn_host), p_port); if (err) { status = STATUS_CANT_CONNECT; @@ -59,7 +85,7 @@ Error HTTPClient::connect_to_host(const String &p_host, int p_port, bool p_ssl, status = STATUS_CONNECTING; } else { - //is hostname + // Host contains hostname and needs to be resolved to IP resolving = IP::get_singleton()->resolve_hostname_queue_item(conn_host); status = STATUS_RESOLVING; } @@ -82,24 +108,13 @@ Ref<StreamPeer> HTTPClient::get_connection() const { Error HTTPClient::request_raw(Method p_method, const String &p_url, const Vector<String> &p_headers, const PoolVector<uint8_t> &p_body) { ERR_FAIL_INDEX_V(p_method, METHOD_MAX, ERR_INVALID_PARAMETER); + ERR_FAIL_COND_V(!p_url.begins_with("/"), ERR_INVALID_PARAMETER); ERR_FAIL_COND_V(status != STATUS_CONNECTED, ERR_INVALID_PARAMETER); ERR_FAIL_COND_V(connection.is_null(), ERR_INVALID_DATA); - static const char *_methods[METHOD_MAX] = { - "GET", - "HEAD", - "POST", - "PUT", - "DELETE", - "OPTIONS", - "TRACE", - "CONNECT", - "PATCH" - }; - String request = String(_methods[p_method]) + " " + p_url + " HTTP/1.1\r\n"; - if ((ssl && conn_port == 443) || (!ssl && conn_port == 80)) { - // don't append the standard ports + if ((ssl && conn_port == PORT_HTTPS) || (!ssl && conn_port == PORT_HTTP)) { + // Don't append the standard ports request += "Host: " + conn_host + "\r\n"; } else { request += "Host: " + conn_host + ":" + itos(conn_port) + "\r\n"; @@ -113,17 +128,20 @@ Error HTTPClient::request_raw(Method p_method, const String &p_url, const Vector } if (add_clen) { request += "Content-Length: " + itos(p_body.size()) + "\r\n"; - //should it add utf8 encoding? not sure + // Should it add utf8 encoding? } request += "\r\n"; CharString cs = request.utf8(); PoolVector<uint8_t> data; - - //Maybe this goes faster somehow? - for (int i = 0; i < cs.length(); i++) { - data.append(cs[i]); + data.resize(cs.length()); + { + PoolVector<uint8_t>::Write data_write = data.write(); + for (int i = 0; i < cs.length(); i++) { + data_write[i] = cs[i]; + } } + data.append_array(p_body); PoolVector<uint8_t>::Read r = data.read(); @@ -143,24 +161,13 @@ Error HTTPClient::request_raw(Method p_method, const String &p_url, const Vector Error HTTPClient::request(Method p_method, const String &p_url, const Vector<String> &p_headers, const String &p_body) { ERR_FAIL_INDEX_V(p_method, METHOD_MAX, ERR_INVALID_PARAMETER); + ERR_FAIL_COND_V(!p_url.begins_with("/"), ERR_INVALID_PARAMETER); ERR_FAIL_COND_V(status != STATUS_CONNECTED, ERR_INVALID_PARAMETER); ERR_FAIL_COND_V(connection.is_null(), ERR_INVALID_DATA); - static const char *_methods[METHOD_MAX] = { - "GET", - "HEAD", - "POST", - "PUT", - "DELETE", - "OPTIONS", - "TRACE", - "CONNECT", - "PATCH" - }; - String request = String(_methods[p_method]) + " " + p_url + " HTTP/1.1\r\n"; - if ((ssl && conn_port == 443) || (!ssl && conn_port == 80)) { - // don't append the standard ports + if ((ssl && conn_port == PORT_HTTPS) || (!ssl && conn_port == PORT_HTTP)) { + // Don't append the standard ports request += "Host: " + conn_host + "\r\n"; } else { request += "Host: " + conn_host + ":" + itos(conn_port) + "\r\n"; @@ -174,7 +181,7 @@ Error HTTPClient::request(Method p_method, const String &p_url, const Vector<Str } if (add_clen) { request += "Content-Length: " + itos(p_body.utf8().length()) + "\r\n"; - //should it add utf8 encoding? not sure + // Should it add utf8 encoding? } request += "\r\n"; request += p_body; @@ -253,7 +260,7 @@ Error HTTPClient::poll() { IP::ResolverStatus rstatus = IP::get_singleton()->get_resolve_item_status(resolving); switch (rstatus) { case IP::RESOLVER_STATUS_WAITING: - return OK; //still resolving + return OK; // Still resolving case IP::RESOLVER_STATUS_DONE: { @@ -285,7 +292,7 @@ Error HTTPClient::poll() { switch (s) { case StreamPeerTCP::STATUS_CONNECTING: { - return OK; //do none + return OK; } break; case StreamPeerTCP::STATUS_CONNECTED: { if (ssl) { @@ -296,7 +303,6 @@ Error HTTPClient::poll() { status = STATUS_SSL_HANDSHAKE_ERROR; return ERR_CANT_CONNECT; } - //print_line("SSL! TURNED ON!"); connection = ssl; } status = STATUS_CONNECTED; @@ -312,7 +318,7 @@ Error HTTPClient::poll() { } } break; case STATUS_CONNECTED: { - //request something please + // Connection established, requests can now be made return OK; } break; case STATUS_REQUESTING: { @@ -328,7 +334,7 @@ Error HTTPClient::poll() { } if (rec == 0) - return OK; //keep trying! + return OK; // Still requesting, keep trying! response_str.push_back(byte); int rs = response_str.size(); @@ -336,11 +342,10 @@ Error HTTPClient::poll() { (rs >= 2 && response_str[rs - 2] == '\n' && response_str[rs - 1] == '\n') || (rs >= 4 && response_str[rs - 4] == '\r' && response_str[rs - 3] == '\n' && response_str[rs - 2] == '\r' && response_str[rs - 1] == '\n')) { - //end of response, parse. + // End of response, parse. response_str.push_back(0); String response; response.parse_utf8((const char *)response_str.ptr()); - //print_line("END OF RESPONSE? :\n"+response+"\n------"); Vector<String> responses = response.split("\n"); body_size = 0; chunked = false; @@ -363,7 +368,6 @@ Error HTTPClient::poll() { if (s.begins_with("transfer-encoding:")) { String encoding = header.substr(header.find(":") + 1, header.length()).strip_edges(); - //print_line("TRANSFER ENCODING: "+encoding); if (encoding == "chunked") { chunked = true; } @@ -381,14 +385,14 @@ Error HTTPClient::poll() { if (body_size == 0 && !chunked) { - status = STATUS_CONNECTED; //ask for something again? + status = STATUS_CONNECTED; // Ready for new requests } else { status = STATUS_BODY; } return OK; } } - //wait for response + // Wait for response return OK; } break; case STATUS_DISCONNECTED: { @@ -424,7 +428,7 @@ PoolByteArray HTTPClient::read_response_body_chunk() { while (true) { if (chunk_left == 0) { - //reading len + // Reading length uint8_t b; int rec = 0; err = _get_http_data(&b, 1, rec); @@ -467,7 +471,7 @@ PoolByteArray HTTPClient::read_response_body_chunk() { } if (len == 0) { - //end! + // End reached! status = STATUS_CONNECTED; chunk.clear(); return PoolByteArray(); @@ -525,7 +529,7 @@ PoolByteArray HTTPClient::read_response_body_chunk() { to_read -= rec; _offset += rec; } else { - if (to_read > 0) //ended up reading less + if (to_read > 0) // Ended up reading less ret.resize(_offset); break; } @@ -540,7 +544,7 @@ PoolByteArray HTTPClient::read_response_body_chunk() { close(); if (err == ERR_FILE_EOF) { - status = STATUS_DISCONNECTED; //server disconnected + status = STATUS_DISCONNECTED; // Server disconnected } else { status = STATUS_CONNECTION_ERROR; @@ -593,7 +597,7 @@ HTTPClient::HTTPClient() { tcp_connection = StreamPeerTCP::create_ref(); resolving = IP::RESOLVER_INVALID_ID; status = STATUS_DISCONNECTED; - conn_port = 80; + conn_port = -1; body_size = 0; chunked = false; body_left = 0; @@ -653,7 +657,7 @@ PoolStringArray HTTPClient::_get_response_headers() { void HTTPClient::_bind_methods() { - ClassDB::bind_method(D_METHOD("connect_to_host", "host", "port", "use_ssl", "verify_host"), &HTTPClient::connect_to_host, DEFVAL(false), DEFVAL(true)); + ClassDB::bind_method(D_METHOD("connect_to_host", "host", "port", "use_ssl", "verify_host"), &HTTPClient::connect_to_host, DEFVAL(-1), DEFVAL(false), DEFVAL(true)); ClassDB::bind_method(D_METHOD("set_connection", "connection"), &HTTPClient::set_connection); ClassDB::bind_method(D_METHOD("get_connection"), &HTTPClient::get_connection); ClassDB::bind_method(D_METHOD("request_raw", "method", "url", "headers", "body"), &HTTPClient::request_raw); @@ -689,13 +693,13 @@ void HTTPClient::_bind_methods() { BIND_ENUM_CONSTANT(METHOD_MAX); BIND_ENUM_CONSTANT(STATUS_DISCONNECTED); - BIND_ENUM_CONSTANT(STATUS_RESOLVING); //resolving hostname (if passed a hostname) + BIND_ENUM_CONSTANT(STATUS_RESOLVING); // Resolving hostname (if hostname was passed in) BIND_ENUM_CONSTANT(STATUS_CANT_RESOLVE); - BIND_ENUM_CONSTANT(STATUS_CONNECTING); //connecting to ip + BIND_ENUM_CONSTANT(STATUS_CONNECTING); // Connecting to IP BIND_ENUM_CONSTANT(STATUS_CANT_CONNECT); - BIND_ENUM_CONSTANT(STATUS_CONNECTED); //connected ); requests only accepted here - BIND_ENUM_CONSTANT(STATUS_REQUESTING); // request in progress - BIND_ENUM_CONSTANT(STATUS_BODY); // request resulted in body ); which must be read + BIND_ENUM_CONSTANT(STATUS_CONNECTED); // Connected, now accepting requests + BIND_ENUM_CONSTANT(STATUS_REQUESTING); // Request in progress + BIND_ENUM_CONSTANT(STATUS_BODY); // Request resulted in body which must be read BIND_ENUM_CONSTANT(STATUS_CONNECTION_ERROR); BIND_ENUM_CONSTANT(STATUS_SSL_HANDSHAKE_ERROR); diff --git a/core/io/http_client.h b/core/io/http_client.h index 2e0a345f1c..3d8953c156 100644 --- a/core/io/http_client.h +++ b/core/io/http_client.h @@ -133,19 +133,29 @@ public: enum Status { STATUS_DISCONNECTED, - STATUS_RESOLVING, //resolving hostname (if passed a hostname) + STATUS_RESOLVING, // Resolving hostname (if passed a hostname) STATUS_CANT_RESOLVE, - STATUS_CONNECTING, //connecting to ip + STATUS_CONNECTING, // Connecting to IP STATUS_CANT_CONNECT, - STATUS_CONNECTED, //connected, requests only accepted here - STATUS_REQUESTING, // request in progress - STATUS_BODY, // request resulted in body, which must be read + STATUS_CONNECTED, // Connected, requests can be made + STATUS_REQUESTING, // Request in progress + STATUS_BODY, // Request resulted in body, which must be read STATUS_CONNECTION_ERROR, STATUS_SSL_HANDSHAKE_ERROR, }; private: + static const char *_methods[METHOD_MAX]; + static const int HOST_MIN_LEN = 4; + + enum Port { + + PORT_HTTP = 80, + PORT_HTTPS = 443, + + }; + #ifndef JAVASCRIPT_ENABLED Status status; IP::ResolverID resolving; @@ -182,8 +192,7 @@ private: static void _bind_methods(); public: - //Error connect_and_get(const String& p_url,bool p_verify_host=true); //connects to a full url and perform request - Error connect_to_host(const String &p_host, int p_port, bool p_ssl = false, bool p_verify_host = true); + Error connect_to_host(const String &p_host, int p_port = -1, bool p_ssl = false, bool p_verify_host = true); void set_connection(const Ref<StreamPeer> &p_connection); Ref<StreamPeer> get_connection() const; @@ -201,9 +210,9 @@ public: Error get_response_headers(List<String> *r_response); int get_response_body_length() const; - PoolByteArray read_response_body_chunk(); // can't get body as partial text because of most encodings UTF8, gzip, etc. + PoolByteArray read_response_body_chunk(); // Can't get body as partial text because of most encodings UTF8, gzip, etc. - void set_blocking_mode(bool p_enable); //useful mostly if running in a thread + void set_blocking_mode(bool p_enable); // Useful mostly if running in a thread bool is_blocking_mode_enabled() const; void set_read_chunk_size(int p_size); diff --git a/core/io/packet_peer.cpp b/core/io/packet_peer.cpp index 16c73c26e7..c6b12f73ae 100644 --- a/core/io/packet_peer.cpp +++ b/core/io/packet_peer.cpp @@ -49,7 +49,7 @@ bool PacketPeer::is_object_decoding_allowed() const { return allow_object_decoding; } -Error PacketPeer::get_packet_buffer(PoolVector<uint8_t> &r_buffer) const { +Error PacketPeer::get_packet_buffer(PoolVector<uint8_t> &r_buffer) { const uint8_t *buffer; int buffer_size; @@ -78,7 +78,7 @@ Error PacketPeer::put_packet_buffer(const PoolVector<uint8_t> &p_buffer) { return put_packet(&r[0], len); } -Error PacketPeer::get_var(Variant &r_variant) const { +Error PacketPeer::get_var(Variant &r_variant) { const uint8_t *buffer; int buffer_size; @@ -107,7 +107,7 @@ Error PacketPeer::put_var(const Variant &p_packet) { return put_packet(buf, len); } -Variant PacketPeer::_bnd_get_var() const { +Variant PacketPeer::_bnd_get_var() { Variant var; get_var(var); @@ -117,7 +117,7 @@ Variant PacketPeer::_bnd_get_var() const { Error PacketPeer::_put_packet(const PoolVector<uint8_t> &p_buffer) { return put_packet_buffer(p_buffer); } -PoolVector<uint8_t> PacketPeer::_get_packet() const { +PoolVector<uint8_t> PacketPeer::_get_packet() { PoolVector<uint8_t> raw; last_get_error = get_packet_buffer(raw); @@ -202,7 +202,7 @@ int PacketPeerStream::get_available_packet_count() const { return count; } -Error PacketPeerStream::get_packet(const uint8_t **r_buffer, int &r_buffer_size) const { +Error PacketPeerStream::get_packet(const uint8_t **r_buffer, int &r_buffer_size) { ERR_FAIL_COND_V(peer.is_null(), ERR_UNCONFIGURED); _poll_buffer(); diff --git a/core/io/packet_peer.h b/core/io/packet_peer.h index b08d44ad8a..a6d363ec12 100644 --- a/core/io/packet_peer.h +++ b/core/io/packet_peer.h @@ -37,13 +37,13 @@ class PacketPeer : public Reference { GDCLASS(PacketPeer, Reference); - Variant _bnd_get_var() const; + Variant _bnd_get_var(); void _bnd_put_var(const Variant &p_var); static void _bind_methods(); Error _put_packet(const PoolVector<uint8_t> &p_buffer); - PoolVector<uint8_t> _get_packet() const; + PoolVector<uint8_t> _get_packet(); Error _get_packet_error() const; mutable Error last_get_error; @@ -52,17 +52,17 @@ class PacketPeer : public Reference { public: virtual int get_available_packet_count() const = 0; - virtual Error get_packet(const uint8_t **r_buffer, int &r_buffer_size) const = 0; ///< buffer is GONE after next get_packet + virtual Error get_packet(const uint8_t **r_buffer, int &r_buffer_size) = 0; ///< buffer is GONE after next get_packet virtual Error put_packet(const uint8_t *p_buffer, int p_buffer_size) = 0; virtual int get_max_packet_size() const = 0; /* helpers / binders */ - virtual Error get_packet_buffer(PoolVector<uint8_t> &r_buffer) const; + virtual Error get_packet_buffer(PoolVector<uint8_t> &r_buffer); virtual Error put_packet_buffer(const PoolVector<uint8_t> &p_buffer); - virtual Error get_var(Variant &r_variant) const; + virtual Error get_var(Variant &r_variant); virtual Error put_var(const Variant &p_packet); void set_allow_object_decoding(bool p_enable); @@ -91,7 +91,7 @@ protected: public: virtual int get_available_packet_count() const; - virtual Error get_packet(const uint8_t **r_buffer, int &r_buffer_size) const; + virtual Error get_packet(const uint8_t **r_buffer, int &r_buffer_size); virtual Error put_packet(const uint8_t *p_buffer, int p_buffer_size); virtual int get_max_packet_size() const; diff --git a/core/io/resource_format_binary.cpp b/core/io/resource_format_binary.cpp index df0d41ea9d..92fdbc1581 100644 --- a/core/io/resource_format_binary.cpp +++ b/core/io/resource_format_binary.cpp @@ -104,7 +104,7 @@ StringName ResourceInteractiveLoaderBinary::_get_string() { uint32_t id = f->get_32(); if (id & 0x80000000) { - int len = id & 0x7FFFFFFF; + uint32_t len = id & 0x7FFFFFFF; if (len > str_buf.size()) { str_buf.resize(len); } @@ -734,6 +734,7 @@ Error ResourceInteractiveLoaderBinary::poll() { for (int i = 0; i < pc; i++) { StringName name = _get_string(); + if (name == StringName()) { error = ERR_FILE_CORRUPT; ERR_FAIL_V(ERR_FILE_CORRUPT); @@ -902,7 +903,9 @@ void ResourceInteractiveLoaderBinary::open(FileAccess *p_f) { ExtResource er; er.type = get_unicode_string(); + er.path = get_unicode_string(); + external_resources.push_back(er); } @@ -1271,7 +1274,7 @@ String ResourceFormatLoaderBinary::get_resource_type(const String &p_path) const /////////////////////////////////////////////////////////// /////////////////////////////////////////////////////////// -void ResourceFormatSaverBinaryInstance::_pad_buffer(int p_bytes) { +void ResourceFormatSaverBinaryInstance::_pad_buffer(FileAccess *f, int p_bytes) { int extra = 4 - (p_bytes % 4); if (extra < 4) { @@ -1280,7 +1283,12 @@ void ResourceFormatSaverBinaryInstance::_pad_buffer(int p_bytes) { } } -void ResourceFormatSaverBinaryInstance::write_variant(const Variant &p_property, const PropertyInfo &p_hint) { +void ResourceFormatSaverBinaryInstance::_write_variant(const Variant &p_property, const PropertyInfo &p_hint) { + + write_variant(f, p_property, resource_set, external_resources, string_map, p_hint); +} + +void ResourceFormatSaverBinaryInstance::write_variant(FileAccess *f, const Variant &p_property, Set<RES> &resource_set, Map<RES, int> &external_resources, Map<StringName, int> &string_map, const PropertyInfo &p_hint) { switch (p_property.get_type()) { @@ -1327,7 +1335,7 @@ void ResourceFormatSaverBinaryInstance::write_variant(const Variant &p_property, f->store_32(VARIANT_STRING); String val = p_property; - save_unicode_string(val); + save_unicode_string(f, val); } break; case Variant::VECTOR2: { @@ -1453,10 +1461,20 @@ void ResourceFormatSaverBinaryInstance::write_variant(const Variant &p_property, if (np.is_absolute()) snc |= 0x8000; f->store_16(snc); - for (int i = 0; i < np.get_name_count(); i++) - f->store_32(get_string_index(np.get_name(i))); - for (int i = 0; i < np.get_subname_count(); i++) - f->store_32(get_string_index(np.get_subname(i))); + for (int i = 0; i < np.get_name_count(); i++) { + if (string_map.has(np.get_name(i))) { + f->store_32(string_map[np.get_name(i)]); + } else { + save_unicode_string(f, np.get_name(i), true); + } + } + for (int i = 0; i < np.get_subname_count(); i++) { + if (string_map.has(np.get_subname(i))) { + f->store_32(string_map[np.get_subname(i)]); + } else { + save_unicode_string(f, np.get_subname(i), true); + } + } } break; case Variant::_RID: { @@ -1508,8 +1526,8 @@ void ResourceFormatSaverBinaryInstance::write_variant(const Variant &p_property, continue; */ - write_variant(E->get()); - write_variant(d[E->get()]); + write_variant(f, E->get(), resource_set, external_resources, string_map); + write_variant(f, d[E->get()], resource_set, external_resources, string_map); } } break; @@ -1520,7 +1538,7 @@ void ResourceFormatSaverBinaryInstance::write_variant(const Variant &p_property, f->store_32(uint32_t(a.size())); for (int i = 0; i < a.size(); i++) { - write_variant(a[i]); + write_variant(f, a[i], resource_set, external_resources, string_map); } } break; @@ -1532,7 +1550,7 @@ void ResourceFormatSaverBinaryInstance::write_variant(const Variant &p_property, f->store_32(len); PoolVector<uint8_t>::Read r = arr.read(); f->store_buffer(r.ptr(), len); - _pad_buffer(len); + _pad_buffer(f, len); } break; case Variant::POOL_INT_ARRAY: { @@ -1566,7 +1584,7 @@ void ResourceFormatSaverBinaryInstance::write_variant(const Variant &p_property, f->store_32(len); PoolVector<String>::Read r = arr.read(); for (int i = 0; i < len; i++) { - save_unicode_string(r[i]); + save_unicode_string(f, r[i]); } } break; @@ -1693,10 +1711,14 @@ void ResourceFormatSaverBinaryInstance::_find_resources(const Variant &p_variant } } -void ResourceFormatSaverBinaryInstance::save_unicode_string(const String &p_string) { +void ResourceFormatSaverBinaryInstance::save_unicode_string(FileAccess *f, const String &p_string, bool p_bit_on_len) { CharString utf8 = p_string.utf8(); - f->store_32(utf8.length() + 1); + if (p_bit_on_len) { + f->store_32(utf8.length() + 1 | 0x80000000); + } else { + f->store_32(utf8.length() + 1); + } f->store_buffer((const uint8_t *)utf8.get_data(), utf8.length() + 1); } @@ -1763,7 +1785,7 @@ Error ResourceFormatSaverBinaryInstance::save(const String &p_path, const RES &p return ERR_CANT_CREATE; } - save_unicode_string(p_resource->get_class()); + save_unicode_string(f, p_resource->get_class()); f->store_64(0); //offset to import metadata for (int i = 0; i < 14; i++) f->store_32(0); // reserved @@ -1800,7 +1822,7 @@ Error ResourceFormatSaverBinaryInstance::save(const String &p_path, const RES &p f->store_32(strings.size()); //string table size for (int i = 0; i < strings.size(); i++) { - save_unicode_string(strings[i]); + save_unicode_string(f, strings[i]); } // save external resource table @@ -1814,10 +1836,10 @@ Error ResourceFormatSaverBinaryInstance::save(const String &p_path, const RES &p for (int i = 0; i < save_order.size(); i++) { - save_unicode_string(save_order[i]->get_save_class()); + save_unicode_string(f, save_order[i]->get_save_class()); String path = save_order[i]->get_path(); path = relative_paths ? local_path.path_to_file(path) : path; - save_unicode_string(path); + save_unicode_string(f, path); } // save internal resource table f->store_32(saved_resources.size()); //amount of internal resources @@ -1853,7 +1875,7 @@ Error ResourceFormatSaverBinaryInstance::save(const String &p_path, const RES &p used_indices.insert(new_subindex); } - save_unicode_string("local://" + itos(r->get_subindex())); + save_unicode_string(f, "local://" + itos(r->get_subindex())); if (takeover_paths) { r->set_path(p_path + "::" + itos(r->get_subindex()), true); } @@ -1861,7 +1883,7 @@ Error ResourceFormatSaverBinaryInstance::save(const String &p_path, const RES &p r->set_edited(false); #endif } else { - save_unicode_string(r->get_path()); //actual external + save_unicode_string(f, r->get_path()); //actual external } ofs_pos.push_back(f->get_position()); f->store_64(0); //offset in 64 bits @@ -1875,14 +1897,14 @@ Error ResourceFormatSaverBinaryInstance::save(const String &p_path, const RES &p ResourceData &rd = E->get(); ofs_table.push_back(f->get_position()); - save_unicode_string(rd.type); + save_unicode_string(f, rd.type); f->store_32(rd.properties.size()); for (List<Property>::Element *F = rd.properties.front(); F; F = F->next()) { Property &p = F->get(); f->store_32(p.name_idx); - write_variant(p.value, F->get().pi); + _write_variant(p.value, F->get().pi); } } diff --git a/core/io/resource_format_binary.h b/core/io/resource_format_binary.h index 687da0a9b4..176b8350cf 100644 --- a/core/io/resource_format_binary.h +++ b/core/io/resource_format_binary.h @@ -140,14 +140,15 @@ class ResourceFormatSaverBinaryInstance { List<Property> properties; }; - void _pad_buffer(int p_bytes); - void write_variant(const Variant &p_property, const PropertyInfo &p_hint = PropertyInfo()); + static void _pad_buffer(FileAccess *f, int p_bytes); + void _write_variant(const Variant &p_property, const PropertyInfo &p_hint = PropertyInfo()); void _find_resources(const Variant &p_variant, bool p_main = false); - void save_unicode_string(const String &p_string); + static void save_unicode_string(FileAccess *f, const String &p_string, bool p_bit_on_len = false); int get_string_index(const String &p_string); public: Error save(const String &p_path, const RES &p_resource, uint32_t p_flags = 0); + static void write_variant(FileAccess *f, const Variant &p_property, Set<RES> &resource_set, Map<RES, int> &external_resources, Map<StringName, int> &string_map, const PropertyInfo &p_hint = PropertyInfo()); }; class ResourceFormatSaverBinary : public ResourceFormatSaver { diff --git a/core/io/resource_loader.cpp b/core/io/resource_loader.cpp index ed0d491679..d2aad1d63a 100644 --- a/core/io/resource_loader.cpp +++ b/core/io/resource_loader.cpp @@ -196,19 +196,19 @@ RES ResourceLoader::load(const String &p_path, const String &p_type_hint, bool p else local_path = ProjectSettings::get_singleton()->localize_path(p_path); - bool xl_remapped = false; - String path = _path_remap(local_path, &xl_remapped); - - ERR_FAIL_COND_V(path == "", RES()); - - if (!p_no_cache && ResourceCache::has(path)) { + if (!p_no_cache && ResourceCache::has(local_path)) { if (OS::get_singleton()->is_stdout_verbose()) - print_line("load resource: " + path + " (cached)"); + print_line("load resource: " + local_path + " (cached)"); - return RES(ResourceCache::get(path)); + return RES(ResourceCache::get(local_path)); } + bool xl_remapped = false; + String path = _path_remap(local_path, &xl_remapped); + + ERR_FAIL_COND_V(path == "", RES()); + if (OS::get_singleton()->is_stdout_verbose()) print_line("load resource: " + path); @@ -247,23 +247,23 @@ Ref<ResourceInteractiveLoader> ResourceLoader::load_interactive(const String &p_ else local_path = ProjectSettings::get_singleton()->localize_path(p_path); - bool xl_remapped = false; - String path = _path_remap(local_path, &xl_remapped); - - ERR_FAIL_COND_V(path == "", Ref<ResourceInteractiveLoader>()); - - if (!p_no_cache && ResourceCache::has(path)) { + if (!p_no_cache && ResourceCache::has(local_path)) { if (OS::get_singleton()->is_stdout_verbose()) - print_line("load resource: " + path + " (cached)"); + print_line("load resource: " + local_path + " (cached)"); - Ref<Resource> res_cached = ResourceCache::get(path); + Ref<Resource> res_cached = ResourceCache::get(local_path); Ref<ResourceInteractiveLoaderDefault> ril = Ref<ResourceInteractiveLoaderDefault>(memnew(ResourceInteractiveLoaderDefault)); ril->resource = res_cached; return ril; } + bool xl_remapped = false; + String path = _path_remap(local_path, &xl_remapped); + + ERR_FAIL_COND_V(path == "", Ref<ResourceInteractiveLoader>()); + if (OS::get_singleton()->is_stdout_verbose()) print_line("load resource: "); @@ -426,9 +426,11 @@ String ResourceLoader::get_resource_type(const String &p_path) { String ResourceLoader::_path_remap(const String &p_path, bool *r_translation_remapped) { - if (translation_remaps.has(p_path)) { + String new_path = p_path; - Vector<String> &v = *translation_remaps.getptr(p_path); + if (translation_remaps.has(new_path)) { + + Vector<String> &v = *translation_remaps.getptr(new_path); String locale = TranslationServer::get_singleton()->get_locale(); if (r_translation_remapped) { *r_translation_remapped = true; @@ -443,12 +445,16 @@ String ResourceLoader::_path_remap(const String &p_path, bool *r_translation_rem continue; if (l.begins_with(locale)) { - return v[i].left(split); + new_path = v[i].left(split); + break; } } } - return p_path; + if (path_remaps.has(new_path)) { + new_path = path_remaps[new_path]; + } + return new_path; } String ResourceLoader::import_remap(const String &p_path) { @@ -515,6 +521,27 @@ void ResourceLoader::clear_translation_remaps() { translation_remaps.clear(); } +void ResourceLoader::load_path_remaps() { + + if (!ProjectSettings::get_singleton()->has_setting("path_remap/remapped_paths")) + return; + + PoolVector<String> remaps = ProjectSettings::get_singleton()->get("path_remap/remapped_paths"); + int rc = remaps.size(); + ERR_FAIL_COND(rc & 1); //must be even + PoolVector<String>::Read r = remaps.read(); + + for (int i = 0; i < rc; i += 2) { + + path_remaps[r[i]] = r[i + 1]; + } +} + +void ResourceLoader::clear_path_remaps() { + + path_remaps.clear(); +} + ResourceLoadErrorNotify ResourceLoader::err_notify = NULL; void *ResourceLoader::err_notify_ud = NULL; @@ -526,3 +553,4 @@ bool ResourceLoader::timestamp_on_load = false; SelfList<Resource>::List ResourceLoader::remapped_list; HashMap<String, Vector<String> > ResourceLoader::translation_remaps; +HashMap<String, String> ResourceLoader::path_remaps; diff --git a/core/io/resource_loader.h b/core/io/resource_loader.h index 5deffbca1a..05f01d8d31 100644 --- a/core/io/resource_loader.h +++ b/core/io/resource_loader.h @@ -91,6 +91,7 @@ class ResourceLoader { static DependencyErrorNotify dep_err_notify; static bool abort_on_missing_resource; static HashMap<String, Vector<String> > translation_remaps; + static HashMap<String, String> path_remaps; static String _path_remap(const String &p_path, bool *r_translation_remapped = NULL); friend class Resource; @@ -137,6 +138,9 @@ public: static String path_remap(const String &p_path); static String import_remap(const String &p_path); + static void load_path_remaps(); + static void clear_path_remaps(); + static void reload_translation_remaps(); static void load_translation_remaps(); static void clear_translation_remaps(); diff --git a/core/os/os.cpp b/core/os/os.cpp index 8088a6fa74..7010d44930 100644 --- a/core/os/os.cpp +++ b/core/os/os.cpp @@ -536,12 +536,21 @@ String OS::get_joy_guid(int p_device) const { void OS::set_context(int p_context) { } + +OS::SwitchVSyncCallbackInThread OS::switch_vsync_function = NULL; + void OS::set_use_vsync(bool p_enable) { + _use_vsync = p_enable; + if (switch_vsync_function) { //if a function was set, use function + switch_vsync_function(p_enable); + } else { //otherwise just call here + _set_use_vsync(p_enable); + } } bool OS::is_vsync_enabled() const { - return true; + return _use_vsync; } OS::PowerState OS::get_power_state() { @@ -606,10 +615,6 @@ bool OS::has_feature(const String &p_feature) { return false; } -void *OS::get_stack_bottom() const { - return _stack_bottom; -} - OS::OS() { void *volatile stack_bottom; diff --git a/core/os/os.h b/core/os/os.h index 24871c5995..2faaa6ab8f 100644 --- a/core/os/os.h +++ b/core/os/os.h @@ -58,6 +58,7 @@ class OS { int _exit_code; int _orientation; bool _allow_hidpi; + bool _use_vsync; char *last_error; @@ -191,7 +192,7 @@ public: virtual bool is_window_maximized() const { return true; } virtual void request_attention() {} - virtual void set_borderless_window(int p_borderless) {} + virtual void set_borderless_window(bool p_borderless) {} virtual bool get_borderless_window() { return 0; } virtual void set_ime_position(const Point2 &p_pos) {} @@ -435,8 +436,16 @@ public: virtual void set_context(int p_context); - virtual void set_use_vsync(bool p_enable); - virtual bool is_vsync_enabled() const; + //amazing hack because OpenGL needs this to be set on a separate thread.. + //also core can't access servers, so a callback must be used + typedef void (*SwitchVSyncCallbackInThread)(bool); + + static SwitchVSyncCallbackInThread switch_vsync_function; + void set_use_vsync(bool p_enable); + bool is_vsync_enabled() const; + + //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) {} virtual OS::PowerState get_power_state(); virtual int get_power_seconds_left(); @@ -445,13 +454,6 @@ public: virtual void force_process_input(){}; bool has_feature(const String &p_feature); - /** - * Returns the stack bottom of the main thread of the application. - * This may be of use when integrating languages with garbage collectors that - * need to check whether a pointer is on the stack. - */ - virtual void *get_stack_bottom() const; - bool is_hidpi_allowed() const { return _allow_hidpi; } OS(); virtual ~OS(); diff --git a/core/ustring.cpp b/core/ustring.cpp index 3a0708851e..ceafe209ea 100644 --- a/core/ustring.cpp +++ b/core/ustring.cpp @@ -393,7 +393,7 @@ bool String::operator<(const CharType *p_str) const { return false; //should never reach here anyway } -bool String::operator<=(String p_str) const { +bool String::operator<=(const String &p_str) const { return (*this < p_str) || (*this == p_str); } @@ -426,7 +426,7 @@ bool String::operator<(const char *p_str) const { return false; //should never reach here anyway } -bool String::operator<(String p_str) const { +bool String::operator<(const String &p_str) const { return operator<(p_str.c_str()); } @@ -734,7 +734,7 @@ Vector<String> String::split_spaces() const { return ret; } -Vector<String> String::split(const String &p_splitter, bool p_allow_empty) const { +Vector<String> String::split(const String &p_splitter, bool p_allow_empty, int p_maxsplit) const { Vector<String> ret; int from = 0; @@ -745,8 +745,21 @@ Vector<String> String::split(const String &p_splitter, bool p_allow_empty) const int end = find(p_splitter, from); if (end < 0) end = len; - if (p_allow_empty || (end > from)) - ret.push_back(substr(from, end - from)); + if (p_allow_empty || (end > from)) { + if (p_maxsplit <= 0) + ret.push_back(substr(from, end - from)); + else if (p_maxsplit > 0) { + + // Put rest of the string and leave cycle. + if (p_maxsplit == ret.size()) { + ret.push_back(substr(from, len)); + break; + } + + // Otherwise, push items until positive limit is reached. + ret.push_back(substr(from, end - from)); + } + } if (end == len) break; @@ -889,7 +902,10 @@ String String::to_upper() const { for (int i = 0; i < upper.size(); i++) { - upper[i] = _find_upper(upper[i]); + const char s = upper[i]; + const char t = _find_upper(s); + if (s != t) // avoid copy on write + upper[i] = t; } return upper; @@ -897,20 +913,17 @@ String String::to_upper() const { String String::to_lower() const { - String upper = *this; + String lower = *this; - for (int i = 0; i < upper.size(); i++) { + for (int i = 0; i < lower.size(); i++) { - upper[i] = _find_lower(upper[i]); + const char s = lower[i]; + const char t = _find_lower(s); + if (s != t) // avoid copy on write + lower[i] = t; } - return upper; -} - -int String::length() const { - - int s = size(); - return s ? (s - 1) : 0; // length does not include zero + return lower; } const CharType *String::c_str() const { @@ -2162,7 +2175,7 @@ Vector<uint8_t> String::sha256_buffer() const { return ret; } -String String::insert(int p_at_pos, String p_string) const { +String String::insert(int p_at_pos, const String &p_string) const { if (p_at_pos < 0) return *this; @@ -2190,10 +2203,15 @@ String String::substr(int p_from, int p_chars) const { p_chars = length() - p_from; } + if (p_from == 0 && p_chars >= length()) { + + return String(*this); + } + return String(&c_str()[p_from], p_chars); } -int String::find_last(String p_str) const { +int String::find_last(const String &p_str) const { int pos = -1; int findfrom = 0; @@ -2206,19 +2224,21 @@ int String::find_last(String p_str) const { return pos; } -int String::find(String p_str, int p_from) const { + +int String::find(const String &p_str, int p_from) const { if (p_from < 0) return -1; - int src_len = p_str.length(); + const int src_len = p_str.length(); - int len = length(); + const int len = length(); if (src_len == 0 || len == 0) return -1; //wont find anything! const CharType *src = c_str(); + const CharType *str = p_str.c_str(); for (int i = p_from; i <= (len - src_len); i++) { @@ -2233,7 +2253,7 @@ int String::find(String p_str, int p_from) const { return -1; }; - if (src[read_pos] != p_str[j]) { + if (src[read_pos] != str[j]) { found = false; break; } @@ -2246,6 +2266,62 @@ int String::find(String p_str, int p_from) const { return -1; } +int String::find(const char *p_str, int p_from) const { + + if (p_from < 0) + return -1; + + const int len = length(); + + if (len == 0) + return -1; //wont find anything! + + const CharType *src = c_str(); + + int src_len = 0; + while (p_str[src_len] != '\0') + src_len++; + + if (src_len == 1) { + + const char needle = p_str[0]; + + for (int i = p_from; i < len; i++) { + + if (src[i] == needle) { + return i; + } + } + + } else { + + for (int i = p_from; i <= (len - src_len); i++) { + + bool found = true; + for (int j = 0; j < src_len; j++) { + + int read_pos = i + j; + + if (read_pos >= len) { + + ERR_PRINT("read_pos>=len"); + return -1; + }; + + if (src[read_pos] != p_str[j]) { + found = false; + break; + } + } + + if (found) + return i; + } + } + + return -1; +} + int String::findmk(const Vector<String> &p_keys, int p_from, int *r_key) const { if (p_from < 0) @@ -2300,7 +2376,7 @@ int String::findmk(const Vector<String> &p_keys, int p_from, int *r_key) const { return -1; } -int String::findn(String p_str, int p_from) const { +int String::findn(const String &p_str, int p_from) const { if (p_from < 0) return -1; @@ -2341,7 +2417,7 @@ int String::findn(String p_str, int p_from) const { return -1; } -int String::rfind(String p_str, int p_from) const { +int String::rfind(const String &p_str, int p_from) const { // establish a limit int limit = length() - p_str.length(); @@ -2387,7 +2463,7 @@ int String::rfind(String p_str, int p_from) const { return -1; } -int String::rfindn(String p_str, int p_from) const { +int String::rfindn(const String &p_str, int p_from) const { // establish a limit int limit = length() - p_str.length(); @@ -2687,7 +2763,7 @@ String String::format(const Variant &values, String placeholder) const { return new_string; } -String String::replace(String p_key, String p_with) const { +String String::replace(const String &p_key, const String &p_with) const { String new_string; int search_from = 0; @@ -2700,12 +2776,43 @@ String String::replace(String p_key, String p_with) const { search_from = result + p_key.length(); } + if (search_from == 0) { + + return *this; + } + new_string += substr(search_from, length() - search_from); return new_string; } -String String::replace_first(String p_key, String p_with) const { +String String::replace(const char *p_key, const char *p_with) const { + + String new_string; + int search_from = 0; + int result = 0; + + while ((result = find(p_key, search_from)) >= 0) { + + new_string += substr(search_from, result - search_from); + new_string += p_with; + int k = 0; + while (p_key[k] != '\0') + k++; + search_from = result + k; + } + + if (search_from == 0) { + + return *this; + } + + new_string += substr(search_from, length() - search_from); + + return new_string; +} + +String String::replace_first(const String &p_key, const String &p_with) const { String new_string; int search_from = 0; @@ -2719,11 +2826,16 @@ String String::replace_first(String p_key, String p_with) const { break; } + if (search_from == 0) { + + return *this; + } + new_string += substr(search_from, length() - search_from); return new_string; } -String String::replacen(String p_key, String p_with) const { +String String::replacen(const String &p_key, const String &p_with) const { String new_string; int search_from = 0; @@ -2736,6 +2848,11 @@ String String::replacen(String p_key, String p_with) const { search_from = result + p_key.length(); } + if (search_from == 0) { + + return *this; + } + new_string += substr(search_from, length() - search_from); return new_string; } diff --git a/core/ustring.h b/core/ustring.h index 9c24133b55..73537bfd13 100644 --- a/core/ustring.h +++ b/core/ustring.h @@ -93,8 +93,8 @@ public: bool operator!=(const CharType *p_str) const; bool operator<(const CharType *p_str) const; bool operator<(const char *p_str) const; - bool operator<(String p_str) const; - bool operator<=(String p_str) const; + bool operator<(const String &p_str) const; + bool operator<=(const String &p_str) const; signed char casecmp_to(const String &p_str) const; signed char nocasecmp_to(const String &p_str) const; @@ -103,15 +103,19 @@ public: const CharType *c_str() const; /* standard size stuff */ - int length() const; + _FORCE_INLINE_ int length() const { + int s = size(); + return s ? (s - 1) : 0; // length does not include zero + } /* complex helpers */ String substr(int p_from, int p_chars) const; - int find(String p_str, int p_from = 0) const; ///< return <0 if failed - int find_last(String p_str) const; ///< return <0 if failed - int findn(String p_str, int p_from = 0) const; ///< return <0 if failed, case insensitive - int rfind(String p_str, int p_from = -1) const; ///< return <0 if failed - int rfindn(String p_str, int p_from = -1) const; ///< return <0 if failed, case insensitive + int find(const String &p_str, int p_from = 0) const; ///< return <0 if failed + int find(const char *p_str, int p_from) const; ///< return <0 if failed + int find_last(const String &p_str) const; ///< return <0 if failed + int findn(const String &p_str, int p_from = 0) const; ///< return <0 if failed, case insensitive + int rfind(const String &p_str, int p_from = -1) const; ///< return <0 if failed + int rfindn(const String &p_str, int p_from = -1) const; ///< return <0 if failed, case insensitive int findmk(const Vector<String> &p_keys, int p_from = 0, int *r_key = NULL) const; ///< return <0 if failed bool match(const String &p_wildcard) const; bool matchn(const String &p_wildcard) const; @@ -125,10 +129,11 @@ public: Vector<String> bigrams() const; float similarity(const String &p_string) const; String format(const Variant &values, String placeholder = "{_}") const; - String replace_first(String p_key, String p_with) const; - String replace(String p_key, String p_with) const; - String replacen(String p_key, String p_with) const; - String insert(int p_at_pos, String p_string) const; + String replace_first(const String &p_key, const String &p_with) const; + String replace(const String &p_key, const String &p_with) const; + String replace(const char *p_key, const char *p_with) const; + String replacen(const String &p_key, const String &p_with) const; + String insert(int p_at_pos, const String &p_string) const; String pad_decimals(int p_digits) const; String pad_zeros(int p_digits) const; String lpad(int min_length, const String &character = " ") const; @@ -162,7 +167,7 @@ public: String get_slice(String p_splitter, int p_slice) const; String get_slicec(CharType p_splitter, int p_slice) const; - Vector<String> split(const String &p_splitter, bool p_allow_empty = true) const; + Vector<String> split(const String &p_splitter, bool p_allow_empty = true, int p_maxsplit = 0) const; Vector<String> split_spaces() const; Vector<float> split_floats(const String &p_splitter, bool p_allow_empty = true) const; Vector<float> split_floats_mk(const Vector<String> &p_splitters, bool p_allow_empty = true) const; @@ -204,7 +209,7 @@ public: Vector<uint8_t> md5_buffer() const; Vector<uint8_t> sha256_buffer() const; - inline bool empty() const { return length() == 0; } + _FORCE_INLINE_ bool empty() const { return length() == 0; } // path functions bool is_abs_path() const; @@ -242,6 +247,8 @@ public: */ /* String(CharType p_char);*/ inline String() {} + inline String(const String &p_str) : + Vector(p_str) {} String(const char *p_str); String(const CharType *p_str, int p_clip_to_len = -1); String(const StrRange &p_range); diff --git a/core/variant_call.cpp b/core/variant_call.cpp index f66cce85c9..2b99a60ba5 100644 --- a/core/variant_call.cpp +++ b/core/variant_call.cpp @@ -254,7 +254,7 @@ struct _VariantCall { VCALL_LOCALMEM2R(String, replacen); VCALL_LOCALMEM2R(String, insert); VCALL_LOCALMEM0R(String, capitalize); - VCALL_LOCALMEM2R(String, split); + VCALL_LOCALMEM3R(String, split); VCALL_LOCALMEM2R(String, split_floats); VCALL_LOCALMEM0R(String, to_upper); VCALL_LOCALMEM0R(String, to_lower); @@ -1446,7 +1446,7 @@ void register_variant_methods() { ADDFUNC2R(STRING, STRING, String, replacen, STRING, "what", STRING, "forwhat", varray()); ADDFUNC2R(STRING, STRING, String, insert, INT, "position", STRING, "what", varray()); ADDFUNC0R(STRING, STRING, String, capitalize, varray()); - ADDFUNC2R(STRING, POOL_STRING_ARRAY, String, split, STRING, "divisor", BOOL, "allow_empty", varray(true)); + ADDFUNC3R(STRING, POOL_STRING_ARRAY, String, split, STRING, "divisor", BOOL, "allow_empty", INT, "maxsplit", varray(true, 0)); ADDFUNC2R(STRING, POOL_REAL_ARRAY, String, split_floats, STRING, "divisor", BOOL, "allow_empty", varray(true)); ADDFUNC0R(STRING, STRING, String, to_upper, varray()); diff --git a/doc/classes/Animation.xml b/doc/classes/Animation.xml index 93b01a466b..f78b39eadb 100644 --- a/doc/classes/Animation.xml +++ b/doc/classes/Animation.xml @@ -38,6 +38,7 @@ <argument index="1" name="to_animation" type="Animation"> </argument> <description> + Adds a new track that is a copy of the given track from [code]to_animation[/code]. </description> </method> <method name="find_track" qualifiers="const"> @@ -260,6 +261,7 @@ <argument index="0" name="idx" type="int"> </argument> <description> + Returns [code]true[/code] if the track at index [code]idx[/code] is enabled. </description> </method> <method name="track_is_imported" qualifiers="const"> @@ -319,6 +321,7 @@ <argument index="1" name="enabled" type="bool"> </argument> <description> + Enables/disables the given track. Tracks are enabled by default. </description> </method> <method name="track_set_imported"> diff --git a/doc/classes/BakedLightmap.xml b/doc/classes/BakedLightmap.xml new file mode 100644 index 0000000000..8084af3817 --- /dev/null +++ b/doc/classes/BakedLightmap.xml @@ -0,0 +1,77 @@ +<?xml version="1.0" encoding="UTF-8" ?> +<class name="BakedLightmap" inherits="VisualInstance" category="Core" version="3.0-beta"> + <brief_description> + </brief_description> + <description> + </description> + <tutorials> + </tutorials> + <demos> + </demos> + <methods> + <method name="bake"> + <return type="int" enum="BakedLightmap.BakeError"> + </return> + <argument index="0" name="from_node" type="Node" default="null"> + </argument> + <argument index="1" name="create_visual_debug" type="bool" default="false"> + </argument> + <description> + </description> + </method> + <method name="debug_bake"> + <return type="void"> + </return> + <description> + </description> + </method> + </methods> + <members> + <member name="bake_mode" type="int" setter="set_bake_mode" getter="get_bake_mode" enum="BakedLightmap.BakeMode"> + </member> + <member name="bake_quality" type="int" setter="set_bake_quality" getter="get_bake_quality" enum="BakedLightmap.BakeQuality"> + </member> + <member name="bake_subdiv" type="int" setter="set_bake_subdiv" getter="get_bake_subdiv" enum="BakedLightmap.Subdiv"> + </member> + <member name="capture_subdiv" type="int" setter="set_capture_subdiv" getter="get_capture_subdiv" enum="BakedLightmap.Subdiv"> + </member> + <member name="energy" type="float" setter="set_energy" getter="get_energy"> + </member> + <member name="extents" type="Vector3" setter="set_extents" getter="get_extents"> + </member> + <member name="hdr" type="bool" setter="set_hdr" getter="is_hdr"> + </member> + <member name="image_path" type="String" setter="set_image_path" getter="get_image_path"> + </member> + <member name="light_data" type="BakedLightmapData" setter="set_light_data" getter="get_light_data"> + </member> + <member name="propagation" type="float" setter="set_propagation" getter="get_propagation"> + </member> + </members> + <constants> + <constant name="SUBDIV_128" value="0" enum="Subdiv"> + </constant> + <constant name="SUBDIV_256" value="1" enum="Subdiv"> + </constant> + <constant name="SUBDIV_512" value="2" enum="Subdiv"> + </constant> + <constant name="SUBDIV_1024" value="3" enum="Subdiv"> + </constant> + <constant name="SUBDIV_2048" value="4" enum="Subdiv"> + </constant> + <constant name="SUBDIV_4096" value="5" enum="Subdiv"> + </constant> + <constant name="SUBDIV_MAX" value="6" enum="Subdiv"> + </constant> + <constant name="BAKE_QUALITY_LOW" value="0" enum="BakeQuality"> + </constant> + <constant name="BAKE_QUALITY_MEDIUM" value="1" enum="BakeQuality"> + </constant> + <constant name="BAKE_QUALITY_HIGH" value="2" enum="BakeQuality"> + </constant> + <constant name="BAKE_MODE_CONE_TRACE" value="0" enum="BakeMode"> + </constant> + <constant name="BAKE_MODE_RAY_TRACE" value="1" enum="BakeMode"> + </constant> + </constants> +</class> diff --git a/doc/classes/BakedLightmapData.xml b/doc/classes/BakedLightmapData.xml new file mode 100644 index 0000000000..6997dcb0b2 --- /dev/null +++ b/doc/classes/BakedLightmapData.xml @@ -0,0 +1,113 @@ +<?xml version="1.0" encoding="UTF-8" ?> +<class name="BakedLightmapData" inherits="Resource" category="Core" version="3.0-beta"> + <brief_description> + </brief_description> + <description> + </description> + <tutorials> + </tutorials> + <demos> + </demos> + <methods> + <method name="add_user"> + <return type="void"> + </return> + <argument index="0" name="path" type="NodePath"> + </argument> + <argument index="1" name="lightmap" type="Texture"> + </argument> + <description> + </description> + </method> + <method name="clear_users"> + <return type="void"> + </return> + <description> + </description> + </method> + <method name="get_bounds" qualifiers="const"> + <return type="AABB"> + </return> + <description> + </description> + </method> + <method name="get_cell_space_transform" qualifiers="const"> + <return type="Transform"> + </return> + <description> + </description> + </method> + <method name="get_cell_subdiv" qualifiers="const"> + <return type="int"> + </return> + <description> + </description> + </method> + <method name="get_octree" qualifiers="const"> + <return type="PoolByteArray"> + </return> + <description> + </description> + </method> + <method name="get_user_count" qualifiers="const"> + <return type="int"> + </return> + <description> + </description> + </method> + <method name="get_user_lightmap" qualifiers="const"> + <return type="Texture"> + </return> + <argument index="0" name="user_idx" type="int"> + </argument> + <description> + </description> + </method> + <method name="get_user_path" qualifiers="const"> + <return type="NodePath"> + </return> + <argument index="0" name="user_idx" type="int"> + </argument> + <description> + </description> + </method> + <method name="set_bounds"> + <return type="void"> + </return> + <argument index="0" name="bounds" type="AABB"> + </argument> + <description> + </description> + </method> + <method name="set_cell_space_transform"> + <return type="void"> + </return> + <argument index="0" name="xform" type="Transform"> + </argument> + <description> + </description> + </method> + <method name="set_cell_subdiv"> + <return type="void"> + </return> + <argument index="0" name="cell_subdiv" type="int"> + </argument> + <description> + </description> + </method> + <method name="set_octree"> + <return type="void"> + </return> + <argument index="0" name="octree" type="PoolByteArray"> + </argument> + <description> + </description> + </method> + </methods> + <members> + <member name="energy" type="float" setter="set_energy" getter="get_energy"> + </member> + </members> + <constants> + </constants> +</class> diff --git a/doc/classes/Camera.xml b/doc/classes/Camera.xml index 5d6c13498c..91c9ecc774 100644 --- a/doc/classes/Camera.xml +++ b/doc/classes/Camera.xml @@ -25,88 +25,6 @@ Get the camera transform. Subclassed cameras (such as CharacterCamera) may provide different transforms than the [Node] transform. </description> </method> - <method name="get_cull_mask" qualifiers="const"> - <return type="int"> - </return> - <description> - Returns the culling mask, describing which 3D render layers are rendered by this Camera. - </description> - </method> - <method name="get_doppler_tracking" qualifiers="const"> - <return type="int" enum="Camera.DopplerTracking"> - </return> - <description> - </description> - </method> - <method name="get_environment" qualifiers="const"> - <return type="Environment"> - </return> - <description> - Returns the [Environment] used by this Camera. - </description> - </method> - <method name="get_fov" qualifiers="const"> - <return type="float"> - </return> - <description> - Returns the [i]FOV[/i] Y angle in degrees (FOV means Field of View). - </description> - </method> - <method name="get_h_offset" qualifiers="const"> - <return type="float"> - </return> - <description> - Returns the horizontal (X) offset of the Camera viewport. - </description> - </method> - <method name="get_keep_aspect_mode" qualifiers="const"> - <return type="int" enum="Camera.KeepAspect"> - </return> - <description> - Returns the current mode for keeping the aspect ratio. See [code]KEEP_*[/code] constants. - </description> - </method> - <method name="get_projection" qualifiers="const"> - <return type="int" enum="Camera.Projection"> - </return> - <description> - Returns the Camera's projection. See PROJECTION_* constants. - </description> - </method> - <method name="get_size" qualifiers="const"> - <return type="float"> - </return> - <description> - </description> - </method> - <method name="get_v_offset" qualifiers="const"> - <return type="float"> - </return> - <description> - Returns the vertical (Y) offset of the Camera viewport. - </description> - </method> - <method name="get_zfar" qualifiers="const"> - <return type="float"> - </return> - <description> - Returns the far clip plane in world space units. - </description> - </method> - <method name="get_znear" qualifiers="const"> - <return type="float"> - </return> - <description> - Returns the near clip plane in world space units. - </description> - </method> - <method name="is_current" qualifiers="const"> - <return type="bool"> - </return> - <description> - Returns [code]true[/code] if the Camera is the current one in the [Viewport], or plans to become current (if outside the scene tree). - </description> - </method> <method name="is_position_behind" qualifiers="const"> <return type="bool"> </return> @@ -129,6 +47,7 @@ <argument index="0" name="screen_point" type="Vector2"> </argument> <description> + Returns a normal vector from the screen point location directed along the camera. Orthogonal cameras are normalized. Perspective cameras account for perspective, screen width/height, etc. </description> </method> <method name="project_position" qualifiers="const"> @@ -158,51 +77,6 @@ Returns a 3D position in worldspace, that is the result of projecting a point on the [Viewport] rectangle by the camera projection. This is useful for casting rays in the form of (origin, normal) for object intersection or picking. </description> </method> - <method name="set_cull_mask"> - <return type="void"> - </return> - <argument index="0" name="mask" type="int"> - </argument> - <description> - Sets the cull mask, describing which 3D render layers are rendered by this Camera. - </description> - </method> - <method name="set_doppler_tracking"> - <return type="void"> - </return> - <argument index="0" name="mode" type="int" enum="Camera.DopplerTracking"> - </argument> - <description> - Changes Doppler effect tracking. See [code]DOPPLER_*[/code] constants. - </description> - </method> - <method name="set_environment"> - <return type="void"> - </return> - <argument index="0" name="env" type="Environment"> - </argument> - <description> - Sets the [Environment] to use for this Camera. - </description> - </method> - <method name="set_h_offset"> - <return type="void"> - </return> - <argument index="0" name="ofs" type="float"> - </argument> - <description> - Sets the horizontal (X) offset of the Camera viewport. - </description> - </method> - <method name="set_keep_aspect_mode"> - <return type="void"> - </return> - <argument index="0" name="mode" type="int" enum="Camera.KeepAspect"> - </argument> - <description> - Sets the mode for keeping the aspect ratio. See [code]KEEP_*[/code] constants. - </description> - </method> <method name="set_orthogonal"> <return type="void"> </return> @@ -229,15 +103,6 @@ Set the camera projection to perspective mode, by specifying a [i]FOV[/i] Y angle in degrees (FOV means Field of View), and the [i]near[/i] and [i]far[/i] clip planes in worldspace units. </description> </method> - <method name="set_v_offset"> - <return type="void"> - </return> - <argument index="0" name="ofs" type="float"> - </argument> - <description> - Sets the vertical (Y) offset of the Camera viewport. - </description> - </method> <method name="unproject_position" qualifiers="const"> <return type="Vector2"> </return> @@ -248,6 +113,47 @@ </description> </method> </methods> + <members> + <member name="cull_mask" type="int" setter="set_cull_mask" getter="get_cull_mask"> + The culling mask that describes which 3D render layers are rendered by this camera. + </member> + <member name="current" type="bool" setter="set_current" getter="is_current"> + If [code]true[/code] the ancestor [Viewport] is currently using this Camera. Default value: [code]false[/code]. + </member> + <member name="doppler_tracking" type="int" setter="set_doppler_tracking" getter="get_doppler_tracking" enum="Camera.DopplerTracking"> + If not [code]DOPPLER_TRACKING_DISABLED[/code] this Camera will simulate the Doppler effect for objects changed in particular [code]_process[/code] methods. Default value: [code]DOPPLER_TRACKING_DISABLED[/code]. + </member> + <member name="environment" type="Environment" setter="set_environment" getter="get_environment"> + Set the [Environment] to use for this Camera. + </member> + <member name="far" type="float" setter="set_zfar" getter="get_zfar"> + The distance to the far culling boundary for this Camera relative to its local z-axis. + </member> + <member name="fov" type="float" setter="set_fov" getter="get_fov"> + The camera's field of view angle (in degrees). Only applicable in perspective mode. Since [member keep_aspect] locks one axis, [code]fov[/code] sets the other axis' field of view angle. + </member> + <member name="h_offset" type="float" setter="set_h_offset" getter="get_h_offset"> + The horizontal (X) offset of the Camear viewport. + </member> + <member name="keep_aspect" type="int" setter="set_keep_aspect_mode" getter="get_keep_aspect_mode" enum="Camera.KeepAspect"> + The axis to lock during [member fov]/[member size] adjustments. + </member> + <member name="near" type="float" setter="set_znear" getter="get_znear"> + The distance to the near culling boundary for this Camera relative to its local z-axis. + </member> + <member name="projection" type="int" setter="set_projection" getter="get_projection" enum="Camera.Projection"> + The camera's projection mode. In [code]PROJECTION_PERSPECTIVE[/code] mode, objects' z-distance from the camera's local space scales their perceived size. + </member> + <member name="size" type="float" setter="set_size" getter="get_size"> + The camera's size measured as 1/2 the width or height. Only applicable in orthogonal mode. Since [member keep_aspect] locks on axis, [code]size[/code] sets the other axis' size length. + </member> + <member name="v_offset" type="float" setter="set_v_offset" getter="get_v_offset"> + The horizontal (Y) offset of the Camear viewport. + </member> + <member name="vaspect" type="bool" setter="set_vaspect" getter="get_vaspect"> + A boolean representation of [member keep_aspect] in which [code]true[/code] is equivalent to [code]KEEP_WIDTH[/code]. + </member> + </members> <constants> <constant name="PROJECTION_PERSPECTIVE" value="0" enum="Projection"> Perspective Projection (object's size on the screen becomes smaller when far away). @@ -256,10 +162,10 @@ Orthogonal Projection (objects remain the same size on the screen no matter how far away they are). </constant> <constant name="KEEP_WIDTH" value="0" enum="KeepAspect"> - Try to keep the aspect ratio when scaling the Camera's viewport to the screen. If not possible, preserve the viewport's width by changing the height. Height is [code]sizey[/code] for orthographic projection, [code]fovy[/code] for perspective projection. + Preserves the horizontal aspect ratio. </constant> <constant name="KEEP_HEIGHT" value="1" enum="KeepAspect"> - Try to keep the aspect ratio when scaling the Camera's viewport to the screen. If not possible, preserve the viewport's height by changing the width. Width is [code]sizex[/code] for orthographic projection, [code]fovx[/code] for perspective projection. + Preserves the vertical aspect ratio. </constant> <constant name="DOPPLER_TRACKING_DISABLED" value="0" enum="DopplerTracking"> Disable Doppler effect simulation (default). diff --git a/doc/classes/CanvasItem.xml b/doc/classes/CanvasItem.xml index cf0b482b07..bd20cfcf5d 100644 --- a/doc/classes/CanvasItem.xml +++ b/doc/classes/CanvasItem.xml @@ -36,7 +36,7 @@ <argument index="4" name="modulate" type="Color" default="Color( 1, 1, 1, 1 )"> </argument> <description> - Draw a string character using a custom font. Returns the advance, depending on the char width and kerning with an optional next char. + Draws a string character using a custom font. Returns the advance, depending on the char width and kerning with an optional next char. </description> </method> <method name="draw_circle"> @@ -49,7 +49,7 @@ <argument index="2" name="color" type="Color"> </argument> <description> - Draw a colored circle. + Draws a colored circle. </description> </method> <method name="draw_colored_polygon"> @@ -68,7 +68,7 @@ <argument index="5" name="antialiased" type="bool" default="false"> </argument> <description> - Draw a colored polygon of any amount of points, convex or concave. + Draws a colored polygon of any amount of points, convex or concave. </description> </method> <method name="draw_line"> @@ -85,7 +85,7 @@ <argument index="4" name="antialiased" type="bool" default="false"> </argument> <description> - Draw a line from a 2D point to another, with a given color and width. It can be optionally antialiased. + Draws a line from a 2D point to another, with a given color and width. It can be optionally antialiased. </description> </method> <method name="draw_multiline"> @@ -100,6 +100,7 @@ <argument index="3" name="antialiased" type="bool" default="false"> </argument> <description> + Draws multiple, parallel lines with a uniform [code]color[/code] and [code]width[/code] and optional antialiasing. </description> </method> <method name="draw_multiline_colors"> @@ -114,6 +115,7 @@ <argument index="3" name="antialiased" type="bool" default="false"> </argument> <description> + Draws multiple, parallel lines with a uniform [code]width[/code], segment-by-segment coloring, and optional antialiasing. Colors assigned to line segments match by index between [code]points[/code] and [code]colors[/code]. </description> </method> <method name="draw_polygon"> @@ -132,7 +134,7 @@ <argument index="5" name="antialiased" type="bool" default="false"> </argument> <description> - Draw a polygon of any amount of points, convex or concave. + Draws a polygon of any amount of points, convex or concave. </description> </method> <method name="draw_polyline"> @@ -147,7 +149,7 @@ <argument index="3" name="antialiased" type="bool" default="false"> </argument> <description> - Draw a polyline with a uniform [code]color[/code] and [code]width[/code] and optional antialiasing. + Draws interconnected line segments with a uniform [code]color[/code] and [code]width[/code] and optional antialiasing. </description> </method> <method name="draw_polyline_colors"> @@ -162,7 +164,7 @@ <argument index="3" name="antialiased" type="bool" default="false"> </argument> <description> - Draw a polyline with a uniform [code]width[/code], segment-by-segment coloring, and optional antialiasing. Colors assigned to line segments match by index between [code]points[/code] and [code]colors[/code]. + Draws interconnected line segments with a uniform [code]width[/code], segment-by-segment coloring, and optional antialiasing. Colors assigned to line segments match by index between [code]points[/code] and [code]colors[/code]. </description> </method> <method name="draw_primitive"> @@ -181,7 +183,7 @@ <argument index="5" name="normal_map" type="Texture" default="null"> </argument> <description> - Draw a custom primitive, 1 point for a point, 2 points for a line, 3 points for a triangle and 4 points for a quad. + Draws a custom primitive, 1 point for a point, 2 points for a line, 3 points for a triangle and 4 points for a quad. </description> </method> <method name="draw_rect"> @@ -194,7 +196,7 @@ <argument index="2" name="filled" type="bool" default="true"> </argument> <description> - Draw a colored rectangle. + Draws a colored rectangle. </description> </method> <method name="draw_set_transform"> @@ -233,7 +235,7 @@ <argument index="4" name="clip_w" type="int" default="-1"> </argument> <description> - Draw a string using a custom font. + Draws a string using a custom font. </description> </method> <method name="draw_style_box"> @@ -244,7 +246,7 @@ <argument index="1" name="rect" type="Rect2"> </argument> <description> - Draw a styled rectangle. + Draws a styled rectangle. </description> </method> <method name="draw_texture"> @@ -259,7 +261,7 @@ <argument index="3" name="normal_map" type="Texture" default="null"> </argument> <description> - Draw a texture at a given position. + Draws a texture at a given position. </description> </method> <method name="draw_texture_rect"> @@ -278,7 +280,7 @@ <argument index="5" name="normal_map" type="Texture" default="null"> </argument> <description> - Draw a textured rectangle at a given position, optionally modulated by a color. Transpose swaps the x and y coordinates when reading the texture. + Draws a textured rectangle at a given position, optionally modulated by a color. Transpose swaps the x and y coordinates when reading the texture. </description> </method> <method name="draw_texture_rect_region"> @@ -299,7 +301,7 @@ <argument index="6" name="clip_uv" type="bool" default="true"> </argument> <description> - Draw a textured rectangle region at a given position, optionally modulated by a color. Transpose swaps the x and y coordinates when reading the texture. + Draws a textured rectangle region at a given position, optionally modulated by a color. Transpose swaps the x and y coordinates when reading the texture. </description> </method> <method name="get_canvas" qualifiers="const"> diff --git a/doc/classes/Curve.xml b/doc/classes/Curve.xml index 3e1158ca3b..8a007cc5cc 100644 --- a/doc/classes/Curve.xml +++ b/doc/classes/Curve.xml @@ -1,8 +1,10 @@ <?xml version="1.0" encoding="UTF-8" ?> <class name="Curve" inherits="Resource" category="Core" version="3.0-beta"> <brief_description> + A mathematic curve. </brief_description> <description> + A curve that can be saved and re-used for other objects. By default it ranges between [code]0[/code] and [code]1[/code] on the y-axis and positions points relative to the [code]0.5[/code] y-position. </description> <tutorials> </tutorials> @@ -23,24 +25,28 @@ <argument index="4" name="right_mode" type="int" enum="Curve.TangentMode" default="0"> </argument> <description> + Adds a point to the curve. For each side, if the [code]*_mode[/code] is [code]TANGENT_LINEAR[/code], the [code]*_tangent[/code] angle (in degrees) uses the slope of the curve halfway to the adjacent point. Allows custom assignments to the [code]*_tangent[/code] angle if [code]*_mode[/code] is set to [code]TANGENT_FREE[/code]. </description> </method> <method name="bake"> <return type="void"> </return> <description> + Recomputes the baked cache of points for the curve. </description> </method> <method name="clean_dupes"> <return type="void"> </return> <description> + Removes points that are closer than [code]CMP_EPSILON[/code] (0.00001) units to their neighbor on the curve. </description> </method> <method name="clear_points"> <return type="void"> </return> <description> + Removes all points from the curve. </description> </method> <method name="get_point_left_mode" qualifiers="const"> @@ -49,6 +55,7 @@ <argument index="0" name="index" type="int"> </argument> <description> + Returns the left [code]TangentMode[/code] for the point at [code]index[/code]. </description> </method> <method name="get_point_left_tangent" qualifiers="const"> @@ -57,6 +64,7 @@ <argument index="0" name="index" type="int"> </argument> <description> + Returns the left tangent angle (in degrees) for the point at [code]index[/code]. </description> </method> <method name="get_point_position" qualifiers="const"> @@ -65,6 +73,7 @@ <argument index="0" name="index" type="int"> </argument> <description> + Returns the curve coordinates for the point at [code]index[/code]. </description> </method> <method name="get_point_right_mode" qualifiers="const"> @@ -73,6 +82,7 @@ <argument index="0" name="index" type="int"> </argument> <description> + Returns the right [code]TangentMode[/code] for the point at [code]index[/code]. </description> </method> <method name="get_point_right_tangent" qualifiers="const"> @@ -81,6 +91,7 @@ <argument index="0" name="index" type="int"> </argument> <description> + Returns the right tangent angle (in degrees) for the point at [code]index[/code]. </description> </method> <method name="interpolate" qualifiers="const"> @@ -89,6 +100,7 @@ <argument index="0" name="offset" type="float"> </argument> <description> + Returns the y value for the point that would exist at x-position [code]offset[/code] along the curve. </description> </method> <method name="interpolate_baked"> @@ -97,6 +109,7 @@ <argument index="0" name="offset" type="float"> </argument> <description> + Returns the y value for the point that would exist at x-position [code]offset[/code] along the curve using the baked cache. Bakes the curve's points if not already baked. </description> </method> <method name="remove_point"> @@ -105,6 +118,7 @@ <argument index="0" name="index" type="int"> </argument> <description> + Removes the point at [code]index[/code] from the curve. </description> </method> <method name="set_point_left_mode"> @@ -115,6 +129,7 @@ <argument index="1" name="mode" type="int" enum="Curve.TangentMode"> </argument> <description> + Sets the left [code]TangentMode[/code] for the point at [code]index[/code] to [code]mode[/code]. </description> </method> <method name="set_point_left_tangent"> @@ -125,6 +140,7 @@ <argument index="1" name="tangent" type="float"> </argument> <description> + Sets the left tangent angle for the point at [code]index[/code] to [code]tangent[/code]. </description> </method> <method name="set_point_offset"> @@ -135,6 +151,7 @@ <argument index="1" name="offset" type="float"> </argument> <description> + Sets the offset from [code]0.5[/code] </description> </method> <method name="set_point_right_mode"> @@ -145,6 +162,7 @@ <argument index="1" name="mode" type="int" enum="Curve.TangentMode"> </argument> <description> + Sets the right [code]TangentMode[/code] for the point at [code]index[/code] to [code]mode[/code]. </description> </method> <method name="set_point_right_tangent"> @@ -155,6 +173,7 @@ <argument index="1" name="tangent" type="float"> </argument> <description> + Sets the right tangent angle for the point at [code]index[/code] to [code]tangent[/code]. </description> </method> <method name="set_point_value"> @@ -165,29 +184,37 @@ <argument index="1" name="y" type="float"> </argument> <description> + Assigns the vertical position [code]y[/code] to the point at [code]index[/code]. </description> </method> </methods> <members> <member name="bake_resolution" type="int" setter="set_bake_resolution" getter="get_bake_resolution"> + The number of points to include in the baked (i.e. cached) curve data. </member> <member name="max_value" type="float" setter="set_max_value" getter="get_max_value"> + The maximum value the curve can reach. Default value: [code]1[/code]. </member> <member name="min_value" type="float" setter="set_min_value" getter="get_min_value"> + The minimum value the curve can reach. Default value: [code]0[/code]. </member> </members> <signals> <signal name="range_changed"> <description> + Emitted when [member max_value] or [member min_value] is changed. </description> </signal> </signals> <constants> <constant name="TANGENT_FREE" value="0" enum="TangentMode"> + The tangent on this side of the point is user-defined. </constant> <constant name="TANGENT_LINEAR" value="1" enum="TangentMode"> + The curve calculates the tangent on this side of the point as the slope halfway towards the adjacent point. </constant> <constant name="TANGENT_MODE_COUNT" value="2" enum="TangentMode"> + The total number of available tangent modes. </constant> </constants> </class> diff --git a/doc/classes/Curve3D.xml b/doc/classes/Curve3D.xml index e30ae85617..91d7a9bed8 100644 --- a/doc/classes/Curve3D.xml +++ b/doc/classes/Curve3D.xml @@ -32,6 +32,7 @@ <return type="void"> </return> <description> + Removes all points from the curve. </description> </method> <method name="get_baked_length" qualifiers="const"> @@ -203,6 +204,7 @@ </methods> <members> <member name="bake_interval" type="float" setter="set_bake_interval" getter="get_bake_interval"> + The distance in meters between two adjacent cached points. Changing it forces the cache to be recomputed the next time the [method get_baked_points] or [method get_baked_length] function is called. The smaller the distance, the more points in the cache and the more memory it will consume, so use with care. </member> </members> <constants> diff --git a/doc/classes/HTTPClient.xml b/doc/classes/HTTPClient.xml index 9d4b45a8d7..80f6966e12 100644 --- a/doc/classes/HTTPClient.xml +++ b/doc/classes/HTTPClient.xml @@ -26,7 +26,7 @@ </return> <argument index="0" name="host" type="String"> </argument> - <argument index="1" name="port" type="int"> + <argument index="1" name="port" type="int" default="-1"> </argument> <argument index="2" name="use_ssl" type="bool" default="false"> </argument> @@ -35,6 +35,7 @@ <description> Connect to a host. This needs to be done before any requests are sent. The host should not have http:// prepended but will strip the protocol identifier if provided. + If no [code]port[/code] is specified (or [code]-1[/code] is used), it is automatically set to 80 for HTTP and 443 for HTTPS (if [code]use_ssl[/code] is enabled). [code]verify_host[/code] will check the SSL identity of the host if set to [code]true[/code]. </description> </method> diff --git a/doc/classes/Light.xml b/doc/classes/Light.xml index e4f92cc9b3..4aa39ffff6 100644 --- a/doc/classes/Light.xml +++ b/doc/classes/Light.xml @@ -15,6 +15,8 @@ <members> <member name="editor_only" type="bool" setter="set_editor_only" getter="is_editor_only"> </member> + <member name="light_bake_mode" type="int" setter="set_bake_mode" getter="get_bake_mode" enum="Light.BakeMode"> + </member> <member name="light_color" type="Color" setter="set_color" getter="get_color"> </member> <member name="light_cull_mask" type="int" setter="set_cull_mask" getter="get_cull_mask"> @@ -71,5 +73,11 @@ </constant> <constant name="PARAM_MAX" value="15" enum="Param"> </constant> + <constant name="BAKE_DISABLED" value="0" enum="BakeMode"> + </constant> + <constant name="BAKE_INDIRECT" value="1" enum="BakeMode"> + </constant> + <constant name="BAKE_ALL" value="2" enum="BakeMode"> + </constant> </constants> </class> diff --git a/doc/classes/Navigation.xml b/doc/classes/Navigation.xml index 4bfe964a4d..8fe520f853 100644 --- a/doc/classes/Navigation.xml +++ b/doc/classes/Navigation.xml @@ -1,8 +1,10 @@ <?xml version="1.0" encoding="UTF-8" ?> <class name="Navigation" inherits="Spatial" category="Core" version="3.0-beta"> <brief_description> + A collection of [code]NavigationMesh[/code] resources and methods used for pathfinding. </brief_description> <description> + The Navigation node is used for basic or advanced navigation. By default it will automatically collect all child [code]NavigationMesh[/code] resources, but they can also be added on the fly through scripting. It can be used for generating a simple path between two points or it can be used to ensure that a navigation agent is angled perfectly to the terrain it is navigating. </description> <tutorials> </tutorials> @@ -15,6 +17,7 @@ <argument index="0" name="to_point" type="Vector3"> </argument> <description> + Returns the closest navigation point to the point passed. </description> </method> <method name="get_closest_point_normal"> @@ -23,6 +26,7 @@ <argument index="0" name="to_point" type="Vector3"> </argument> <description> + Returns the surface normal of the navigation mesh at the point passed. For instance, if the point passed was at a 45 degree slope it would return something like (0.5,0.5,0). This is useful for rotating a navigation agent in accordance with the [code]NavigationMesh[/code]. </description> </method> <method name="get_closest_point_owner"> @@ -31,6 +35,7 @@ <argument index="0" name="to_point" type="Vector3"> </argument> <description> + Returns the nearest [code]NavigationMeshInstance[/code] to the point passed. </description> </method> <method name="get_closest_point_to_segment"> @@ -43,6 +48,7 @@ <argument index="2" name="use_collision" type="bool" default="false"> </argument> <description> + Returns the nearest point to the line segment passed. The third optional parameter takes collisions into account. </description> </method> <method name="get_simple_path"> @@ -55,9 +61,10 @@ <argument index="2" name="optimize" type="bool" default="true"> </argument> <description> + Returns a path of points as a [code]PoolVector3Array[/code]. If [code]optimize[/code] is false the [code]NavigationMesh[/code] agent properties will be taken into account, otherwise it will return the nearest path and ignore agent radius, height, etc. </description> </method> - <method name="navmesh_create"> + <method name="navmesh_add"> <return type="int"> </return> <argument index="0" name="mesh" type="NavigationMesh"> @@ -67,6 +74,7 @@ <argument index="2" name="owner" type="Object" default="null"> </argument> <description> + Adds a [code]NavigationMesh[/code] to the list of NavigationMesh's in this node. Returns an id. Its position, rotation and scale are associated with the [code]Transform[/code] passed. The [code]Node[/code] (or [code]Object[/code]) that owns this node is an optional parameter. </description> </method> <method name="navmesh_remove"> @@ -75,6 +83,7 @@ <argument index="0" name="id" type="int"> </argument> <description> + Removes a [code]NavigationMesh[/code] from the list of NavigationMesh's in this node. </description> </method> <method name="navmesh_set_transform"> @@ -85,11 +94,13 @@ <argument index="1" name="xform" type="Transform"> </argument> <description> + Associates a [code]NavigationMesh[/code]'s id with a [code]Transform[/code]. Its position, rotation and scale are based on the [code]Transform[/code] passed. </description> </method> </methods> <members> <member name="up_vector" type="Vector3" setter="set_up_vector" getter="get_up_vector"> + Defines which direction is up. The default defines 0,1,0 as up which is the world up direction. To make this a ceiling use 0,-1,0 to define down as up. </member> </members> <constants> diff --git a/doc/classes/Navigation2D.xml b/doc/classes/Navigation2D.xml index 8868348cf9..18c15a616a 100644 --- a/doc/classes/Navigation2D.xml +++ b/doc/classes/Navigation2D.xml @@ -37,7 +37,7 @@ <description> </description> </method> - <method name="navpoly_create"> + <method name="navpoly_add"> <return type="int"> </return> <argument index="0" name="mesh" type="NavigationPolygon"> diff --git a/doc/classes/PacketPeer.xml b/doc/classes/PacketPeer.xml index 891f0c9ffc..57d88d7ff8 100644 --- a/doc/classes/PacketPeer.xml +++ b/doc/classes/PacketPeer.xml @@ -18,7 +18,7 @@ Return the number of packets currently available in the ring-buffer. </description> </method> - <method name="get_packet" qualifiers="const"> + <method name="get_packet"> <return type="PoolByteArray"> </return> <description> @@ -32,7 +32,7 @@ Return the error state of the last packet received (via [method get_packet] and [method get_var]). </description> </method> - <method name="get_var" qualifiers="const"> + <method name="get_var"> <return type="Variant"> </return> <description> diff --git a/doc/classes/SceneState.xml b/doc/classes/SceneState.xml index 4fcaaa23dc..f5cf2dbee4 100644 --- a/doc/classes/SceneState.xml +++ b/doc/classes/SceneState.xml @@ -88,6 +88,14 @@ Returns the list of group names associated with the node at [code]idx[/code]. </description> </method> + <method name="get_node_index" qualifiers="const"> + <return type="int"> + </return> + <argument index="0" name="idx" type="int"> + </argument> + <description> + </description> + </method> <method name="get_node_instance" qualifiers="const"> <return type="PackedScene"> </return> diff --git a/doc/classes/ScriptEditor.xml b/doc/classes/ScriptEditor.xml index 0b035f90d2..81b0b3d0c3 100644 --- a/doc/classes/ScriptEditor.xml +++ b/doc/classes/ScriptEditor.xml @@ -57,6 +57,16 @@ Returns an array with all [Script] objects which are currently open in editor. </description> </method> + <method name="open_script_create_dialog"> + <return type="void"> + </return> + <argument index="0" name="base_name" type="String"> + </argument> + <argument index="1" name="base_path" type="String"> + </argument> + <description> + </description> + </method> </methods> <signals> <signal name="editor_script_changed"> diff --git a/doc/classes/SpatialMaterial.xml b/doc/classes/SpatialMaterial.xml index cf08b0daae..403a6dc930 100644 --- a/doc/classes/SpatialMaterial.xml +++ b/doc/classes/SpatialMaterial.xml @@ -75,6 +75,8 @@ </member> <member name="emission_energy" type="float" setter="set_emission_energy" getter="get_emission_energy"> </member> + <member name="emission_on_uv2" type="bool" setter="set_flag" getter="get_flag"> + </member> <member name="emission_operator" type="int" setter="set_emission_operator" getter="get_emission_operator" enum="SpatialMaterial.EmissionOperator"> </member> <member name="emission_texture" type="Texture" setter="set_texture" getter="get_texture"> @@ -305,13 +307,15 @@ </constant> <constant name="FLAG_AO_ON_UV2" value="10" enum="Flags"> </constant> - <constant name="FLAG_USE_ALPHA_SCISSOR" value="11" enum="Flags"> + <constant name="FLAG_EMISSION_ON_UV2" value="11" enum="Flags"> + </constant> + <constant name="FLAG_USE_ALPHA_SCISSOR" value="12" enum="Flags"> </constant> <constant name="FLAG_TRIPLANAR_USE_WORLD" value="9" enum="Flags"> </constant> - <constant name="FLAG_ALBEDO_TEXTURE_FORCE_SRGB" value="12" enum="Flags"> + <constant name="FLAG_ALBEDO_TEXTURE_FORCE_SRGB" value="13" enum="Flags"> </constant> - <constant name="FLAG_MAX" value="13" enum="Flags"> + <constant name="FLAG_MAX" value="14" enum="Flags"> </constant> <constant name="DIFFUSE_BURLEY" value="0" enum="DiffuseMode"> </constant> diff --git a/doc/classes/String.xml b/doc/classes/String.xml index 78e9f3cd3f..8bbd52b417 100644 --- a/doc/classes/String.xml +++ b/doc/classes/String.xml @@ -662,8 +662,11 @@ </argument> <argument index="1" name="allow_empty" type="bool" default="True"> </argument> + <argument index="2" name="maxsplit" type="int" default="0"> + </argument> <description> Splits the string by a divisor string and returns an array of the substrings. Example "One,Two,Three" will return ["One","Two","Three"] if split by ",". + If [code]maxsplit[/code] is given, at most maxsplit number of splits occur, and the remainder of the string is returned as the final element of the list (thus, the list will have at most maxsplit+1 elements) </description> </method> <method name="split_floats"> diff --git a/doc/classes/TextEdit.xml b/doc/classes/TextEdit.xml index da30c4c7bd..85cbeaaa03 100644 --- a/doc/classes/TextEdit.xml +++ b/doc/classes/TextEdit.xml @@ -109,6 +109,13 @@ Cut the current selection. </description> </method> + <method name="deselect"> + <return type="void"> + </return> + <description> + Clears the current selection. + </description> + </method> <method name="fold_all_lines"> <return type="void"> </return> diff --git a/doc/classes/TileMap.xml b/doc/classes/TileMap.xml index 72cd56dc55..510a215fbc 100644 --- a/doc/classes/TileMap.xml +++ b/doc/classes/TileMap.xml @@ -182,6 +182,24 @@ <description> </description> </method> + <method name="update_bitmask_area"> + <return type="void"> + </return> + <argument index="0" name="arg0" type="Vector2"> + </argument> + <description> + </description> + </method> + <method name="update_bitmask_region"> + <return type="void"> + </return> + <argument index="0" name="start" type="Vector2" default="Vector2( 0, 0 )"> + </argument> + <argument index="1" name="end" type="Vector2" default="Vector2( 0, 0 )"> + </argument> + <description> + </description> + </method> <method name="world_to_map" qualifiers="const"> <return type="Vector2"> </return> diff --git a/doc/classes/VisualServer.xml b/doc/classes/VisualServer.xml index 1a9dc3a669..0cba132de8 100644 --- a/doc/classes/VisualServer.xml +++ b/doc/classes/VisualServer.xml @@ -2315,7 +2315,9 @@ </constant> <constant name="INSTANCE_GI_PROBE" value="7" enum="InstanceType"> </constant> - <constant name="INSTANCE_MAX" value="8" enum="InstanceType"> + <constant name="INSTANCE_LIGHTMAP_CAPTURE" value="8" enum="InstanceType"> + </constant> + <constant name="INSTANCE_MAX" value="9" enum="InstanceType"> The max value for INSTANCE_* constants, used internally. </constant> <constant name="INSTANCE_GEOMETRY_MASK" value="30" enum="InstanceType"> diff --git a/drivers/gles3/rasterizer_canvas_gles3.cpp b/drivers/gles3/rasterizer_canvas_gles3.cpp index 309497c938..5d93c6a982 100644 --- a/drivers/gles3/rasterizer_canvas_gles3.cpp +++ b/drivers/gles3/rasterizer_canvas_gles3.cpp @@ -1545,7 +1545,7 @@ void RasterizerCanvasGLES3::reset_canvas() { glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, 0); //use for reading from screen - if (storage->frame.current_rt) { + if (storage->frame.current_rt && !storage->frame.current_rt->flags[RasterizerStorage::RENDER_TARGET_NO_SAMPLING]) { glActiveTexture(GL_TEXTURE0 + storage->config.max_texture_image_units - 3); glBindTexture(GL_TEXTURE_2D, storage->frame.current_rt->effects.mip_maps[0].color); } diff --git a/drivers/gles3/rasterizer_scene_gles3.cpp b/drivers/gles3/rasterizer_scene_gles3.cpp index 13fbb5c293..29ab531177 100644 --- a/drivers/gles3/rasterizer_scene_gles3.cpp +++ b/drivers/gles3/rasterizer_scene_gles3.cpp @@ -1557,7 +1557,7 @@ void RasterizerSceneGLES3::_render_geometry(RenderList::Element *e) { glEnableVertexAttribArray(VS::ARRAY_NORMAL); glBufferSubData(GL_ARRAY_BUFFER, buf_ofs, sizeof(Vector3) * vertices, c.normals.ptr()); - glVertexAttribPointer(VS::ARRAY_NORMAL, 3, GL_FLOAT, false, sizeof(Vector3) * vertices, ((uint8_t *)NULL) + buf_ofs); + glVertexAttribPointer(VS::ARRAY_NORMAL, 3, GL_FLOAT, false, sizeof(Vector3), ((uint8_t *)NULL) + buf_ofs); buf_ofs += sizeof(Vector3) * vertices; } else { @@ -1569,7 +1569,7 @@ void RasterizerSceneGLES3::_render_geometry(RenderList::Element *e) { glEnableVertexAttribArray(VS::ARRAY_TANGENT); glBufferSubData(GL_ARRAY_BUFFER, buf_ofs, sizeof(Plane) * vertices, c.tangents.ptr()); - glVertexAttribPointer(VS::ARRAY_TANGENT, 4, GL_FLOAT, false, sizeof(Plane) * vertices, ((uint8_t *)NULL) + buf_ofs); + glVertexAttribPointer(VS::ARRAY_TANGENT, 4, GL_FLOAT, false, sizeof(Plane), ((uint8_t *)NULL) + buf_ofs); buf_ofs += sizeof(Plane) * vertices; } else { diff --git a/drivers/gles3/shader_compiler_gles3.cpp b/drivers/gles3/shader_compiler_gles3.cpp index 21102e8c25..101978548d 100644 --- a/drivers/gles3/shader_compiler_gles3.cpp +++ b/drivers/gles3/shader_compiler_gles3.cpp @@ -812,6 +812,7 @@ ShaderCompilerGLES3::ShaderCompilerGLES3() { //for light actions[VS::SHADER_SPATIAL].renames["VIEW"] = "view"; actions[VS::SHADER_SPATIAL].renames["LIGHT_COLOR"] = "light_color"; + actions[VS::SHADER_SPATIAL].renames["LIGHT"] = "light"; actions[VS::SHADER_SPATIAL].renames["ATTENUATION"] = "attenuation"; actions[VS::SHADER_SPATIAL].renames["DIFFUSE_LIGHT"] = "diffuse_light"; actions[VS::SHADER_SPATIAL].renames["SPECULAR_LIGHT"] = "specular_light"; diff --git a/drivers/unix/packet_peer_udp_posix.cpp b/drivers/unix/packet_peer_udp_posix.cpp index 61d2737555..f6742d8114 100644 --- a/drivers/unix/packet_peer_udp_posix.cpp +++ b/drivers/unix/packet_peer_udp_posix.cpp @@ -65,7 +65,7 @@ int PacketPeerUDPPosix::get_available_packet_count() const { return queue_count; } -Error PacketPeerUDPPosix::get_packet(const uint8_t **r_buffer, int &r_buffer_size) const { +Error PacketPeerUDPPosix::get_packet(const uint8_t **r_buffer, int &r_buffer_size) { Error err = const_cast<PacketPeerUDPPosix *>(this)->_poll(false); if (err != OK) diff --git a/drivers/unix/packet_peer_udp_posix.h b/drivers/unix/packet_peer_udp_posix.h index e580d336b2..ad7be5bbe0 100644 --- a/drivers/unix/packet_peer_udp_posix.h +++ b/drivers/unix/packet_peer_udp_posix.h @@ -41,12 +41,12 @@ class PacketPeerUDPPosix : public PacketPeerUDP { PACKET_BUFFER_SIZE = 65536 }; - mutable RingBuffer<uint8_t> rb; + RingBuffer<uint8_t> rb; uint8_t recv_buffer[PACKET_BUFFER_SIZE]; - mutable uint8_t packet_buffer[PACKET_BUFFER_SIZE]; - mutable IP_Address packet_ip; - mutable int packet_port; - mutable int queue_count; + uint8_t packet_buffer[PACKET_BUFFER_SIZE]; + IP_Address packet_ip; + int packet_port; + int queue_count; int sockfd; bool sock_blocking; IP::Type sock_type; @@ -62,7 +62,7 @@ class PacketPeerUDPPosix : public PacketPeerUDP { public: virtual int get_available_packet_count() const; - virtual Error get_packet(const uint8_t **r_buffer, int &r_buffer_size) const; + virtual Error get_packet(const uint8_t **r_buffer, int &r_buffer_size); virtual Error put_packet(const uint8_t *p_buffer, int p_buffer_size); virtual int get_max_packet_size() const; diff --git a/platform/windows/packet_peer_udp_winsock.cpp b/drivers/windows/packet_peer_udp_winsock.cpp index d414ec891e..119ee68bd2 100644 --- a/platform/windows/packet_peer_udp_winsock.cpp +++ b/drivers/windows/packet_peer_udp_winsock.cpp @@ -27,6 +27,8 @@ /* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE */ /* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ /*************************************************************************/ +#ifdef WINDOWS_ENABLED + #include "packet_peer_udp_winsock.h" #include <winsock2.h> @@ -43,7 +45,7 @@ int PacketPeerUDPWinsock::get_available_packet_count() const { return queue_count; } -Error PacketPeerUDPWinsock::get_packet(const uint8_t **r_buffer, int &r_buffer_size) const { +Error PacketPeerUDPWinsock::get_packet(const uint8_t **r_buffer, int &r_buffer_size) { Error err = const_cast<PacketPeerUDPWinsock *>(this)->_poll(false); if (err != OK) @@ -291,3 +293,5 @@ PacketPeerUDPWinsock::~PacketPeerUDPWinsock() { close(); } + +#endif diff --git a/platform/windows/packet_peer_udp_winsock.h b/drivers/windows/packet_peer_udp_winsock.h index 8a6951fd6e..8ce2cff741 100644 --- a/platform/windows/packet_peer_udp_winsock.h +++ b/drivers/windows/packet_peer_udp_winsock.h @@ -27,6 +27,8 @@ /* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE */ /* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ /*************************************************************************/ +#ifdef WINDOWS_ENABLED + #ifndef PACKET_PEER_UDP_WINSOCK_H #define PACKET_PEER_UDP_WINSOCK_H @@ -39,12 +41,12 @@ class PacketPeerUDPWinsock : public PacketPeerUDP { PACKET_BUFFER_SIZE = 65536 }; - mutable RingBuffer<uint8_t> rb; + RingBuffer<uint8_t> rb; uint8_t recv_buffer[PACKET_BUFFER_SIZE]; - mutable uint8_t packet_buffer[PACKET_BUFFER_SIZE]; - mutable IP_Address packet_ip; - mutable int packet_port; - mutable int queue_count; + uint8_t packet_buffer[PACKET_BUFFER_SIZE]; + IP_Address packet_ip; + int packet_port; + int queue_count; int sockfd; bool sock_blocking; IP::Type sock_type; @@ -62,7 +64,7 @@ class PacketPeerUDPWinsock : public PacketPeerUDP { public: virtual int get_available_packet_count() const; - virtual Error get_packet(const uint8_t **r_buffer, int &r_buffer_size) const; + virtual Error get_packet(const uint8_t **r_buffer, int &r_buffer_size); virtual Error put_packet(const uint8_t *p_buffer, int p_buffer_size); virtual int get_max_packet_size() const; @@ -82,3 +84,5 @@ public: ~PacketPeerUDPWinsock(); }; #endif // PACKET_PEER_UDP_WINSOCK_H + +#endif diff --git a/platform/windows/stream_peer_winsock.cpp b/drivers/windows/stream_peer_tcp_winsock.cpp index 8b83215325..f4cd38079d 100644 --- a/platform/windows/stream_peer_winsock.cpp +++ b/drivers/windows/stream_peer_tcp_winsock.cpp @@ -1,5 +1,5 @@ /*************************************************************************/ -/* stream_peer_winsock.cpp */ +/* stream_peer_tcp_winsock.cpp */ /*************************************************************************/ /* This file is part of: */ /* GODOT ENGINE */ @@ -29,7 +29,7 @@ /*************************************************************************/ #ifdef WINDOWS_ENABLED -#include "stream_peer_winsock.h" +#include "stream_peer_tcp_winsock.h" #include <winsock2.h> #include <ws2tcpip.h> @@ -38,14 +38,14 @@ int winsock_refcount = 0; -StreamPeerTCP *StreamPeerWinsock::_create() { +StreamPeerTCP *StreamPeerTCPWinsock::_create() { - return memnew(StreamPeerWinsock); + return memnew(StreamPeerTCPWinsock); }; -void StreamPeerWinsock::make_default() { +void StreamPeerTCPWinsock::make_default() { - StreamPeerTCP::_create = StreamPeerWinsock::_create; + StreamPeerTCP::_create = StreamPeerTCPWinsock::_create; if (winsock_refcount == 0) { WSADATA data; @@ -54,7 +54,7 @@ void StreamPeerWinsock::make_default() { ++winsock_refcount; }; -void StreamPeerWinsock::cleanup() { +void StreamPeerTCPWinsock::cleanup() { --winsock_refcount; if (winsock_refcount == 0) { @@ -63,7 +63,7 @@ void StreamPeerWinsock::cleanup() { }; }; -Error StreamPeerWinsock::_block(int p_sockfd, bool p_read, bool p_write) const { +Error StreamPeerTCPWinsock::_block(int p_sockfd, bool p_read, bool p_write) const { fd_set read, write; FD_ZERO(&read); @@ -78,7 +78,7 @@ Error StreamPeerWinsock::_block(int p_sockfd, bool p_read, bool p_write) const { return ret < 0 ? FAILED : OK; }; -Error StreamPeerWinsock::_poll_connection() const { +Error StreamPeerTCPWinsock::_poll_connection() const { ERR_FAIL_COND_V(status != STATUS_CONNECTING || sockfd == INVALID_SOCKET, FAILED); @@ -108,7 +108,7 @@ Error StreamPeerWinsock::_poll_connection() const { return OK; }; -Error StreamPeerWinsock::write(const uint8_t *p_data, int p_bytes, int &r_sent, bool p_block) { +Error StreamPeerTCPWinsock::write(const uint8_t *p_data, int p_bytes, int &r_sent, bool p_block) { if (status == STATUS_NONE || status == STATUS_ERROR) { @@ -166,7 +166,7 @@ Error StreamPeerWinsock::write(const uint8_t *p_data, int p_bytes, int &r_sent, return OK; }; -Error StreamPeerWinsock::read(uint8_t *p_buffer, int p_bytes, int &r_received, bool p_block) { +Error StreamPeerTCPWinsock::read(uint8_t *p_buffer, int p_bytes, int &r_received, bool p_block) { if (!is_connected_to_host()) { @@ -224,29 +224,29 @@ Error StreamPeerWinsock::read(uint8_t *p_buffer, int p_bytes, int &r_received, b return OK; }; -Error StreamPeerWinsock::put_data(const uint8_t *p_data, int p_bytes) { +Error StreamPeerTCPWinsock::put_data(const uint8_t *p_data, int p_bytes) { int total; return write(p_data, p_bytes, total, true); }; -Error StreamPeerWinsock::put_partial_data(const uint8_t *p_data, int p_bytes, int &r_sent) { +Error StreamPeerTCPWinsock::put_partial_data(const uint8_t *p_data, int p_bytes, int &r_sent) { return write(p_data, p_bytes, r_sent, false); }; -Error StreamPeerWinsock::get_data(uint8_t *p_buffer, int p_bytes) { +Error StreamPeerTCPWinsock::get_data(uint8_t *p_buffer, int p_bytes) { int total; return read(p_buffer, p_bytes, total, true); }; -Error StreamPeerWinsock::get_partial_data(uint8_t *p_buffer, int p_bytes, int &r_received) { +Error StreamPeerTCPWinsock::get_partial_data(uint8_t *p_buffer, int p_bytes, int &r_received) { return read(p_buffer, p_bytes, r_received, false); }; -StreamPeerTCP::Status StreamPeerWinsock::get_status() const { +StreamPeerTCP::Status StreamPeerTCPWinsock::get_status() const { if (status == STATUS_CONNECTING) { _poll_connection(); @@ -255,7 +255,7 @@ StreamPeerTCP::Status StreamPeerWinsock::get_status() const { return status; }; -bool StreamPeerWinsock::is_connected_to_host() const { +bool StreamPeerTCPWinsock::is_connected_to_host() const { if (status == STATUS_NONE || status == STATUS_ERROR) { @@ -268,7 +268,7 @@ bool StreamPeerWinsock::is_connected_to_host() const { return (sockfd != INVALID_SOCKET); }; -void StreamPeerWinsock::disconnect_from_host() { +void StreamPeerTCPWinsock::disconnect_from_host() { if (sockfd != INVALID_SOCKET) closesocket(sockfd); @@ -281,7 +281,7 @@ void StreamPeerWinsock::disconnect_from_host() { peer_port = 0; }; -void StreamPeerWinsock::set_socket(int p_sockfd, IP_Address p_host, int p_port, IP::Type p_sock_type) { +void StreamPeerTCPWinsock::set_socket(int p_sockfd, IP_Address p_host, int p_port, IP::Type p_sock_type) { sockfd = p_sockfd; sock_type = p_sock_type; @@ -290,7 +290,7 @@ void StreamPeerWinsock::set_socket(int p_sockfd, IP_Address p_host, int p_port, peer_port = p_port; }; -Error StreamPeerWinsock::connect_to_host(const IP_Address &p_host, uint16_t p_port) { +Error StreamPeerTCPWinsock::connect_to_host(const IP_Address &p_host, uint16_t p_port) { ERR_FAIL_COND_V(!p_host.is_valid(), ERR_INVALID_PARAMETER); @@ -331,13 +331,13 @@ Error StreamPeerWinsock::connect_to_host(const IP_Address &p_host, uint16_t p_po return OK; }; -void StreamPeerWinsock::set_nodelay(bool p_enabled) { +void StreamPeerTCPWinsock::set_nodelay(bool p_enabled) { ERR_FAIL_COND(!is_connected_to_host()); int flag = p_enabled ? 1 : 0; setsockopt(sockfd, IPPROTO_TCP, TCP_NODELAY, (char *)&flag, sizeof(int)); } -int StreamPeerWinsock::get_available_bytes() const { +int StreamPeerTCPWinsock::get_available_bytes() const { unsigned long len; int ret = ioctlsocket(sockfd, FIONREAD, &len); @@ -345,17 +345,17 @@ int StreamPeerWinsock::get_available_bytes() const { return len; } -IP_Address StreamPeerWinsock::get_connected_host() const { +IP_Address StreamPeerTCPWinsock::get_connected_host() const { return peer_host; }; -uint16_t StreamPeerWinsock::get_connected_port() const { +uint16_t StreamPeerTCPWinsock::get_connected_port() const { return peer_port; }; -StreamPeerWinsock::StreamPeerWinsock() { +StreamPeerTCPWinsock::StreamPeerTCPWinsock() { sock_type = IP::TYPE_NONE; sockfd = INVALID_SOCKET; @@ -363,7 +363,7 @@ StreamPeerWinsock::StreamPeerWinsock() { peer_port = 0; }; -StreamPeerWinsock::~StreamPeerWinsock() { +StreamPeerTCPWinsock::~StreamPeerTCPWinsock() { disconnect_from_host(); }; diff --git a/platform/windows/stream_peer_winsock.h b/drivers/windows/stream_peer_tcp_winsock.h index 26e2a3e4c9..fef457c43f 100644 --- a/platform/windows/stream_peer_winsock.h +++ b/drivers/windows/stream_peer_tcp_winsock.h @@ -29,15 +29,15 @@ /*************************************************************************/ #ifdef WINDOWS_ENABLED -#ifndef STREAM_PEER_WINSOCK_H -#define STREAM_PEER_WINSOCK_H +#ifndef STREAM_PEER_TCP_WINSOCK_H +#define STREAM_PEER_TCP_WINSOCK_H #include "error_list.h" #include "core/io/ip_address.h" #include "core/io/stream_peer_tcp.h" -class StreamPeerWinsock : public StreamPeerTCP { +class StreamPeerTCPWinsock : public StreamPeerTCP { protected: mutable Status status; @@ -82,10 +82,10 @@ public: virtual void set_nodelay(bool p_enabled); - StreamPeerWinsock(); - ~StreamPeerWinsock(); + StreamPeerTCPWinsock(); + ~StreamPeerTCPWinsock(); }; -#endif // TCP_SOCKET_POSIX_H +#endif // STREAM_PEER_TCP_WINSOCK_H #endif diff --git a/platform/windows/tcp_server_winsock.cpp b/drivers/windows/tcp_server_winsock.cpp index de300befa7..49de279793 100644 --- a/platform/windows/tcp_server_winsock.cpp +++ b/drivers/windows/tcp_server_winsock.cpp @@ -27,9 +27,11 @@ /* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE */ /* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ /*************************************************************************/ +#ifdef WINDOWS_ENABLED + #include "tcp_server_winsock.h" -#include "stream_peer_winsock.h" +#include "stream_peer_tcp_winsock.h" #include <winsock2.h> #include <ws2tcpip.h> @@ -151,7 +153,7 @@ Ref<StreamPeerTCP> TCPServerWinsock::take_connection() { int fd = accept(listen_sockfd, (struct sockaddr *)&their_addr, &sin_size); ERR_FAIL_COND_V(fd == INVALID_SOCKET, NULL); - Ref<StreamPeerWinsock> conn = memnew(StreamPeerWinsock); + Ref<StreamPeerTCPWinsock> conn = memnew(StreamPeerTCPWinsock); IP_Address ip; int port; _set_ip_addr_port(ip, port, &their_addr); @@ -181,3 +183,5 @@ TCPServerWinsock::~TCPServerWinsock() { stop(); }; + +#endif diff --git a/platform/windows/tcp_server_winsock.h b/drivers/windows/tcp_server_winsock.h index a3e01098ed..fd16480167 100644 --- a/platform/windows/tcp_server_winsock.h +++ b/drivers/windows/tcp_server_winsock.h @@ -27,6 +27,8 @@ /* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE */ /* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ /*************************************************************************/ +#ifdef WINDOWS_ENABLED + #ifndef TCP_SERVER_WINSOCK_H #define TCP_SERVER_WINSOCK_H @@ -54,3 +56,5 @@ public: }; #endif + +#endif diff --git a/editor/dependency_editor.cpp b/editor/dependency_editor.cpp index ec0ca3add5..f357f1e51f 100644 --- a/editor/dependency_editor.cpp +++ b/editor/dependency_editor.cpp @@ -678,7 +678,7 @@ bool OrphanResourcesDialog::_fill_owners(EditorFileSystemDirectory *efsd, HashMa int ds = efsd->get_file_deps(i).size(); ti->set_text(1, itos(ds)); if (ds) { - ti->add_button(1, get_icon("Visible", "EditorIcons")); + ti->add_button(1, get_icon("GuiVisibilityVisible", "EditorIcons")); } ti->set_metadata(0, path); has_childs = true; diff --git a/editor/editor_export.cpp b/editor/editor_export.cpp index 3f618c3199..3585417d13 100644 --- a/editor/editor_export.cpp +++ b/editor/editor_export.cpp @@ -39,10 +39,10 @@ #include "io/zip_io.h" #include "os/file_access.h" #include "project_settings.h" +#include "scene/resources/scene_format_text.h" #include "script_language.h" -#include "version.h" - #include "thirdparty/misc/md5.h" +#include "version.h" static int _get_pad(int p_alignment, int p_n) { @@ -1288,8 +1288,18 @@ bool EditorExportPlatformPC::can_export(const Ref<EditorExportPreset> &p_preset, return valid; } -String EditorExportPlatformPC::get_binary_extension() const { - return extension; +String EditorExportPlatformPC::get_binary_extension(const Ref<EditorExportPreset> &p_preset) const { + for (Map<String, String>::Element *E = extensions.front(); E; E = E->next()) { + if (p_preset->get(E->key())) { + return extensions[E->key()]; + } + } + + if (extensions.has("default")) { + return extensions["default"]; + } + + return ""; } Error EditorExportPlatformPC::export_project(const Ref<EditorExportPreset> &p_preset, bool p_debug, const String &p_path, int p_flags) { @@ -1337,8 +1347,8 @@ Error EditorExportPlatformPC::export_project(const Ref<EditorExportPreset> &p_pr return save_pack(p_preset, pck_path); } -void EditorExportPlatformPC::set_extension(const String &p_extension) { - extension = p_extension; +void EditorExportPlatformPC::set_extension(const String &p_extension, const String &p_feature_key) { + extensions[p_feature_key] = p_extension; } void EditorExportPlatformPC::set_name(const String &p_name) { @@ -1399,3 +1409,30 @@ EditorExportPlatformPC::EditorExportPlatformPC() { chmod_flags = -1; } + +/////////////////////// + +void EditorExportTextSceneToBinaryPlugin::_export_file(const String &p_path, const String &p_type, const Set<String> &p_features) { + + String extension = p_path.get_extension().to_lower(); + if (extension != "tres" && extension != "tscn") { + return; + } + + print_line("exporting " + p_path); + + bool convert = GLOBAL_GET("editor/convert_text_resources_to_binary_on_export"); + if (!convert) + return; + String tmp_path = EditorSettings::get_singleton()->get_cache_dir().plus_file("file.res"); + Error err = ResourceFormatLoaderText::convert_file_to_binary(p_path, tmp_path); + ERR_FAIL_COND(err != OK); + Vector<uint8_t> data = FileAccess::get_file_as_array(tmp_path); + ERR_FAIL_COND(data.size() == 0); + add_file(p_path + ".converted.res", data, true); +} + +EditorExportTextSceneToBinaryPlugin::EditorExportTextSceneToBinaryPlugin() { + + GLOBAL_DEF("editor/convert_text_resources_to_binary_on_export", false); +} diff --git a/editor/editor_export.h b/editor/editor_export.h index 215a770a12..02b15aff10 100644 --- a/editor/editor_export.h +++ b/editor/editor_export.h @@ -240,7 +240,7 @@ public: virtual bool can_export(const Ref<EditorExportPreset> &p_preset, String &r_error, bool &r_missing_templates) const = 0; - virtual String get_binary_extension() const = 0; + virtual String get_binary_extension(const Ref<EditorExportPreset> &p_preset) const = 0; virtual Error export_project(const Ref<EditorExportPreset> &p_preset, bool p_debug, const String &p_path, int p_flags = 0) = 0; virtual void get_platform_features(List<String> *r_features) = 0; @@ -363,7 +363,7 @@ class EditorExportPlatformPC : public EditorExportPlatform { Ref<ImageTexture> logo; String name; String os_name; - String extension; + Map<String, String> extensions; String release_file_32; String release_file_64; @@ -385,10 +385,10 @@ public: virtual Ref<Texture> get_logo() const; virtual bool can_export(const Ref<EditorExportPreset> &p_preset, String &r_error, bool &r_missing_templates) const; - virtual String get_binary_extension() const; + virtual String get_binary_extension(const Ref<EditorExportPreset> &p_preset) const; virtual Error export_project(const Ref<EditorExportPreset> &p_preset, bool p_debug, const String &p_path, int p_flags = 0); - void set_extension(const String &p_extension); + void set_extension(const String &p_extension, const String &p_feature_key = "default"); void set_name(const String &p_name); void set_os_name(const String &p_name); @@ -408,4 +408,13 @@ public: EditorExportPlatformPC(); }; +class EditorExportTextSceneToBinaryPlugin : public EditorExportPlugin { + + GDCLASS(EditorExportTextSceneToBinaryPlugin, EditorExportPlugin) + +public: + virtual void _export_file(const String &p_path, const String &p_type, const Set<String> &p_features); + EditorExportTextSceneToBinaryPlugin(); +}; + #endif // EDITOR_IMPORT_EXPORT_H diff --git a/editor/editor_node.cpp b/editor/editor_node.cpp index d0d13fdbcf..cb8407386d 100644 --- a/editor/editor_node.cpp +++ b/editor/editor_node.cpp @@ -4708,6 +4708,7 @@ EditorNode::EditorNode() { EditorHelp::generate_doc(); //before any editor classes are crated SceneState::set_disable_placeholders(true); ResourceLoader::clear_translation_remaps(); //no remaps using during editor + ResourceLoader::clear_path_remaps(); editor_initialize_certificates(); //for asset sharing InputDefault *id = Object::cast_to<InputDefault>(Input::get_singleton()); @@ -5717,6 +5718,11 @@ EditorNode::EditorNode() { editor_plugins_force_over = memnew(EditorPluginList); editor_plugins_force_input_forwarding = memnew(EditorPluginList); + Ref<EditorExportTextSceneToBinaryPlugin> export_text_to_binary_plugin; + export_text_to_binary_plugin.instance(); + + EditorExport::get_singleton()->add_export_plugin(export_text_to_binary_plugin); + _edit_current(); current = NULL; diff --git a/editor/editor_sub_scene.cpp b/editor/editor_sub_scene.cpp index b81dfd3f46..fad9346b38 100644 --- a/editor/editor_sub_scene.cpp +++ b/editor/editor_sub_scene.cpp @@ -96,14 +96,54 @@ void EditorSubScene::_fill_tree(Node *p_node, TreeItem *p_parent) { } } -void EditorSubScene::ok_pressed() { +void EditorSubScene::_selected_changed() { + selection.clear(); + is_root = false; +} - TreeItem *s = tree->get_selected(); - if (!s) - return; - Node *selnode = s->get_metadata(0); - if (!selnode) +void EditorSubScene::_item_multi_selected(Object *p_object, int p_cell, bool p_selected) { + if (!is_root) { + TreeItem *item = Object::cast_to<TreeItem>(p_object); + ERR_FAIL_COND(!item); + + Node *n = item->get_metadata(0); + + if (!n) + return; + if (p_selected) { + if (n == scene) { + is_root = true; + selection.clear(); + } + selection.push_back(n); + } + } +} + +void EditorSubScene::_remove_selection_child(Node *n) { + if (n->get_child_count() > 0) { + for (int i = 0; i < n->get_child_count(); i++) { + Node *c = n->get_child(i); + List<Node *>::Element *E = selection.find(c); + if (E) { + selection.move_to_back(E); + selection.pop_back(); + } + if (c->get_child_count() > 0) { + _remove_selection_child(c); + } + } + } +} + +void EditorSubScene::ok_pressed() { + if (selection.size() <= 0) { return; + } + for (List<Node *>::Element *E = selection.front(); E; E = E->next()) { + Node *c = E->get(); + _remove_selection_child(c); + } emit_signal("subscene_selected"); hide(); clear(); @@ -127,37 +167,34 @@ void EditorSubScene::_reown(Node *p_node, List<Node *> *p_to_reown) { } void EditorSubScene::move(Node *p_new_parent, Node *p_new_owner) { - if (!scene) { return; } - TreeItem *s = tree->get_selected(); - if (!s) { - return; - } - Node *selnode = s->get_metadata(0); - if (!selnode) { + if (selection.size() <= 0) { return; } - List<Node *> to_reown; - _reown(selnode, &to_reown); - - if (selnode != scene) { - selnode->get_parent()->remove_child(selnode); - } + for (List<Node *>::Element *E = selection.front(); E; E = E->next()) { + Node *selnode = E->get(); + if (!selnode) { + return; + } + List<Node *> to_reown; + _reown(selnode, &to_reown); + if (selnode != scene) { + selnode->get_parent()->remove_child(selnode); + } - p_new_parent->add_child(selnode); - for (List<Node *>::Element *E = to_reown.front(); E; E = E->next()) { - E->get()->set_owner(p_new_owner); + p_new_parent->add_child(selnode); + for (List<Node *>::Element *E = to_reown.front(); E; E = E->next()) { + E->get()->set_owner(p_new_owner); + } } - - if (selnode != scene) { + if (!is_root) { memdelete(scene); } scene = NULL; - //return selnode; } @@ -172,12 +209,15 @@ void EditorSubScene::_bind_methods() { ClassDB::bind_method(D_METHOD("_path_selected"), &EditorSubScene::_path_selected); ClassDB::bind_method(D_METHOD("_path_changed"), &EditorSubScene::_path_changed); ClassDB::bind_method(D_METHOD("_path_browse"), &EditorSubScene::_path_browse); + ClassDB::bind_method(D_METHOD("_item_multi_selected"), &EditorSubScene::_item_multi_selected); + ClassDB::bind_method(D_METHOD("_selected_changed"), &EditorSubScene::_selected_changed); ADD_SIGNAL(MethodInfo("subscene_selected")); } EditorSubScene::EditorSubScene() { scene = NULL; + is_root = false; set_title(TTR("Select Node(s) to Import")); set_hide_on_ok(false); @@ -200,6 +240,11 @@ EditorSubScene::EditorSubScene() { tree = memnew(Tree); tree->set_v_size_flags(SIZE_EXPAND_FILL); vb->add_margin_child(TTR("Import From Node:"), tree, true); + tree->set_select_mode(Tree::SELECT_MULTI); + tree->connect("multi_selected", this, "_item_multi_selected"); + //tree->connect("nothing_selected", this, "_deselect_items"); + tree->connect("cell_selected", this, "_selected_changed"); + tree->connect("item_activated", this, "_ok", make_binds(), CONNECT_DEFERRED); file_dialog = memnew(EditorFileDialog); diff --git a/editor/editor_sub_scene.h b/editor/editor_sub_scene.h index 13ce19bbb2..db9d91018a 100644 --- a/editor/editor_sub_scene.h +++ b/editor/editor_sub_scene.h @@ -38,13 +38,18 @@ class EditorSubScene : public ConfirmationDialog { GDCLASS(EditorSubScene, ConfirmationDialog); + List<Node *> selection; LineEdit *path; Tree *tree; Node *scene; + bool is_root; EditorFileDialog *file_dialog; void _fill_tree(Node *p_node, TreeItem *p_parent); + void _selected_changed(); + void _item_multi_selected(Object *p_object, int p_cell, bool p_selected); + void _remove_selection_child(Node *c); void _reown(Node *p_node, List<Node *> *p_to_reown); void ok_pressed(); diff --git a/editor/editor_themes.cpp b/editor/editor_themes.cpp index 152eda7d91..cc0b292cc4 100644 --- a/editor/editor_themes.cpp +++ b/editor/editor_themes.cpp @@ -999,6 +999,12 @@ Ref<Theme> create_editor_theme(const Ref<Theme> p_theme) { theme->set_icon("bg", "ColorPickerButton", theme->get_icon("GuiMiniCheckerboard", "EditorIcons")); + // Information on 3D viewport + Ref<StyleBoxFlat> style_info_3d_viewport = style_default->duplicate(); + style_info_3d_viewport->set_bg_color(style_info_3d_viewport->get_bg_color() * Color(1, 1, 1, 0.5)); + style_info_3d_viewport->set_border_width_all(0); + theme->set_stylebox("Information3dViewport", "EditorStyles", style_info_3d_viewport); + // adaptive script theme constants // for comments and elements with lower relevance const Color dim_color = Color(font_color.r, font_color.g, font_color.b, 0.5); diff --git a/editor/filesystem_dock.cpp b/editor/filesystem_dock.cpp index 9ece36ea80..c30f077888 100644 --- a/editor/filesystem_dock.cpp +++ b/editor/filesystem_dock.cpp @@ -129,6 +129,7 @@ void FileSystemDock::_update_tree(bool keep_collapse_state) { } _create_tree(root, EditorFileSystem::get_singleton()->get_filesystem(), uncollapsed_paths); + tree->ensure_cursor_is_visible(); updating_tree = false; } @@ -590,10 +591,7 @@ void FileSystemDock::_select_file(int p_idx) { if (fpath != "res://") { fpath = fpath.substr(0, fpath.length() - 1); } - path = fpath; - _update_files(false); - current_path->set_text(path); - _push_to_history(); + navigate_to_path(fpath); } else { if (ResourceLoader::get_resource_type(fpath) == "PackedScene") { editor->open_request(fpath); @@ -1219,6 +1217,9 @@ void FileSystemDock::_go_to_file_list() { tree->hide(); file_list_vb->show(); button_favorite->hide(); + } else { + bool collapsed = tree->get_selected()->is_collapsed(); + tree->get_selected()->set_collapsed(!collapsed); } //file_options->show(); diff --git a/editor/icons/icon_GUI_visibility_hidden.svg b/editor/icons/icon_GUI_visibility_hidden.svg index 2add2e9eb8..61131c77c8 100644 --- a/editor/icons/icon_GUI_visibility_hidden.svg +++ b/editor/icons/icon_GUI_visibility_hidden.svg @@ -1,55 +1,3 @@ -<?xml version="1.0" encoding="UTF-8" standalone="no"?> -<svg - xmlns:dc="http://purl.org/dc/elements/1.1/" - xmlns:cc="http://creativecommons.org/ns#" - xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#" - xmlns:svg="http://www.w3.org/2000/svg" - xmlns="http://www.w3.org/2000/svg" - xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd" - xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape" - width="16" - height="16" - version="1.1" - viewBox="0 0 16 16" - id="svg2" - inkscape:version="0.91 r13725" - sodipodi:docname="icon_GUI_visibility_hidden.svg"> - <metadata - id="metadata12"> - <rdf:RDF> - <cc:Work - rdf:about=""> - <dc:format>image/svg+xml</dc:format> - <dc:type - rdf:resource="http://purl.org/dc/dcmitype/StillImage" /> - <dc:title /> - </cc:Work> - </rdf:RDF> - </metadata> - <defs - id="defs10" /> - <sodipodi:namedview - pagecolor="#ffffff" - bordercolor="#666666" - borderopacity="1" - objecttolerance="10" - gridtolerance="10" - guidetolerance="10" - inkscape:pageopacity="0" - inkscape:pageshadow="2" - inkscape:window-width="1920" - inkscape:window-height="1027" - id="namedview8" - showgrid="false" - inkscape:zoom="14.75" - inkscape:cx="18.882384" - inkscape:cy="7.2939487" - inkscape:window-x="-8" - inkscape:window-y="-8" - inkscape:window-maximized="1" - inkscape:current-layer="svg2" /> - <path - style="color:#000000;text-indent:0;text-decoration:none;text-decoration-line:none;text-decoration-style:solid;text-decoration-color:#000000;text-transform:none;white-space:normal;isolation:auto;mix-blend-mode:normal;solid-color:#000000;fill:#e0e0e0;fill-opacity:1;fill-rule:evenodd;color-rendering:auto;image-rendering:auto;shape-rendering:auto" - d="M 8.3320312 2.1328125 C 8.1166713 2.129146 7.900423 2.1368613 7.6855469 2.1542969 C 4.8418629 2.3850399 2.1034153 4.4237115 1.0449219 7.5722656 C 0.98765482 7.7577705 0.9856205 7.9559357 1.0390625 8.1425781 C 1.2458895 8.8664725 1.5352035 9.5092453 1.8730469 10.089844 L 12.501953 3.7890625 C 11.256805 2.6845102 9.797893 2.1577685 8.3320312 2.1328125 z M 14.554688 3.3046875 L 0.7421875 11.507812 L 1.4453125 12.695312 L 15.257812 4.4921875 L 14.554688 3.3046875 z M 14.169922 5.8847656 L 3.6171875 12.140625 C 4.9944165 13.294116 6.6188565 13.867188 8 13.867188 C 10.5 13.867188 13.836536 12.077978 14.960938 8.1425781 C 15.012856 7.9619931 15.012856 7.7704285 14.960938 7.5898438 C 14.731965 6.9583712 14.46336 6.3981967 14.169922 5.8847656 z " - id="path6" /> +<svg width="16" height="16" version="1.1" viewBox="0 0 16 16" xmlns="http://www.w3.org/2000/svg"> +<path d="m7.9998 2c-2.5567 0-5.7907 1.9477-6.9551 5.7051a1.0001 1.0001 0 0 0 -0.00586 0.5703c1.1244 3.9354 4.4609 5.7246 6.9609 5.7246s5.8365-1.7892 6.9609-5.7246a1.0001 1.0001 0 0 0 0 -0.5527c-1.1003-3.7876-4.4066-5.7227-6.9609-5.7227zm0 2a4 4 0 0 1 4 4 4 4 0 0 1 -4 4 4 4 0 0 1 -4 -4 4 4 0 0 1 4 -4zm0 2a2 2 0 0 0 -2 2 2 2 0 0 0 2 2 2 2 0 0 0 2 -2 2 2 0 0 0 -2 -2z" color="#000000" color-rendering="auto" fill="#e0e0e0" fill-opacity=".39216" fill-rule="evenodd" image-rendering="auto" shape-rendering="auto" solid-color="#000000" style="isolation:auto;mix-blend-mode:normal;text-decoration-color:#000000;text-decoration-line:none;text-decoration-style:solid;text-indent:0;text-transform:none;white-space:normal"/> </svg> diff --git a/editor/icons/icon_GUI_visibility_visible.svg b/editor/icons/icon_GUI_visibility_visible.svg index 11ae563779..e3aff37058 100644 --- a/editor/icons/icon_GUI_visibility_visible.svg +++ b/editor/icons/icon_GUI_visibility_visible.svg @@ -1,63 +1,3 @@ -<?xml version="1.0" encoding="UTF-8" standalone="no"?> -<svg - xmlns:dc="http://purl.org/dc/elements/1.1/" - xmlns:cc="http://creativecommons.org/ns#" - xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#" - xmlns:svg="http://www.w3.org/2000/svg" - xmlns="http://www.w3.org/2000/svg" - xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd" - xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape" - width="16" - height="16" - version="1.1" - viewBox="0 0 16 16" - id="svg2" - inkscape:version="0.91 r13725" - sodipodi:docname="icon_visibility_visible.svg"> - <metadata - id="metadata12"> - <rdf:RDF> - <cc:Work - rdf:about=""> - <dc:format>image/svg+xml</dc:format> - <dc:type - rdf:resource="http://purl.org/dc/dcmitype/StillImage" /> - <dc:title></dc:title> - </cc:Work> - </rdf:RDF> - </metadata> - <defs - id="defs10" /> - <sodipodi:namedview - pagecolor="#ffffff" - bordercolor="#666666" - borderopacity="1" - objecttolerance="10" - gridtolerance="10" - guidetolerance="10" - inkscape:pageopacity="0" - inkscape:pageshadow="2" - inkscape:window-width="1920" - inkscape:window-height="1027" - id="namedview8" - showgrid="false" - inkscape:zoom="14.75" - inkscape:cx="15.823281" - inkscape:cy="12.108563" - inkscape:window-x="-8" - inkscape:window-y="-8" - inkscape:window-maximized="1" - inkscape:current-layer="svg2" /> - <g - transform="translate(0 -1036.4)" - id="g4" - style="fill:#e0e0e0;fill-opacity:1"> - <path - transform="translate(0,1036.4)" - d="M 8,2 C 5.4433,2 2.2093,3.9477 1.0449,7.7051 c -0.0572671,0.1855049 -0.059303,0.3836676 -0.00586,0.57031 1.1244,3.9354 4.4609,5.7246 6.9609,5.7246 2.5000004,0 5.8365004,-1.7892 6.9609004,-5.7246 0.05192,-0.180585 0.05192,-0.372145 0,-0.55273 -1.1003,-3.7876 -4.4066,-5.7227 -6.9609004,-5.7227 z m 0,2 c 2.209139,0 4,1.790861 4,4 0,2.209139 -1.790861,4 -4,4 C 5.790861,12 4,10.209139 4,8 4,5.790861 5.790861,4 8,4 Z M 8,6 C 6.8954305,6 6,6.8954305 6,8 6,9.1045695 6.8954305,10 8,10 9.1045695,10 10,9.1045695 10,8 10,6.8954305 9.1045695,6 8,6 Z" - style="color:#000000;text-indent:0;text-decoration:none;text-decoration-line:none;text-decoration-style:solid;text-decoration-color:#000000;text-transform:none;white-space:normal;isolation:auto;mix-blend-mode:normal;solid-color:#000000;fill:#e0e0e0;fill-opacity:1;fill-rule:evenodd;color-rendering:auto;image-rendering:auto;shape-rendering:auto" - id="path6" - inkscape:connector-curvature="0" - sodipodi:nodetypes="cccsccccssssssssss" /> - </g> +<svg width="16" height="16" version="1.1" viewBox="0 0 16 16" xmlns="http://www.w3.org/2000/svg"> +<path d="m8 2c-2.5567 0-5.7907 1.9477-6.9551 5.7051a1.0001 1.0001 0 0 0 -0.00586 0.57031c1.1244 3.9354 4.4609 5.7246 6.9609 5.7246s5.8365-1.7892 6.9609-5.7246a1.0001 1.0001 0 0 0 0 -0.55273c-1.1003-3.7876-4.4066-5.7227-6.9609-5.7227zm0 2a4 4 0 0 1 4 4 4 4 0 0 1 -4 4 4 4 0 0 1 -4 -4 4 4 0 0 1 4 -4zm0 2a2 2 0 0 0 -2 2 2 2 0 0 0 2 2 2 2 0 0 0 2 -2 2 2 0 0 0 -2 -2z" color="#000000" color-rendering="auto" fill="#e0e0e0" fill-opacity=".99608" fill-rule="evenodd" image-rendering="auto" shape-rendering="auto" solid-color="#000000" style="isolation:auto;mix-blend-mode:normal;text-decoration-color:#000000;text-decoration-line:none;text-decoration-style:solid;text-indent:0;text-transform:none;white-space:normal"/> </svg> diff --git a/editor/icons/icon_GUI_visibility_xray.svg b/editor/icons/icon_GUI_visibility_xray.svg index 1fd9fcf1b5..b78709821f 100644 --- a/editor/icons/icon_GUI_visibility_xray.svg +++ b/editor/icons/icon_GUI_visibility_xray.svg @@ -1,61 +1,6 @@ -<?xml version="1.0" encoding="UTF-8" standalone="no"?> -<svg - xmlns:dc="http://purl.org/dc/elements/1.1/" - xmlns:cc="http://creativecommons.org/ns#" - xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#" - xmlns:svg="http://www.w3.org/2000/svg" - xmlns="http://www.w3.org/2000/svg" - xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd" - xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape" - width="16" - height="16" - version="1.1" - viewBox="0 0 16 16" - id="svg2" - inkscape:version="0.91 r13725" - sodipodi:docname="icon_GUI_visibility_xray.svg"> - <metadata - id="metadata12"> - <rdf:RDF> - <cc:Work - rdf:about=""> - <dc:format>image/svg+xml</dc:format> - <dc:type - rdf:resource="http://purl.org/dc/dcmitype/StillImage" /> - <dc:title /> - </cc:Work> - </rdf:RDF> - </metadata> - <defs - id="defs10" /> - <sodipodi:namedview - pagecolor="#ffffff" - bordercolor="#666666" - borderopacity="1" - objecttolerance="10" - gridtolerance="10" - guidetolerance="10" - inkscape:pageopacity="0" - inkscape:pageshadow="2" - inkscape:window-width="1920" - inkscape:window-height="1027" - id="namedview8" - showgrid="false" - inkscape:zoom="7.375" - inkscape:cx="43.019438" - inkscape:cy="-8.9853027" - inkscape:window-x="-8" - inkscape:window-y="-8" - inkscape:window-maximized="1" - inkscape:current-layer="svg2" /> - <g - transform="translate(0.20338214,-1036.671)" - id="g4" - style="fill:#e0e0e0;fill-opacity:1" /> - <path - id="path4154" - style="opacity:1;fill:#e0e0e0;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1.42799997;stroke-linecap:square;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1" - d="m 5.0107427,7.1191578 c -0.084872,0.2859445 -0.1282828,0.5825859 -0.128907,0.8808593 8.579e-4,0.263009 0.034983,0.5248532 0.101563,0.7792969 l 6.0312493,0 C 11.081887,8.5249547 11.116668,8.2631092 11.118164,8.0000171 11.11754,7.7017437 11.074129,7.4051023 10.989257,7.1191578 Z M 7.9999096,2.000005 c -2.5567,0 -5.7907,1.9477 -6.9551,5.7051 -0.057267,0.1855049 -0.059303,0.3836676 -0.00586,0.57031 1.1244,3.9354 4.4609,5.7246 6.9609,5.7246 2.4999994,0 5.8364994,-1.7892 6.9608994,-5.7246 0.05192,-0.180585 0.05192,-0.372145 0,-0.55273 -1.1003,-3.7876 -4.4066,-5.7227 -6.9608994,-5.7227 z m 0,2 c 2.2091384,0 3.9999994,1.790861 3.9999994,4 0,2.209139 -1.790861,4 -3.9999994,4 -2.209139,0 -4,-1.790861 -4,-4 0,-2.209139 1.790861,-4 4,-4 z" - inkscape:connector-curvature="0" - sodipodi:nodetypes="ccccccccccsccccsssss" /> +<svg width="16" height="16" version="1.1" viewBox="0 0 16 16" xmlns="http://www.w3.org/2000/svg"> +<g fill="#e0e0e0" fill-rule="evenodd" shape-rendering="auto"> +<path d="m7.9998 2c-2.5567 0-5.7907 1.9477-6.9551 5.7051a1.0001 1.0001 0 0 0 -0.00586 0.5703c1.1244 3.9354 4.4609 5.7246 6.9609 5.7246s5.8365-1.7892 6.9609-5.7246a1.0001 1.0001 0 0 0 0 -0.5527c-1.1003-3.7876-4.4066-5.7227-6.9609-5.7227zm0 2a4 4 0 0 1 4 4 4 4 0 0 1 -4 4 4 4 0 0 1 -4 -4 4 4 0 0 1 4 -4zm0 2a2 2 0 0 0 -2 2 2 2 0 0 0 2 2 2 2 0 0 0 2 -2 2 2 0 0 0 -2 -2z" color="#000000" color-rendering="auto" fill-opacity=".39216" image-rendering="auto" solid-color="#000000" style="isolation:auto;mix-blend-mode:normal;text-decoration-color:#000000;text-decoration-line:none;text-decoration-style:solid;text-indent:0;text-transform:none;white-space:normal"/> +<path d="m8 2c-2.5567 0-5.7907 1.9477-6.9551 5.7051a1.0001 1.0001 0 0 0 -0.00586 0.57031c1.1244 3.9354 4.4609 5.7246 6.9609 5.7246v-2a4 4 0 0 1 -4 -4 4 4 0 0 1 4 -4zm0 4a2 2 0 0 0 -2 2 2 2 0 0 0 2 2z" color="#000000" color-rendering="auto" fill-opacity=".99608" image-rendering="auto" solid-color="#000000" style="isolation:auto;mix-blend-mode:normal;text-decoration-color:#000000;text-decoration-line:none;text-decoration-style:solid;text-indent:0;text-transform:none;white-space:normal"/> +</g> </svg> diff --git a/editor/icons/icon_bake.svg b/editor/icons/icon_bake.svg index 4a9ccfed12..ca5245da10 100644 --- a/editor/icons/icon_bake.svg +++ b/editor/icons/icon_bake.svg @@ -1,5 +1,3 @@ <svg width="16" height="16" version="1.1" viewBox="0 0 16 16" xmlns="http://www.w3.org/2000/svg"> -<g transform="translate(0 -1036.4)"> -<path transform="translate(0 1036.4)" d="m2 1v2h12v-2h-12zm-1 3v9a2 2 0 0 0 2 2h10a2 2 0 0 0 2 -2v-9h-14zm2 1h1v1h-1v-1zm3 0h1v1h-1v-1zm3 0h1v1h-1v-1zm3 0h1v1h-1v-1zm-9 2h10v6h-10v-6zm3 1v1h4v-1h-4z" fill="#e0e0e0"/> -</g> +<path d="m2 1v2h12v-2h-12zm-1 3v9a2 2 0 0 0 2 2h10a2 2 0 0 0 2 -2v-9h-14zm2 1h1v1h-1v-1zm3 0h1v1h-1v-1zm3 0h1v1h-1v-1zm3 0h1v1h-1v-1zm-9 2h10v6h-10v-6zm3 1v1h4v-1h-4z" fill="#e0e0e0"/> </svg> diff --git a/editor/icons/icon_baked_light.svg b/editor/icons/icon_baked_light.svg deleted file mode 100644 index f5bf07a444..0000000000 --- a/editor/icons/icon_baked_light.svg +++ /dev/null @@ -1,5 +0,0 @@ -<svg width="16" height="16" version="1.1" viewBox="0 0 16 16" xmlns="http://www.w3.org/2000/svg"> -<g transform="translate(0 -1036.4)"> -<path transform="translate(0 1036.4)" d="m2 1v2h12v-2h-12zm-1 3v9a2 2 0 0 0 2 2h10a2 2 0 0 0 2 -2v-9h-14zm2 1h1v1h-1v-1zm3 0h1v1h-1v-1zm3 0h1v1h-1v-1zm3 0h1v1h-1v-1zm-9 2h10v6h-10v-6zm3 1v1h4v-1h-4z" fill="#fc9c9c"/> -</g> -</svg> diff --git a/editor/icons/icon_baked_light_instance.svg b/editor/icons/icon_baked_light_instance.svg deleted file mode 100644 index f5bf07a444..0000000000 --- a/editor/icons/icon_baked_light_instance.svg +++ /dev/null @@ -1,5 +0,0 @@ -<svg width="16" height="16" version="1.1" viewBox="0 0 16 16" xmlns="http://www.w3.org/2000/svg"> -<g transform="translate(0 -1036.4)"> -<path transform="translate(0 1036.4)" d="m2 1v2h12v-2h-12zm-1 3v9a2 2 0 0 0 2 2h10a2 2 0 0 0 2 -2v-9h-14zm2 1h1v1h-1v-1zm3 0h1v1h-1v-1zm3 0h1v1h-1v-1zm3 0h1v1h-1v-1zm-9 2h10v6h-10v-6zm3 1v1h4v-1h-4z" fill="#fc9c9c"/> -</g> -</svg> diff --git a/editor/icons/icon_baked_light_sampler.svg b/editor/icons/icon_baked_light_sampler.svg deleted file mode 100644 index 0bf630039d..0000000000 --- a/editor/icons/icon_baked_light_sampler.svg +++ /dev/null @@ -1,5 +0,0 @@ -<svg width="16" height="16" version="1.1" viewBox="0 0 16 16" xmlns="http://www.w3.org/2000/svg"> -<g transform="translate(0 -1036.4)"> -<path transform="translate(0 1036.4)" d="m2 1v2h12v-2h-12zm-1 3v9a2 2 0 0 0 2 2h4v-2h-4v-6h4 6 2v-3h-14zm2 1h1v1h-1v-1zm3 0h1v1h-1v-1zm3 0h1v1h-1v-1zm3 0h1v1h-1v-1zm-6 3v1h1v-1h-1zm4 1a1 1 0 0 0 -1 1v4a1 1 0 0 0 1 1h4a1 1 0 0 0 1 -1v-4a1 1 0 0 0 -1 -1h-4zm3 1a1 1 0 0 1 1 1 1 1 0 0 1 -1 1 1 1 0 0 1 -1 -1 1 1 0 0 1 1 -1zm-2 2a1 1 0 0 1 1 1 1 1 0 0 1 -1 1 1 1 0 0 1 -1 -1 1 1 0 0 1 1 -1z" fill="#fc9c9c"/> -</g> -</svg> diff --git a/editor/icons/icon_baked_lightmap.svg b/editor/icons/icon_baked_lightmap.svg new file mode 100644 index 0000000000..6c6586244e --- /dev/null +++ b/editor/icons/icon_baked_lightmap.svg @@ -0,0 +1,3 @@ +<svg width="16" height="16" version="1.1" viewBox="0 0 16 16" xmlns="http://www.w3.org/2000/svg"> +<path d="m2 1v2h12v-2h-12zm-1 3v9a2 2 0 0 0 2 2h10a2 2 0 0 0 2 -2v-9h-14zm2 1h1v1h-1v-1zm3 0h1v1h-1v-1zm3 0h1v1h-1v-1zm3 0h1v1h-1v-1zm-9 2h10v6h-10v-6zm3 1v1h4v-1h-4z" fill="#fc9c9c"/> +</svg> diff --git a/editor/icons/icon_baked_lightmap_data.svg b/editor/icons/icon_baked_lightmap_data.svg new file mode 100644 index 0000000000..b5ddd24680 --- /dev/null +++ b/editor/icons/icon_baked_lightmap_data.svg @@ -0,0 +1,3 @@ +<svg width="16" height="16" version="1.1" viewBox="0 0 16 16" xmlns="http://www.w3.org/2000/svg"> +<path d="m1 1v2h2v-2h-2zm3 0v2h2v-2h-2zm4 0v2h6v-2h-6zm-7 3v2h2v-2h-2zm3 0v2h2v-2h-2zm4 0v3h5v6h-5v2h5a2 2 0 0 0 2 -2v-9h-7zm1 1h1v1h-1v-1zm3 0h1v1h-1v-1zm-11 2v2h2v-2h-2zm3 0v2h2v-2h-2zm4 1v1h2v-1h-2zm-7 2v2h2v-2h-2zm3 0v2h2v-2h-2zm-3 3v2h2v-2h-2zm3 0v2h2v-2h-2z" fill="#e0e0e0"/> +</svg> diff --git a/editor/icons/icon_editor_handle.svg b/editor/icons/icon_editor_handle.svg index 05f3e2f2cc..f215820ddc 100644 --- a/editor/icons/icon_editor_handle.svg +++ b/editor/icons/icon_editor_handle.svg @@ -1,7 +1,5 @@ <svg width="10" height="10" version="1.1" viewBox="0 0 10 10" xmlns="http://www.w3.org/2000/svg"> -<g transform="translate(0 -1042.4)"> -<ellipse cx="5" cy="1047.4" rx="5" ry="5" fill-opacity=".29412"/> -<ellipse cx="5" cy="1047.4" rx="4" ry="4" fill="#fff"/> -<ellipse cx="5" cy="1047.4" rx="3" ry="3" fill="#ff8484"/> -</g> +<circle cx="5" cy="5" r="5" fill-opacity=".29412"/> +<circle cx="5" cy="5" r="4" fill="#fff"/> +<circle cx="5" cy="5" r="3" fill="#ff8484"/> </svg> diff --git a/editor/icons/icon_editor_handle_add.svg b/editor/icons/icon_editor_handle_add.svg index be61cd53f9..a8bc1fdc9b 100644 --- a/editor/icons/icon_editor_handle_add.svg +++ b/editor/icons/icon_editor_handle_add.svg @@ -1,5 +1,5 @@ <svg width="10" height="10" version="1.1" viewBox="0 0 10 10" xmlns="http://www.w3.org/2000/svg"> - <circle cx="5" cy="5" r="5" fill-opacity=".29412"/> - <circle cx="5" cy="5" r="4" fill="#474747"/> - <path d="m4 2v2h-2v2h2v2h2v-2h2v-2h-2v-2z" fill="#84ffb1"/> +<circle cx="5" cy="5" r="5" fill-opacity=".29412"/> +<circle cx="5" cy="5" r="4" fill="#474747"/> +<path d="m4 2v2h-2v2h2v2h2v-2h2v-2h-2v-2z" fill="#84ffb1"/> </svg> diff --git a/editor/icons/icon_editor_plugin.svg b/editor/icons/icon_editor_plugin.svg index 528a583a04..e68d787bd3 100644 --- a/editor/icons/icon_editor_plugin.svg +++ b/editor/icons/icon_editor_plugin.svg @@ -1,9 +1,3 @@ <svg width="16" height="16" version="1.1" viewBox="0 0 16 16" xmlns="http://www.w3.org/2000/svg"> -<g transform="translate(0 -1036.4)" fill="#e0e0e0" fill-opacity=".99608"> -<path d="m2 1038.4v8h8v-8z" fill-rule="evenodd" stroke="#e0e0e0" stroke-linejoin="round" stroke-opacity=".99608" stroke-width="2"/> -<circle cx="13" cy="1042.4" r="2"/> -<circle cx="6" cy="1049.4" r="2"/> -<rect x="5" y="1046.4" width="2" height="2"/> -<rect x="10" y="1041.4" width="2" height="2"/> -</g> +<path d="m2 1c-0.55226 1e-4 -0.99994 0.4477-1 1v8c5.52e-5 0.5523 0.44774 0.9999 1 1h3v0.27148a2 2 0 0 0 -1 1.7285 2 2 0 0 0 2 2 2 2 0 0 0 2 -2 2 2 0 0 0 -1 -1.7305v-0.26953h3c0.55226-1e-4 0.99994-0.4477 1-1v-3h0.27148a2 2 0 0 0 1.7285 1 2 2 0 0 0 2 -2 2 2 0 0 0 -2 -2 2 2 0 0 0 -1.7305 1h-0.26953v-3c-5.5e-5 -0.5523-0.44774-0.9999-1-1h-8z" color="#000000" color-rendering="auto" dominant-baseline="auto" fill="#e0e0e0" fill-opacity=".99608" fill-rule="evenodd" image-rendering="auto" shape-rendering="auto" solid-color="#000000" style="font-feature-settings:normal;font-variant-alternates:normal;font-variant-caps:normal;font-variant-ligatures:normal;font-variant-numeric:normal;font-variant-position:normal;isolation:auto;mix-blend-mode:normal;shape-padding:0;text-decoration-color:#000000;text-decoration-line:none;text-decoration-style:solid;text-indent:0;text-orientation:mixed;text-transform:none;white-space:normal"/> </svg> diff --git a/editor/icons/icon_gizmo_baked_lightmap.svg b/editor/icons/icon_gizmo_baked_lightmap.svg new file mode 100644 index 0000000000..cc21b7c1c5 --- /dev/null +++ b/editor/icons/icon_gizmo_baked_lightmap.svg @@ -0,0 +1,4 @@ +<svg width="128" height="128" version="1.1" viewBox="0 0 128 128" xmlns="http://www.w3.org/2000/svg"> +<path d="m18 8c-2.209 2.2e-4 -3.9998 1.791-4 4l0.01563 20h-6.0156c-2.209 2.2e-4 -3.9998 1.791-4 4v71.076c0 9.3065 7.6174 16.924 16.924 16.924h61.076c2.209-2e-4 3.9998-1.791 4-4v-12c-2.21e-4 -2.209-1.791-3.9998-4-4h-58v-40h20v12c2.21e-4 2.209 1.791 3.9998 4 4h32c2.209-2e-4 3.9998-1.791 4-4v-12h20v4c2e-3 0.72576 0.20093 1.4374 0.57617 2.0586-0.19584-6e-3 -0.37901-0.058594-0.57617-0.058594-10.998 0-20 9.0016-20 20-4e-6 0-4e-6 0.0098 0 0.0098 0.0088 6.2734 3.0833 12.01 8 15.756v2.2383c0 2.8834 1.66 5.3456 4 6.75v5.2461c2.21e-4 2.209 1.791 3.9998 4 4h8c2.209-2e-4 3.9998-1.791 4-4v-5.248c2.3405-1.4043 4-3.8682 4-6.752v-2.2344c4.9179-3.7475 7.9931-9.4866 8-15.762 0-7.935-4.7186-14.774-11.459-18h7.459c2.209-2.2e-4 3.9998-1.791 4-4v-32c-2.2e-4 -2.209-1.791-3.9998-4-4l-6-0.003906v-19.996c-2.2e-4 -2.209-1.791-3.9998-4-4zm8 38c1.1519 0 2 0.84806 2 2 3e-6 1.1519-0.84806 2-2 2s-2-0.84806-2-2c-3e-6 -1.1519 0.84806-2 2-2zm25 0c1.1519 0 2 0.84806 2 2 3e-6 1.1519-0.84806 2-2 2s-2-0.84806-2-2c-3e-6 -1.1519 0.84806-2 2-2zm26 0c1.1519 0 2 0.84806 2 2 3e-6 1.1519-0.84806 2-2 2s-2-0.84806-2-2c-3e-6 -1.1519 0.84806-2 2-2zm25 0c1.1519 0 2 0.84806 2 2s-0.84806 2-2 2-2-0.84806-2-2c-3e-6 -1.1519 0.84806-2 2-2zm2 38c3.3611 0 6 2.6388 6 6 0 3.361-2.639 6-6 6-3.361 0-6-2.639-6-6 0-3.3612 2.6389-6 6-6z" color="#000000" color-rendering="auto" dominant-baseline="auto" fill-opacity=".29412" image-rendering="auto" shape-rendering="auto" solid-color="#000000" style="font-feature-settings:normal;font-variant-alternates:normal;font-variant-caps:normal;font-variant-ligatures:normal;font-variant-numeric:normal;font-variant-position:normal;isolation:auto;mix-blend-mode:normal;shape-padding:0;text-decoration-color:#000000;text-decoration-line:none;text-decoration-style:solid;text-indent:0;text-orientation:mixed;text-transform:none;white-space:normal"/> +<path d="m18 12v16h92v-16zm-10 24v71.076c0 7.1594 5.7644 12.924 12.924 12.924h61.076v-12h-62v-48h88v8h12v-32zm18 6c3.3137-1e-5 6 2.6863 6 6 9e-6 3.3137-2.6863 6-6 6-3.3137 1e-5 -6-2.6863-6-6-9e-6 -3.3137 2.6863-6 6-6zm25 0c3.3137-1e-5 6 2.6863 6 6 9e-6 3.3137-2.6863 6-6 6-3.3137 1e-5 -6-2.6863-6-6-9e-6 -3.3137 2.6863-6 6-6zm26 0c3.3137-1e-5 6 2.6863 6 6 9e-6 3.3137-2.6863 6-6 6-3.3137 1e-5 -6-2.6863-6-6-9e-6 -3.3137 2.6863-6 6-6zm25 0c3.3137-1e-5 6 2.6863 6 6 1e-5 3.3137-2.6863 6-6 6-3.3137 1e-5 -6-2.6863-6-6-9e-6 -3.3137 2.6863-6 6-6zm-54 26v8h32v-8zm56 6c-8.8365 0-16 7.1634-16 16 8e-3 5.7082 3.0565 10.98 8 13.834v4.166c0 2.216 1.784 4 4 4h8c2.216 0 4-1.784 4-4v-4.1602c4.945-2.855 7.9937-8.1299 8-13.84 0-8.8366-7.1635-16-16-16zm0 6c5.5228 0 10 4.4771 10 10 0 5.5228-4.4772 10-10 10-5.5228 0-10-4.4772-10-10 0-5.5229 4.4772-10 10-10zm-4 36v4h8v-4z" fill="#f7f5cf"/> +</svg> diff --git a/editor/icons/icon_hidden.svg b/editor/icons/icon_hidden.svg deleted file mode 100644 index 8328156e76..0000000000 --- a/editor/icons/icon_hidden.svg +++ /dev/null @@ -1,5 +0,0 @@ -<svg width="16" height="16" version="1.1" viewBox="0 0 16 16" xmlns="http://www.w3.org/2000/svg"> -<g transform="translate(0 -1036.4)"> -<path transform="translate(0 1036.4)" d="m2.9609 7.7266l-1.9219 0.54883c0.31999 1.12 0.8236 2.0593 1.4316 2.8398l-0.83398 0.83398 1.4141 1.4141 0.84375-0.84375c0.98585 0.74762 2.0766 1.2067 3.1055 1.3867v1.0938h2v-1.0938c1.0288-0.17998 2.1196-0.6391 3.1055-1.3867l0.84375 0.84375 1.4141-1.4141-0.83398-0.83398c0.60804-0.78055 1.1117-1.7199 1.4316-2.8398l-1.9219-0.54883c-0.8756 3.0646-3.5391 4.2734-5.0391 4.2734s-4.1635-1.2088-5.0391-4.2734z" color="#000000" color-rendering="auto" dominant-baseline="auto" fill="#e0e0e0" fill-opacity=".99608" fill-rule="evenodd" image-rendering="auto" shape-rendering="auto" solid-color="#000000" style="filter-blend-mode:normal;filter-gaussianBlur-deviation:0;font-feature-settings:normal;font-variant-alternates:normal;font-variant-caps:normal;font-variant-east-asian:normal;font-variant-ligatures:normal;font-variant-numeric:normal;font-variant-position:normal;isolation:auto;mix-blend-mode:normal;shape-padding:0;text-decoration-color:#000000;text-decoration-line:none;text-decoration-style:solid;text-indent:0;text-orientation:mixed;text-transform:none;white-space:normal"/> -</g> -</svg> diff --git a/editor/icons/icon_kinematic_body_2d.svg b/editor/icons/icon_kinematic_body_2d.svg index 51026e5f28..0441e499c0 100644 --- a/editor/icons/icon_kinematic_body_2d.svg +++ b/editor/icons/icon_kinematic_body_2d.svg @@ -1,7 +1,7 @@ <svg width="16" height="16" version="1.1" viewBox="0 0 16 16" xmlns="http://www.w3.org/2000/svg"> <g transform="translate(0 -1036.4)"> -<g transform="translate(.49212 -.0044019)" fill="#a5b7f5" fill-opacity=".98824"> -<path transform="translate(0 1036.4)" d="m6 1c-0.55401 0-1 0.44599-1 1v3c0 0.55401 0.44599 1 1 1h1v0.99023a1.0001 1.0001 0 0 0 -0.31641 0.0625l-2.0508 0.68359-0.68359-2.0508a1.0001 1.0001 0 0 0 -0.99023 -0.69727 1.0001 1.0001 0 0 0 -0.9082 1.3281l1 3a1.0001 1.0001 0 0 0 1.2656 0.63281l1.6836-0.56055v0.61133c0 0.04088 0.018715 0.07566 0.023437 0.11523l-4.5781 3.0527a1.0001 1.0001 0 1 0 1.1094 1.6641l5.0566-3.3711 1.4941 2.9863a1.0001 1.0001 0 0 0 1.2109 0.50195l3-1a1.0001 1.0001 0 1 0 -0.63281 -1.8965l-2.1777 0.72461-0.97461-1.9512c0.2759-0.17764 0.46875-0.47227 0.46875-0.82617v-1h1.3828l0.72266 1.4473a1.0001 1.0001 0 1 0 1.7891 -0.89453l-1-2a1.0001 1.0001 0 0 0 -0.89453 -0.55273h-3v-1h1c0.55401 0 1-0.44599 1-1v-3c0-0.55401-0.44599-1-1-1zm0 2h1v2h-1z" fill="#a5b7f5" fill-opacity=".98824"/> +<g transform="translate(.49212 -.0044019)" fill="#a5b7f3"> +<path transform="translate(0 1036.4)" d="m6 1c-0.55401 0-1 0.44599-1 1v3c0 0.55401 0.44599 1 1 1h1v0.99023a1.0001 1.0001 0 0 0 -0.31641 0.0625l-2.0508 0.68359-0.68359-2.0508a1.0001 1.0001 0 0 0 -0.99023 -0.69727 1.0001 1.0001 0 0 0 -0.9082 1.3281l1 3a1.0001 1.0001 0 0 0 1.2656 0.63281l1.6836-0.56055v0.61133c0 0.04088 0.018715 0.07566 0.023437 0.11523l-4.5781 3.0527a1.0001 1.0001 0 1 0 1.1094 1.6641l5.0566-3.3711 1.4941 2.9863a1.0001 1.0001 0 0 0 1.2109 0.50195l3-1a1.0001 1.0001 0 1 0 -0.63281 -1.8965l-2.1777 0.72461-0.97461-1.9512c0.2759-0.17764 0.46875-0.47227 0.46875-0.82617v-1h1.3828l0.72266 1.4473a1.0001 1.0001 0 1 0 1.7891 -0.89453l-1-2a1.0001 1.0001 0 0 0 -0.89453 -0.55273h-3v-1h1c0.55401 0 1-0.44599 1-1v-3c0-0.55401-0.44599-1-1-1zm0 2h1v2h-1z" fill="#a5b7f3"/> </g> </g> </svg> diff --git a/editor/icons/icon_plugin_script.svg b/editor/icons/icon_plugin_script.svg new file mode 100644 index 0000000000..763cca3a92 --- /dev/null +++ b/editor/icons/icon_plugin_script.svg @@ -0,0 +1,3 @@ +<svg width="16" height="16" version="1.1" viewBox="0 0 16 16" xmlns="http://www.w3.org/2000/svg"> +<path d="m7 1l-0.56445 2.2578c-0.23643 0.075851-0.46689 0.16921-0.68945 0.2793l-1.9883-1.1934-1.4141 1.4141 1.1953 1.9941c-0.11191 0.22113-0.20723 0.45028-0.28516 0.68555l-2.2539 0.5625v2l2.2578 0.56445c0.048141 0.14946 0.11579 0.29137 0.17773 0.43555h0.58789c0.51595-0.6841 1.1988-1.2456 2.0195-1.5957-0.028019-0.13296-0.042416-0.26842-0.042969-0.4043 9.6e-6 -1.1046 0.89543-2 2-2 1.1046 9.6e-6 2 0.89543 2 2-1.737e-4 0.1345-0.013915 0.26865-0.041016 0.40039 0.82295 0.35108 1.509 0.91301 2.0254 1.5996h0.58008c0.063668-0.14463 0.13192-0.2874 0.18164-0.4375l2.2539-0.5625v-2l-2.2578-0.56445c-0.075942-0.23577-0.1693-0.46557-0.2793-0.6875l1.1934-1.9902-1.4141-1.4141-1.9941 1.1953c-0.22113-0.11191-0.45028-0.20723-0.68555-0.28516l-0.5625-2.2539h-2zm1 6a1 1 0 0 0 -0.99805 0.92969 1 1 0 0 0 -0.0019531 0.070312v2.1738a3 3 0 0 0 -2 2.8262h1v2h1v-2h2v2h1v-2h1a3 3 0 0 0 -0.015625 -0.29883 3 3 0 0 0 -1.9844 -2.5254v-2.1758a1 1 0 0 0 -1 -1z" fill="#e0e0e0"/> +</svg> diff --git a/editor/icons/icon_proxy_texture.svg b/editor/icons/icon_proxy_texture.svg new file mode 100644 index 0000000000..15ed5e7f2b --- /dev/null +++ b/editor/icons/icon_proxy_texture.svg @@ -0,0 +1,5 @@ +<svg width="16" height="16" version="1.1" viewBox="0 0 16 16" xmlns="http://www.w3.org/2000/svg"> +<g transform="translate(0 -1036.4)"> +<path transform="translate(0 1036.4)" d="m1 1v4h4v-4h-4zm6 0v2h6v8h-6v4h7a1 1 0 0 0 1 -1v-12a1 1 0 0 0 -1 -1h-7zm2 4v1h-1v1h-1v3h1 2 2v-2h-1v-2h-1v-1h-1zm-8 1v4h4v-4h-4zm0 5v4h4v-4h-4z" fill="#e0e0e0" fill-opacity=".99608"/> +</g> +</svg> diff --git a/editor/icons/icon_sprite.svg b/editor/icons/icon_sprite.svg index 09fc2f0979..11ad42ec98 100644 --- a/editor/icons/icon_sprite.svg +++ b/editor/icons/icon_sprite.svg @@ -1,3 +1,3 @@ <svg width="16" height="16" version="1.1" viewBox="0 0 16 16" xmlns="http://www.w3.org/2000/svg"> -<path d="m5 1c-2.216 0-4 1.784-4 4v6c0 2.216 1.784 4 4 4h6c2.216 0 4-1.784 4-4v-6c0-2.216-1.784-4-4-4h-6zm-1 5c0.554 0 1 0.446 1 1v2c0 0.554-0.446 1-1 1s-1-0.446-1-1v-2c0-0.554 0.446-1 1-1zm8 0c0.554 0 1 0.446 1 1v2c0 0.554-0.446 1-1 1s-1-0.446-1-1v-2c0-0.554 0.446-1 1-1zm-1.8887 5.1074a1.0001 1.0001 0 0 1 0.7168 1.7207c-0.74987 0.74987-1.7676 1.1719-2.8281 1.1719s-2.0783-0.422-2.8281-1.1719a1.0001 1.0001 0 0 1 0.69727 -1.7168 1.0001 1.0001 0 0 1 0.7168 0.30273c0.37534 0.37535 0.88325 0.58594 1.4141 0.58594s1.0387-0.21059 1.4141-0.58594a1.0001 1.0001 0 0 1 0.69727 -0.30664z" fill="#a5b7f6" fill-opacity=".98824"/> +<path d="m5 1c-2.216 0-4 1.784-4 4v6c0 2.216 1.784 4 4 4h6c2.216 0 4-1.784 4-4v-6c0-2.216-1.784-4-4-4h-6zm-1 5c0.554 0 1 0.446 1 1v2c0 0.554-0.446 1-1 1s-1-0.446-1-1v-2c0-0.554 0.446-1 1-1zm8 0c0.554 0 1 0.446 1 1v2c0 0.554-0.446 1-1 1s-1-0.446-1-1v-2c0-0.554 0.446-1 1-1zm-1.8887 5.1074a1.0001 1.0001 0 0 1 0.7168 1.7207c-0.74987 0.74987-1.7676 1.1719-2.8281 1.1719s-2.0783-0.422-2.8281-1.1719a1.0001 1.0001 0 0 1 0.69727 -1.7168 1.0001 1.0001 0 0 1 0.7168 0.30273c0.37534 0.37535 0.88325 0.58594 1.4141 0.58594s1.0387-0.21059 1.4141-0.58594a1.0001 1.0001 0 0 1 0.69727 -0.30664z" fill="#a5b7f3"/> </svg> diff --git a/editor/icons/icon_visible.svg b/editor/icons/icon_visible.svg deleted file mode 100644 index 7d157d7b7f..0000000000 --- a/editor/icons/icon_visible.svg +++ /dev/null @@ -1,5 +0,0 @@ -<svg width="16" height="16" version="1.1" viewBox="0 0 16 16" xmlns="http://www.w3.org/2000/svg"> -<g transform="translate(0 -1036.4)"> -<path transform="translate(0 1036.4)" d="m8 2c-2.5567 0-5.7907 1.9477-6.9551 5.7051a1.0001 1.0001 0 0 0 -0.0058594 0.57031c1.1244 3.9354 4.4609 5.7246 6.9609 5.7246s5.8365-1.7892 6.9609-5.7246a1.0001 1.0001 0 0 0 0 -0.55273c-1.1003-3.7876-4.4066-5.7227-6.9609-5.7227zm0 2a4 4 0 0 1 4 4 4 4 0 0 1 -4 4 4 4 0 0 1 -4 -4 4 4 0 0 1 4 -4zm0 2a2 2 0 0 0 -2 2 2 2 0 0 0 2 2 2 2 0 0 0 2 -2 2 2 0 0 0 -2 -2z" color="#000000" color-rendering="auto" fill="#e0e0e0" fill-opacity=".99608" fill-rule="evenodd" image-rendering="auto" shape-rendering="auto" solid-color="#000000" style="block-progression:tb;isolation:auto;mix-blend-mode:normal;text-decoration-color:#000000;text-decoration-line:none;text-decoration-style:solid;text-indent:0;text-transform:none;white-space:normal"/> -</g> -</svg> diff --git a/editor/plugins/baked_lightmap_editor_plugin.cpp b/editor/plugins/baked_lightmap_editor_plugin.cpp index 9ae3a4c771..08f4d06ef7 100644 --- a/editor/plugins/baked_lightmap_editor_plugin.cpp +++ b/editor/plugins/baked_lightmap_editor_plugin.cpp @@ -79,7 +79,7 @@ BakedLightmapEditorPlugin::BakedLightmapEditorPlugin(EditorNode *p_node) { editor = p_node; bake = memnew(Button); - bake->set_icon(editor->get_gui_base()->get_icon("BakedLight", "EditorIcons")); + bake->set_icon(editor->get_gui_base()->get_icon("Bake", "EditorIcons")); bake->set_text(TTR("Bake Lightmaps")); bake->hide(); bake->connect("pressed", this, "_bake"); diff --git a/editor/plugins/gi_probe_editor_plugin.cpp b/editor/plugins/gi_probe_editor_plugin.cpp index 443cd2e41f..416b0edb20 100644 --- a/editor/plugins/gi_probe_editor_plugin.cpp +++ b/editor/plugins/gi_probe_editor_plugin.cpp @@ -90,7 +90,7 @@ GIProbeEditorPlugin::GIProbeEditorPlugin(EditorNode *p_node) { editor = p_node; bake = memnew(Button); - bake->set_icon(editor->get_gui_base()->get_icon("BakedLight", "EditorIcons")); + bake->set_icon(editor->get_gui_base()->get_icon("Bake", "EditorIcons")); bake->set_text(TTR("Bake GI Probe")); bake->hide(); bake->connect("pressed", this, "_bake"); diff --git a/editor/plugins/mesh_instance_editor_plugin.h b/editor/plugins/mesh_instance_editor_plugin.h index 68c149f98a..32c779509a 100644 --- a/editor/plugins/mesh_instance_editor_plugin.h +++ b/editor/plugins/mesh_instance_editor_plugin.h @@ -35,9 +35,9 @@ #include "scene/3d/mesh_instance.h" #include "scene/gui/spin_box.h" -class MeshInstanceEditor : public Node { +class MeshInstanceEditor : public Control { - GDCLASS(MeshInstanceEditor, Node); + GDCLASS(MeshInstanceEditor, Control); enum Menu { diff --git a/editor/plugins/script_editor_plugin.cpp b/editor/plugins/script_editor_plugin.cpp index c02b3458e5..591e6dac56 100644 --- a/editor/plugins/script_editor_plugin.cpp +++ b/editor/plugins/script_editor_plugin.cpp @@ -1329,12 +1329,12 @@ void ScriptEditor::_members_overview_selected(int p_idx) { if (!se) { return; } - Dictionary state; - state["scroll_position"] = members_overview->get_item_metadata(p_idx); + // Go to the member's line and reset the cursor column. We can't just change scroll_position + // directly, since code might be folded. + se->goto_line(members_overview->get_item_metadata(p_idx)); + Dictionary state = se->get_edit_state(); state["column"] = 0; - state["row"] = members_overview->get_item_metadata(p_idx); se->set_edit_state(state); - se->ensure_focus(); } void ScriptEditor::_help_overview_selected(int p_idx) { @@ -1845,6 +1845,11 @@ void ScriptEditor::apply_scripts() const { } } +void ScriptEditor::open_script_create_dialog(const String &p_base_name, const String &p_base_path) { + _menu_option(FILE_NEW); + script_create_dialog->config(p_base_name, p_base_path); +} + void ScriptEditor::_editor_play() { debugger->start(); @@ -2548,6 +2553,7 @@ void ScriptEditor::_bind_methods() { ClassDB::bind_method(D_METHOD("get_current_script"), &ScriptEditor::_get_current_script); ClassDB::bind_method(D_METHOD("get_open_scripts"), &ScriptEditor::_get_open_scripts); + ClassDB::bind_method(D_METHOD("open_script_create_dialog", "base_name", "base_path"), &ScriptEditor::open_script_create_dialog); ADD_SIGNAL(MethodInfo("editor_script_changed", PropertyInfo(Variant::OBJECT, "script", PROPERTY_HINT_RESOURCE_TYPE, "Script"))); ADD_SIGNAL(MethodInfo("script_close", PropertyInfo(Variant::OBJECT, "script", PROPERTY_HINT_RESOURCE_TYPE, "Script"))); diff --git a/editor/plugins/script_editor_plugin.h b/editor/plugins/script_editor_plugin.h index ffd42d18ca..9d5c110dec 100644 --- a/editor/plugins/script_editor_plugin.h +++ b/editor/plugins/script_editor_plugin.h @@ -360,6 +360,7 @@ public: void ensure_focus_current(); void apply_scripts() const; + void open_script_create_dialog(const String &p_base_name, const String &p_base_path); void ensure_select_current(); diff --git a/editor/plugins/script_text_editor.cpp b/editor/plugins/script_text_editor.cpp index 95f2739927..0610f55b3f 100644 --- a/editor/plugins/script_text_editor.cpp +++ b/editor/plugins/script_text_editor.cpp @@ -537,10 +537,6 @@ void ScriptTextEditor::set_edit_state(const Variant &p_state) { code_editor->get_text_edit()->cursor_set_line(state["row"]); code_editor->get_text_edit()->set_v_scroll(state["scroll_position"]); code_editor->get_text_edit()->grab_focus(); - - //int scroll_pos; - //int cursor_column; - //int cursor_row; } String ScriptTextEditor::get_name() { @@ -924,26 +920,7 @@ void ScriptTextEditor::_edit_option(int p_op) { if (scr.is_null()) return; - tx->begin_complex_operation(); - if (tx->is_selection_active()) { - tx->indent_selection_left(); - } else { - int begin = tx->cursor_get_line(); - String line_text = tx->get_line(begin); - // begins with tab - if (line_text.begins_with("\t")) { - line_text = line_text.substr(1, line_text.length()); - tx->set_line(begin, line_text); - } - // begins with 4 spaces - else if (line_text.begins_with(" ")) { - line_text = line_text.substr(4, line_text.length()); - tx->set_line(begin, line_text); - } - } - tx->end_complex_operation(); - tx->update(); - //tx->deselect(); + tx->indent_left(); } break; case EDIT_INDENT_RIGHT: { @@ -951,18 +928,7 @@ void ScriptTextEditor::_edit_option(int p_op) { if (scr.is_null()) return; - tx->begin_complex_operation(); - if (tx->is_selection_active()) { - tx->indent_selection_right(); - } else { - int begin = tx->cursor_get_line(); - String line_text = tx->get_line(begin); - line_text = '\t' + line_text; - tx->set_line(begin, line_text); - } - tx->end_complex_operation(); - tx->update(); - //tx->deselect(); + tx->indent_right(); } break; case EDIT_DELETE_LINE: { @@ -1503,14 +1469,15 @@ void ScriptTextEditor::_make_context_menu(bool p_selection, bool p_color, bool p context_menu->add_shortcut(ED_GET_SHORTCUT("script_text_editor/select_all"), EDIT_SELECT_ALL); context_menu->add_shortcut(ED_GET_SHORTCUT("script_text_editor/undo"), EDIT_UNDO); context_menu->add_shortcut(ED_GET_SHORTCUT("script_text_editor/redo"), EDIT_REDO); + context_menu->add_separator(); + context_menu->add_shortcut(ED_GET_SHORTCUT("script_text_editor/indent_left"), EDIT_INDENT_LEFT); + context_menu->add_shortcut(ED_GET_SHORTCUT("script_text_editor/indent_right"), EDIT_INDENT_RIGHT); + context_menu->add_shortcut(ED_GET_SHORTCUT("script_text_editor/toggle_comment"), EDIT_TOGGLE_COMMENT); if (p_selection) { context_menu->add_separator(); context_menu->add_shortcut(ED_GET_SHORTCUT("script_text_editor/convert_to_uppercase"), EDIT_TO_UPPERCASE); context_menu->add_shortcut(ED_GET_SHORTCUT("script_text_editor/convert_to_lowercase"), EDIT_TO_LOWERCASE); - context_menu->add_shortcut(ED_GET_SHORTCUT("script_text_editor/indent_left"), EDIT_INDENT_LEFT); - context_menu->add_shortcut(ED_GET_SHORTCUT("script_text_editor/indent_right"), EDIT_INDENT_RIGHT); - context_menu->add_shortcut(ED_GET_SHORTCUT("script_text_editor/toggle_comment"), EDIT_TOGGLE_COMMENT); } if (p_can_fold || p_is_folded) context_menu->add_shortcut(ED_GET_SHORTCUT("script_text_editor/toggle_fold_line"), EDIT_TOGGLE_FOLD_LINE); diff --git a/editor/plugins/shader_editor_plugin.cpp b/editor/plugins/shader_editor_plugin.cpp index b390070b4a..3e00776dfd 100644 --- a/editor/plugins/shader_editor_plugin.cpp +++ b/editor/plugins/shader_editor_plugin.cpp @@ -161,7 +161,7 @@ void ShaderTextEditor::_load_theme_settings() { for (const Map<StringName, ShaderLanguage::FunctionInfo>::Element *E = ShaderTypes::get_singleton()->get_functions(VisualServer::ShaderMode(shader->get_mode())).front(); E; E = E->next()) { - for (const Map<StringName, ShaderLanguage::DataType>::Element *F = E->get().built_ins.front(); F; F = F->next()) { + for (const Map<StringName, ShaderLanguage::BuiltInInfo>::Element *F = E->get().built_ins.front(); F; F = F->next()) { keywords.push_back(F->key()); } } @@ -379,26 +379,7 @@ void ShaderEditor::_menu_option(int p_option) { if (shader.is_null()) return; - tx->begin_complex_operation(); - if (tx->is_selection_active()) { - tx->indent_selection_left(); - } else { - int begin = tx->cursor_get_line(); - String line_text = tx->get_line(begin); - // begins with tab - if (line_text.begins_with("\t")) { - line_text = line_text.substr(1, line_text.length()); - tx->set_line(begin, line_text); - } - // begins with 4 spaces - else if (line_text.begins_with(" ")) { - line_text = line_text.substr(4, line_text.length()); - tx->set_line(begin, line_text); - } - } - tx->end_complex_operation(); - tx->update(); - //tx->deselect(); + tx->indent_left(); } break; case EDIT_INDENT_RIGHT: { @@ -407,18 +388,7 @@ void ShaderEditor::_menu_option(int p_option) { if (shader.is_null()) return; - tx->begin_complex_operation(); - if (tx->is_selection_active()) { - tx->indent_selection_right(); - } else { - int begin = tx->cursor_get_line(); - String line_text = tx->get_line(begin); - line_text = '\t' + line_text; - tx->set_line(begin, line_text); - } - tx->end_complex_operation(); - tx->update(); - //tx->deselect(); + tx->indent_right(); } break; case EDIT_DELETE_LINE: { diff --git a/editor/plugins/spatial_editor_plugin.cpp b/editor/plugins/spatial_editor_plugin.cpp index cefc957ebf..59da5112ae 100644 --- a/editor/plugins/spatial_editor_plugin.cpp +++ b/editor/plugins/spatial_editor_plugin.cpp @@ -2219,15 +2219,9 @@ void SpatialEditorViewport::_notification(int p_what) { viewport->set_hdr(hdr); bool show_info = view_menu->get_popup()->is_item_checked(view_menu->get_popup()->get_item_index(VIEW_INFORMATION)); - if (show_info != info->is_visible()) { - if (show_info) - info->show(); - else - info->hide(); - } + info_label->set_visible(show_info); if (show_info) { - String text; text += TTR("Objects Drawn") + ": " + itos(viewport->get_render_info(Viewport::RENDER_INFO_OBJECTS_IN_FRAME)) + "\n"; text += TTR("Material Changes") + ": " + itos(viewport->get_render_info(Viewport::RENDER_INFO_MATERIAL_CHANGES_IN_FRAME)) + "\n"; @@ -2235,38 +2229,19 @@ void SpatialEditorViewport::_notification(int p_what) { text += TTR("Surface Changes") + ": " + itos(viewport->get_render_info(Viewport::RENDER_INFO_SURFACE_CHANGES_IN_FRAME)) + "\n"; text += TTR("Draw Calls") + ": " + itos(viewport->get_render_info(Viewport::RENDER_INFO_DRAW_CALLS_IN_FRAME)) + "\n"; text += TTR("Vertices") + ": " + itos(viewport->get_render_info(Viewport::RENDER_INFO_VERTICES_IN_FRAME)); - - if (info_label->get_text() != text || surface->get_size() != prev_size) { - info_label->set_text(text); - Size2 ms = info->get_minimum_size(); - info->set_position(surface->get_size() - ms - Vector2(20, 20) * EDSCALE); - } + info_label->set_text(text); } // FPS Counter. bool show_fps = view_menu->get_popup()->is_item_checked(view_menu->get_popup()->get_item_index(VIEW_FPS)); - if (show_fps != fps->is_visible()) { - if (show_fps) - fps->show(); - else - fps->hide(); - } + fps_label->set_visible(show_fps); if (show_fps) { String text; const float temp_fps = Engine::get_singleton()->get_frames_per_second(); text += TTR("FPS") + ": " + itos(temp_fps) + " (" + String::num(1000.0f / temp_fps, 2) + " ms)"; - - if (fps_label->get_text() != text || surface->get_size() != prev_size) { - fps_label->set_text(text); - Size2 ms = fps->get_size(); - Size2 size = surface->get_size(); - size.y = ms.y + 20; - fps->set_position(size - ms - Vector2(20, 0) * EDSCALE); - } + fps_label->set_text(text); } - - prev_size = surface->get_size(); } if (p_what == NOTIFICATION_ENTER_TREE) { @@ -2275,8 +2250,8 @@ void SpatialEditorViewport::_notification(int p_what) { surface->connect("gui_input", this, "_sinput"); surface->connect("mouse_entered", this, "_smouseenter"); surface->connect("mouse_exited", this, "_smouseexit"); - info->add_style_override("panel", get_stylebox("panel", "Panel")); - fps->add_style_override("panel", get_stylebox("panel", "Panel")); + info_label->add_style_override("normal", editor->get_gui_base()->get_stylebox("Information3dViewport", "EditorStyles")); + fps_label->add_style_override("normal", editor->get_gui_base()->get_stylebox("Information3dViewport", "EditorStyles")); preview_camera->set_icon(get_icon("Camera", "EditorIcons")); _init_gizmo_instance(index); } @@ -2773,8 +2748,10 @@ void SpatialEditorViewport::set_can_preview(Camera *p_preview) { if (!preview_camera->is_pressed()) { if (p_preview) { + fps_label->set_anchor_and_margin(MARGIN_TOP, ANCHOR_BEGIN, 15 * EDSCALE + preview_camera->get_size().height); preview_camera->show(); } else { + fps_label->set_anchor_and_margin(MARGIN_TOP, ANCHOR_BEGIN, 10 * EDSCALE); preview_camera->hide(); } } @@ -3399,20 +3376,24 @@ SpatialEditorViewport::SpatialEditorViewport(SpatialEditor *p_spatial_editor, Ed preview_node = NULL; - info = memnew(PanelContainer); - info->set_self_modulate(Color(1, 1, 1, 0.4)); - surface->add_child(info); info_label = memnew(Label); - info->add_child(info_label); - info->hide(); + info_label->set_anchor_and_margin(MARGIN_LEFT, ANCHOR_END, -90 * EDSCALE); + info_label->set_anchor_and_margin(MARGIN_TOP, ANCHOR_END, -90 * EDSCALE); + info_label->set_anchor_and_margin(MARGIN_RIGHT, ANCHOR_END, -10 * EDSCALE); + info_label->set_anchor_and_margin(MARGIN_BOTTOM, ANCHOR_END, -10 * EDSCALE); + info_label->set_h_grow_direction(GROW_DIRECTION_BEGIN); + info_label->set_v_grow_direction(GROW_DIRECTION_BEGIN); + surface->add_child(info_label); + info_label->hide(); // FPS Counter. - fps = memnew(PanelContainer); - fps->set_self_modulate(Color(1, 1, 1, 0.4)); - surface->add_child(fps); fps_label = memnew(Label); - fps->add_child(fps_label); - fps->hide(); + fps_label->set_anchor_and_margin(MARGIN_LEFT, ANCHOR_END, -90 * EDSCALE); + fps_label->set_anchor_and_margin(MARGIN_TOP, ANCHOR_BEGIN, 10 * EDSCALE); + fps_label->set_anchor_and_margin(MARGIN_RIGHT, ANCHOR_END, -10 * EDSCALE); + fps_label->set_h_grow_direction(GROW_DIRECTION_BEGIN); + surface->add_child(fps_label); + fps_label->hide(); accept = NULL; @@ -3884,8 +3865,7 @@ Dictionary SpatialEditor::get_state() const { d["rotate_snap"] = get_rotate_snap(); d["scale_snap"] = get_scale_snap(); - int local_coords_index = transform_menu->get_popup()->get_item_index(MENU_TRANSFORM_LOCAL_COORDS); - d["local_coords"] = transform_menu->get_popup()->is_item_checked(local_coords_index); + d["local_coords"] = tool_option_button[TOOL_OPT_LOCAL_COORDS]->is_pressed(); int vc = 0; if (view_menu->get_popup()->is_item_checked(view_menu->get_popup()->get_item_index(MENU_VIEW_USE_1_VIEWPORT))) @@ -3923,8 +3903,7 @@ void SpatialEditor::set_state(const Dictionary &p_state) { if (d.has("snap_enabled")) { snap_enabled = d["snap_enabled"]; - int snap_enabled_idx = transform_menu->get_popup()->get_item_index(MENU_TRANSFORM_USE_SNAP); - transform_menu->get_popup()->set_item_checked(snap_enabled_idx, snap_enabled); + tool_option_button[TOOL_OPT_LOCAL_COORDS]->set_pressed(d["snap_enabled"]); } if (d.has("translate_snap")) @@ -3937,8 +3916,7 @@ void SpatialEditor::set_state(const Dictionary &p_state) { snap_scale->set_text(d["scale_snap"]); if (d.has("local_coords")) { - int local_coords_idx = transform_menu->get_popup()->get_item_index(MENU_TRANSFORM_LOCAL_COORDS); - transform_menu->get_popup()->set_item_checked(local_coords_idx, d["local_coords"]); + tool_option_button[TOOL_OPT_LOCAL_COORDS]->set_pressed(d["local_coords"]); update_transform_gizmo(); } @@ -4078,6 +4056,22 @@ void SpatialEditor::_xform_dialog_action() { undo_redo->commit_action(); } +void SpatialEditor::_menu_item_toggled(bool pressed, int p_option) { + + switch (p_option) { + case MENU_TOOL_LOCAL_COORDS: { + + tool_option_button[TOOL_OPT_LOCAL_COORDS]->set_pressed(pressed); + update_transform_gizmo(); + } break; + + case MENU_TOOL_USE_SNAP: { + tool_option_button[TOOL_OPT_USE_SNAP]->set_pressed(pressed); + snap_enabled = pressed; + } break; + } +} + void SpatialEditor::_menu_item_pressed(int p_option) { switch (p_option) { @@ -4091,29 +4085,13 @@ void SpatialEditor::_menu_item_pressed(int p_option) { for (int i = 0; i < TOOL_MAX; i++) tool_button[i]->set_pressed(i == p_option); tool_mode = (ToolMode)p_option; - - //static const char *_mode[]={"Selection Mode.","Translation Mode.","Rotation Mode.","Scale Mode.","List Selection Mode."}; - //set_message(_mode[p_option],3); update_transform_gizmo(); } break; - case MENU_TRANSFORM_USE_SNAP: { - - bool is_checked = transform_menu->get_popup()->is_item_checked(transform_menu->get_popup()->get_item_index(p_option)); - snap_enabled = !is_checked; - transform_menu->get_popup()->set_item_checked(transform_menu->get_popup()->get_item_index(p_option), snap_enabled); - } break; case MENU_TRANSFORM_CONFIGURE_SNAP: { snap_dialog->popup_centered(Size2(200, 180)); } break; - case MENU_TRANSFORM_LOCAL_COORDS: { - - bool is_checked = transform_menu->get_popup()->is_item_checked(transform_menu->get_popup()->get_item_index(p_option)); - transform_menu->get_popup()->set_item_checked(transform_menu->get_popup()->get_item_index(p_option), !is_checked); - update_transform_gizmo(); - - } break; case MENU_TRANSFORM_DIALOG: { for (int i = 0; i < 3; i++) { @@ -4718,6 +4696,19 @@ void SpatialEditor::_unhandled_key_input(Ref<InputEvent> p_event) { else if (ED_IS_SHORTCUT("spatial_editor/tool_scale", p_event)) _menu_item_pressed(MENU_TOOL_SCALE); + + else if (ED_IS_SHORTCUT("spatial_editor/local_coords", p_event)) + if (are_local_coords_enabled()) { + _menu_item_toggled(false, MENU_TOOL_LOCAL_COORDS); + } else { + _menu_item_toggled(true, MENU_TOOL_LOCAL_COORDS); + } + else if (ED_IS_SHORTCUT("spatial_editor/snap", p_event)) + if (is_snap_enabled()) { + _menu_item_toggled(false, MENU_TOOL_USE_SNAP); + } else { + _menu_item_toggled(true, MENU_TOOL_USE_SNAP); + } } } } @@ -4733,6 +4724,9 @@ void SpatialEditor::_notification(int p_what) { tool_button[SpatialEditor::TOOL_LOCK_SELECTED]->set_icon(get_icon("Lock", "EditorIcons")); tool_button[SpatialEditor::TOOL_UNLOCK_SELECTED]->set_icon(get_icon("Unlock", "EditorIcons")); + tool_option_button[SpatialEditor::TOOL_OPT_LOCAL_COORDS]->set_icon(get_icon("Object", "EditorIcons")); + tool_option_button[SpatialEditor::TOOL_OPT_USE_SNAP]->set_icon(get_icon("Snap", "EditorIcons")); + view_menu->get_popup()->set_item_icon(view_menu->get_popup()->get_item_index(MENU_VIEW_USE_1_VIEWPORT), get_icon("Panels1", "EditorIcons")); view_menu->get_popup()->set_item_icon(view_menu->get_popup()->get_item_index(MENU_VIEW_USE_2_VIEWPORTS), get_icon("Panels2", "EditorIcons")); view_menu->get_popup()->set_item_icon(view_menu->get_popup()->get_item_index(MENU_VIEW_USE_2_VIEWPORTS_ALT), get_icon("Panels2Alt", "EditorIcons")); @@ -4768,6 +4762,9 @@ void SpatialEditor::_notification(int p_what) { tool_button[SpatialEditor::TOOL_MODE_SCALE]->set_icon(get_icon("ToolScale", "EditorIcons")); tool_button[SpatialEditor::TOOL_MODE_LIST_SELECT]->set_icon(get_icon("ListSelect", "EditorIcons")); + tool_option_button[SpatialEditor::TOOL_OPT_LOCAL_COORDS]->set_icon(get_icon("Object", "EditorIcons")); + tool_option_button[SpatialEditor::TOOL_OPT_USE_SNAP]->set_icon(get_icon("Snap", "EditorIcons")); + view_menu->get_popup()->set_item_icon(view_menu->get_popup()->get_item_index(MENU_VIEW_USE_1_VIEWPORT), get_icon("Panels1", "EditorIcons")); view_menu->get_popup()->set_item_icon(view_menu->get_popup()->get_item_index(MENU_VIEW_USE_2_VIEWPORTS), get_icon("Panels2", "EditorIcons")); view_menu->get_popup()->set_item_icon(view_menu->get_popup()->get_item_index(MENU_VIEW_USE_2_VIEWPORTS_ALT), get_icon("Panels2Alt", "EditorIcons")); @@ -4886,6 +4883,7 @@ void SpatialEditor::_bind_methods() { ClassDB::bind_method("_unhandled_key_input", &SpatialEditor::_unhandled_key_input); ClassDB::bind_method("_node_removed", &SpatialEditor::_node_removed); ClassDB::bind_method("_menu_item_pressed", &SpatialEditor::_menu_item_pressed); + ClassDB::bind_method("_menu_item_toggled", &SpatialEditor::_menu_item_toggled); ClassDB::bind_method("_xform_dialog_action", &SpatialEditor::_xform_dialog_action); ClassDB::bind_method("_get_editor_data", &SpatialEditor::_get_editor_data); ClassDB::bind_method("_request_gizmo", &SpatialEditor::_request_gizmo); @@ -4949,6 +4947,7 @@ SpatialEditor::SpatialEditor(EditorNode *p_editor) { Vector<Variant> button_binds; button_binds.resize(1); + String sct; tool_button[TOOL_MODE_SELECT] = memnew(ToolButton); hbc_menu->add_child(tool_button[TOOL_MODE_SELECT]); @@ -4960,7 +4959,6 @@ SpatialEditor::SpatialEditor(EditorNode *p_editor) { tool_button[TOOL_MODE_SELECT]->set_tooltip(TTR("Select Mode (Q)\n") + keycode_get_string(KEY_MASK_CMD) + TTR("Drag: Rotate\nAlt+Drag: Move\nAlt+RMB: Depth list selection")); tool_button[TOOL_MODE_MOVE] = memnew(ToolButton); - hbc_menu->add_child(tool_button[TOOL_MODE_MOVE]); tool_button[TOOL_MODE_MOVE]->set_toggle_mode(true); tool_button[TOOL_MODE_MOVE]->set_flat(true); @@ -4984,9 +4982,6 @@ SpatialEditor::SpatialEditor(EditorNode *p_editor) { tool_button[TOOL_MODE_SCALE]->connect("pressed", this, "_menu_item_pressed", button_binds); tool_button[TOOL_MODE_SCALE]->set_tooltip(TTR("Scale Mode (R)")); - VSeparator *vs = memnew(VSeparator); - hbc_menu->add_child(vs); - tool_button[TOOL_MODE_LIST_SELECT] = memnew(ToolButton); hbc_menu->add_child(tool_button[TOOL_MODE_LIST_SELECT]); tool_button[TOOL_MODE_LIST_SELECT]->set_toggle_mode(true); @@ -5007,6 +5002,29 @@ SpatialEditor::SpatialEditor(EditorNode *p_editor) { tool_button[TOOL_UNLOCK_SELECTED]->connect("pressed", this, "_menu_item_pressed", button_binds); tool_button[TOOL_UNLOCK_SELECTED]->set_tooltip(TTR("Unlock the selected object (can be moved).")); + VSeparator *vs = memnew(VSeparator); + hbc_menu->add_child(vs); + + tool_option_button[TOOL_OPT_LOCAL_COORDS] = memnew(ToolButton); + hbc_menu->add_child(tool_option_button[TOOL_OPT_LOCAL_COORDS]); + tool_option_button[TOOL_OPT_LOCAL_COORDS]->set_toggle_mode(true); + tool_option_button[TOOL_OPT_LOCAL_COORDS]->set_flat(true); + button_binds[0] = MENU_TOOL_LOCAL_COORDS; + tool_option_button[TOOL_OPT_LOCAL_COORDS]->connect("toggled", this, "_menu_item_toggled", button_binds); + ED_SHORTCUT("spatial_editor/local_coords", TTR("Local Coords"), KEY_T); + sct = ED_GET_SHORTCUT("spatial_editor/local_coords").ptr()->get_as_text(); + tool_option_button[TOOL_OPT_LOCAL_COORDS]->set_tooltip(vformat(TTR("Local Space Mode (%s)"), sct)); + + tool_option_button[TOOL_OPT_USE_SNAP] = memnew(ToolButton); + hbc_menu->add_child(tool_option_button[TOOL_OPT_USE_SNAP]); + tool_option_button[TOOL_OPT_USE_SNAP]->set_toggle_mode(true); + tool_option_button[TOOL_OPT_USE_SNAP]->set_flat(true); + button_binds[0] = MENU_TOOL_USE_SNAP; + tool_option_button[TOOL_OPT_USE_SNAP]->connect("toggled", this, "_menu_item_toggled", button_binds); + ED_SHORTCUT("spatial_editor/snap", TTR("Snap"), KEY_Y); + sct = ED_GET_SHORTCUT("spatial_editor/snap").ptr()->get_as_text(); + tool_option_button[TOOL_OPT_USE_SNAP]->set_tooltip(vformat(TTR("Snap Mode (%s)"), sct)); + vs = memnew(VSeparator); hbc_menu->add_child(vs); @@ -5021,7 +5039,6 @@ SpatialEditor::SpatialEditor(EditorNode *p_editor) { ED_SHORTCUT("spatial_editor/left_view", TTR("Left View"), KEY_MASK_ALT + KEY_KP_3); ED_SHORTCUT("spatial_editor/right_view", TTR("Right View"), KEY_KP_3); ED_SHORTCUT("spatial_editor/switch_perspective_orthogonal", TTR("Switch Perspective/Orthogonal view"), KEY_KP_5); - ED_SHORTCUT("spatial_editor/snap", TTR("Snap"), KEY_S); ED_SHORTCUT("spatial_editor/insert_anim_key", TTR("Insert Animation Key"), KEY_K); ED_SHORTCUT("spatial_editor/focus_origin", TTR("Focus Origin"), KEY_O); ED_SHORTCUT("spatial_editor/focus_selection", TTR("Focus Selection"), KEY_F); @@ -5043,12 +5060,8 @@ SpatialEditor::SpatialEditor(EditorNode *p_editor) { hbc_menu->add_child(transform_menu); p = transform_menu->get_popup(); - p->add_check_shortcut(ED_SHORTCUT("spatial_editor/use_snap", TTR("Use Snap")), MENU_TRANSFORM_USE_SNAP); p->add_shortcut(ED_SHORTCUT("spatial_editor/configure_snap", TTR("Configure Snap..")), MENU_TRANSFORM_CONFIGURE_SNAP); p->add_separator(); - p->add_check_shortcut(ED_SHORTCUT("spatial_editor/local_coords", TTR("Local Coords")), MENU_TRANSFORM_LOCAL_COORDS); - //p->set_item_checked(p->get_item_count()-1,true); - p->add_separator(); p->add_shortcut(ED_SHORTCUT("spatial_editor/transform_dialog", TTR("Transform Dialog..")), MENU_TRANSFORM_DIALOG); p->connect("id_pressed", this, "_menu_item_pressed"); diff --git a/editor/plugins/spatial_editor_plugin.h b/editor/plugins/spatial_editor_plugin.h index 8369a5de54..4aa1d9c0c1 100644 --- a/editor/plugins/spatial_editor_plugin.h +++ b/editor/plugins/spatial_editor_plugin.h @@ -106,7 +106,6 @@ private: int index; String name; void _menu_option(int p_option); - Size2 prev_size; Spatial *preview_node; AABB *preview_bounds; @@ -136,10 +135,7 @@ private: bool freelook_active; real_t freelook_speed; - PanelContainer *info; Label *info_label; - - PanelContainer *fps; Label *fps_label; struct _RayResult { @@ -405,6 +401,14 @@ public: }; + enum ToolOptions { + + TOOL_OPT_LOCAL_COORDS, + TOOL_OPT_USE_SNAP, + TOOL_OPT_MAX + + }; + private: EditorNode *editor; EditorSelection *editor_selection; @@ -449,17 +453,6 @@ private: Spatial *preview_node; AABB preview_bounds; - /* - struct Selected { - AABB aabb; - Transform original; // original location when moving - Transform last_xform; // last transform - Spatial *sp; - RID poly_instance; - }; - - Map<uint32_t,Selected> selected; -*/ struct Gizmo { bool visible; @@ -474,9 +467,9 @@ private: MENU_TOOL_ROTATE, MENU_TOOL_SCALE, MENU_TOOL_LIST_SELECT, - MENU_TRANSFORM_USE_SNAP, + MENU_TOOL_LOCAL_COORDS, + MENU_TOOL_USE_SNAP, MENU_TRANSFORM_CONFIGURE_SNAP, - MENU_TRANSFORM_LOCAL_COORDS, MENU_TRANSFORM_DIALOG, MENU_VIEW_USE_1_VIEWPORT, MENU_VIEW_USE_2_VIEWPORTS, @@ -493,6 +486,7 @@ private: }; Button *tool_button[TOOL_MAX]; + Button *tool_option_button[TOOL_OPT_MAX]; MenuButton *transform_menu; MenuButton *view_menu; @@ -524,11 +518,10 @@ private: void _xform_dialog_action(); void _menu_item_pressed(int p_option); + void _menu_item_toggled(bool pressed, int p_option); HBoxContainer *hbc_menu; - // - // void _generate_selection_box(); UndoRedo *undo_redo; @@ -579,13 +572,12 @@ public: bool is_gizmo_visible() const { return gizmo.visible; } ToolMode get_tool_mode() const { return tool_mode; } + bool are_local_coords_enabled() const { return tool_option_button[SpatialEditor::TOOL_OPT_LOCAL_COORDS]->is_pressed(); } bool is_snap_enabled() const { return snap_enabled; } float get_translate_snap() const { return snap_translate->get_text().to_double(); } float get_rotate_snap() const { return snap_rotate->get_text().to_double(); } float get_scale_snap() const { return snap_scale->get_text().to_double(); } - bool are_local_coords_enabled() const { return transform_menu->get_popup()->is_item_checked(transform_menu->get_popup()->get_item_index(SpatialEditor::MENU_TRANSFORM_LOCAL_COORDS)); } - Ref<ArrayMesh> get_move_gizmo(int idx) const { return move_gizmo[idx]; } Ref<ArrayMesh> get_move_plane_gizmo(int idx) const { return move_plane_gizmo[idx]; } Ref<ArrayMesh> get_rotate_gizmo(int idx) const { return rotate_gizmo[idx]; } diff --git a/editor/project_export.cpp b/editor/project_export.cpp index 767dbcc27b..3c31b70564 100644 --- a/editor/project_export.cpp +++ b/editor/project_export.cpp @@ -718,7 +718,9 @@ void ProjectExportDialog::_export_project() { export_project->set_access(FileDialog::ACCESS_FILESYSTEM); export_project->clear_filters(); export_project->set_current_file(default_filename); - String extension = platform->get_binary_extension(); + + String extension = platform->get_binary_extension(current); + if (extension != String()) { export_project->add_filter("*." + extension + " ; " + platform->get_name() + " Export"); } diff --git a/editor/property_editor.cpp b/editor/property_editor.cpp index d22bee40d9..623b0e15ab 100644 --- a/editor/property_editor.cpp +++ b/editor/property_editor.cpp @@ -551,6 +551,7 @@ bool CustomPropertyEditor::edit(Object *p_owner, const String &p_name, Variant:: text_edit->show(); text_edit->set_text(v); + text_edit->deselect(); int button_margin = get_constant("button_margin", "Dialogs"); int margin = get_constant("margin", "Dialogs"); @@ -2952,14 +2953,19 @@ void PropertyEditor::update_tree() { if (!found) { DocData *dd = EditorHelp::get_doc_data(); Map<String, DocData::ClassDoc>::Element *E = dd->class_list.find(classname); - if (E) { + while (E && descr == String()) { for (int i = 0; i < E->get().properties.size(); i++) { if (E->get().properties[i].name == propname.operator String()) { descr = E->get().properties[i].description.strip_edges().word_wrap(80); + break; } } + if (!E->get().inherits.empty()) { + E = dd->class_list.find(E->get().inherits); + } else { + break; + } } - descr_cache[classname][propname] = descr; } diff --git a/editor/scene_tree_dock.cpp b/editor/scene_tree_dock.cpp index 4d86030e7d..4d5d467857 100644 --- a/editor/scene_tree_dock.cpp +++ b/editor/scene_tree_dock.cpp @@ -1373,77 +1373,81 @@ void SceneTreeDock::_create() { } } else if (current_option == TOOL_REPLACE) { - Node *n = scene_tree->get_selected(); - ERR_FAIL_COND(!n); + List<Node *> selection = editor_selection->get_selected_node_list(); + ERR_FAIL_COND(selection.size() <= 0); + for (List<Node *>::Element *E = selection.front(); E; E = E->next()) { + Node *n = E->get(); + ERR_FAIL_COND(!n); - Object *c = create_dialog->instance_selected(); + Object *c = create_dialog->instance_selected(); - ERR_FAIL_COND(!c); - Node *newnode = Object::cast_to<Node>(c); - ERR_FAIL_COND(!newnode); + ERR_FAIL_COND(!c); + Node *newnode = Object::cast_to<Node>(c); + ERR_FAIL_COND(!newnode); - List<PropertyInfo> pinfo; - n->get_property_list(&pinfo); + List<PropertyInfo> pinfo; + n->get_property_list(&pinfo); - for (List<PropertyInfo>::Element *E = pinfo.front(); E; E = E->next()) { - if (!(E->get().usage & PROPERTY_USAGE_STORAGE)) - continue; - if (E->get().name == "__meta__") - continue; - newnode->set(E->get().name, n->get(E->get().name)); - } + for (List<PropertyInfo>::Element *E = pinfo.front(); E; E = E->next()) { + if (!(E->get().usage & PROPERTY_USAGE_STORAGE)) + continue; + if (E->get().name == "__meta__") + continue; + newnode->set(E->get().name, n->get(E->get().name)); + } - editor->push_item(NULL); + editor->push_item(NULL); - //reconnect signals - List<MethodInfo> sl; + //reconnect signals + List<MethodInfo> sl; - n->get_signal_list(&sl); - for (List<MethodInfo>::Element *E = sl.front(); E; E = E->next()) { + n->get_signal_list(&sl); + for (List<MethodInfo>::Element *E = sl.front(); E; E = E->next()) { - List<Object::Connection> cl; - n->get_signal_connection_list(E->get().name, &cl); + List<Object::Connection> cl; + n->get_signal_connection_list(E->get().name, &cl); - for (List<Object::Connection>::Element *F = cl.front(); F; F = F->next()) { + for (List<Object::Connection>::Element *F = cl.front(); F; F = F->next()) { - Object::Connection &c = F->get(); - if (!(c.flags & Object::CONNECT_PERSIST)) - continue; - newnode->connect(c.signal, c.target, c.method, varray(), Object::CONNECT_PERSIST); + Object::Connection &c = F->get(); + if (!(c.flags & Object::CONNECT_PERSIST)) + continue; + newnode->connect(c.signal, c.target, c.method, varray(), Object::CONNECT_PERSIST); + } } - } - String newname = n->get_name(); + String newname = n->get_name(); - List<Node *> to_erase; - for (int i = 0; i < n->get_child_count(); i++) { - if (n->get_child(i)->get_owner() == NULL && n->is_owned_by_parent()) { - to_erase.push_back(n->get_child(i)); + List<Node *> to_erase; + for (int i = 0; i < n->get_child_count(); i++) { + if (n->get_child(i)->get_owner() == NULL && n->is_owned_by_parent()) { + to_erase.push_back(n->get_child(i)); + } } - } - n->replace_by(newnode, true); + n->replace_by(newnode, true); - if (n == edited_scene) { - edited_scene = newnode; - editor->set_edited_scene(newnode); - newnode->set_editable_instances(n->get_editable_instances()); - } + if (n == edited_scene) { + edited_scene = newnode; + editor->set_edited_scene(newnode); + newnode->set_editable_instances(n->get_editable_instances()); + } - //small hack to make collisionshapes and other kind of nodes to work - for (int i = 0; i < newnode->get_child_count(); i++) { - Node *c = newnode->get_child(i); - c->call("set_transform", c->call("get_transform")); - } - editor_data->get_undo_redo().clear_history(); - newnode->set_name(newname); + //small hack to make collisionshapes and other kind of nodes to work + for (int i = 0; i < newnode->get_child_count(); i++) { + Node *c = newnode->get_child(i); + c->call("set_transform", c->call("get_transform")); + } + editor_data->get_undo_redo().clear_history(); + newnode->set_name(newname); - editor->push_item(newnode); + editor->push_item(newnode); - memdelete(n); + memdelete(n); - while (to_erase.front()) { - memdelete(to_erase.front()->get()); - to_erase.pop_front(); + while (to_erase.front()) { + memdelete(to_erase.front()->get()); + to_erase.pop_front(); + } } } } @@ -1737,13 +1741,12 @@ void SceneTreeDock::_tree_rmb(const Vector2 &p_menu_pos) { menu->add_icon_shortcut(get_icon("Add", "EditorIcons"), ED_GET_SHORTCUT("scene_tree/add_child_node"), TOOL_NEW); menu->add_icon_shortcut(get_icon("Instance", "EditorIcons"), ED_GET_SHORTCUT("scene_tree/instance_scene"), TOOL_INSTANCE); menu->add_separator(); - menu->add_icon_shortcut(get_icon("Reload", "EditorIcons"), ED_GET_SHORTCUT("scene_tree/change_node_type"), TOOL_REPLACE); - menu->add_separator(); menu->add_icon_shortcut(get_icon("ScriptCreate", "EditorIcons"), ED_GET_SHORTCUT("scene_tree/attach_script"), TOOL_ATTACH_SCRIPT); menu->add_icon_shortcut(get_icon("ScriptRemove", "EditorIcons"), ED_GET_SHORTCUT("scene_tree/clear_script"), TOOL_CLEAR_SCRIPT); menu->add_separator(); } - + menu->add_icon_shortcut(get_icon("Reload", "EditorIcons"), ED_GET_SHORTCUT("scene_tree/change_node_type"), TOOL_REPLACE); + menu->add_separator(); menu->add_icon_shortcut(get_icon("MoveUp", "EditorIcons"), ED_GET_SHORTCUT("scene_tree/move_up"), TOOL_MOVE_UP); menu->add_icon_shortcut(get_icon("MoveDown", "EditorIcons"), ED_GET_SHORTCUT("scene_tree/move_down"), TOOL_MOVE_DOWN); menu->add_icon_shortcut(get_icon("Duplicate", "EditorIcons"), ED_GET_SHORTCUT("scene_tree/duplicate"), TOOL_DUPLICATE); diff --git a/editor/scene_tree_editor.cpp b/editor/scene_tree_editor.cpp index 25924212fd..827e8d9ee4 100644 --- a/editor/scene_tree_editor.cpp +++ b/editor/scene_tree_editor.cpp @@ -256,9 +256,9 @@ bool SceneTreeEditor::_add_nodes(Node *p_node, TreeItem *p_parent) { bool v = p_node->call("is_visible"); if (v) - item->add_button(0, get_icon("Visible", "EditorIcons"), BUTTON_VISIBILITY, false, TTR("Toggle Visibility")); + item->add_button(0, get_icon("GuiVisibilityVisible", "EditorIcons"), BUTTON_VISIBILITY, false, TTR("Toggle Visibility")); else - item->add_button(0, get_icon("Hidden", "EditorIcons"), BUTTON_VISIBILITY, false, TTR("Toggle Visibility")); + item->add_button(0, get_icon("GuiVisibilityHidden", "EditorIcons"), BUTTON_VISIBILITY, false, TTR("Toggle Visibility")); if (!p_node->is_connected("visibility_changed", this, "_node_visibility_changed")) p_node->connect("visibility_changed", this, "_node_visibility_changed", varray(p_node)); @@ -272,9 +272,9 @@ bool SceneTreeEditor::_add_nodes(Node *p_node, TreeItem *p_parent) { bool v = p_node->call("is_visible"); if (v) - item->add_button(0, get_icon("Visible", "EditorIcons"), BUTTON_VISIBILITY, false, TTR("Toggle Visibility")); + item->add_button(0, get_icon("GuiVisibilityVisible", "EditorIcons"), BUTTON_VISIBILITY, false, TTR("Toggle Visibility")); else - item->add_button(0, get_icon("Hidden", "EditorIcons"), BUTTON_VISIBILITY, false, TTR("Toggle Visibility")); + item->add_button(0, get_icon("GuiVisibilityHidden", "EditorIcons"), BUTTON_VISIBILITY, false, TTR("Toggle Visibility")); if (!p_node->is_connected("visibility_changed", this, "_node_visibility_changed")) p_node->connect("visibility_changed", this, "_node_visibility_changed", varray(p_node)); @@ -337,9 +337,9 @@ void SceneTreeEditor::_node_visibility_changed(Node *p_node) { } if (visible) - item->set_button(0, idx, get_icon("Visible", "EditorIcons")); + item->set_button(0, idx, get_icon("GuiVisibilityVisible", "EditorIcons")); else - item->set_button(0, idx, get_icon("Hidden", "EditorIcons")); + item->set_button(0, idx, get_icon("GuiVisibilityHidden", "EditorIcons")); _update_visibility_color(p_node, item); } @@ -774,9 +774,11 @@ Variant SceneTreeEditor::get_drag_data_fw(const Point2 &p_point, Control *p_from Node *n = get_node(np); if (n) { - - selected.push_back(n); - icons.push_back(next->get_icon(0)); + // Only allow selection if not part of an instanced scene. + if (!n->get_owner() || n->get_owner() == get_scene_node() || n->get_owner()->get_filename() == String()) { + selected.push_back(n); + icons.push_back(next->get_icon(0)); + } } next = tree->get_next_selected(next); } diff --git a/editor/script_create_dialog.cpp b/editor/script_create_dialog.cpp index 3cab14b0c4..97f442b0ec 100644 --- a/editor/script_create_dialog.cpp +++ b/editor/script_create_dialog.cpp @@ -331,6 +331,12 @@ void ScriptCreateDialog::_file_selected(const String &p_file) { } else { file_path->set_text(p); _path_changed(p); + + String filename = p.get_file().get_basename(); + int select_start = p.find_last(filename); + file_path->select(select_start, select_start + filename.length()); + file_path->set_cursor_position(select_start + filename.length()); + file_path->grab_focus(); } } @@ -425,6 +431,10 @@ void ScriptCreateDialog::_path_changed(const String &p_path) { _update_dialog(); } +void ScriptCreateDialog::_path_entered(const String &p_path) { + ok_pressed(); +} + void ScriptCreateDialog::_msg_script_valid(bool valid, const String &p_msg) { error_label->set_text(TTR(p_msg)); @@ -459,7 +469,7 @@ void ScriptCreateDialog::_update_dialog() { script_ok = false; } } - if (has_named_classes && (!is_class_name_valid)) { + if (has_named_classes && (is_new_script_created && !is_class_name_valid)) { _msg_script_valid(false, TTR("Invalid class name")); script_ok = false; } @@ -550,6 +560,7 @@ void ScriptCreateDialog::_bind_methods() { ClassDB::bind_method("_browse_path", &ScriptCreateDialog::_browse_path); ClassDB::bind_method("_file_selected", &ScriptCreateDialog::_file_selected); ClassDB::bind_method("_path_changed", &ScriptCreateDialog::_path_changed); + ClassDB::bind_method("_path_entered", &ScriptCreateDialog::_path_entered); ClassDB::bind_method("_template_changed", &ScriptCreateDialog::_template_changed); ADD_SIGNAL(MethodInfo("script_created", PropertyInfo(Variant::OBJECT, "script", PROPERTY_HINT_RESOURCE_TYPE, "Script"))); } @@ -715,6 +726,7 @@ ScriptCreateDialog::ScriptCreateDialog() { hb = memnew(HBoxContainer); file_path = memnew(LineEdit); file_path->connect("text_changed", this, "_path_changed"); + file_path->connect("text_entered", this, "_path_entered"); file_path->set_h_size_flags(SIZE_EXPAND_FILL); hb->add_child(file_path); path_button = memnew(Button); diff --git a/editor/script_create_dialog.h b/editor/script_create_dialog.h index c7bbc82d47..1cff9871d8 100644 --- a/editor/script_create_dialog.h +++ b/editor/script_create_dialog.h @@ -73,6 +73,7 @@ class ScriptCreateDialog : public ConfirmationDialog { Vector<String> template_list; void _path_changed(const String &p_path = String()); + void _path_entered(const String &p_path = String()); void _lang_changed(int l = 0); void _built_in_pressed(); bool _validate(const String &p_string); diff --git a/editor/spatial_editor_gizmos.cpp b/editor/spatial_editor_gizmos.cpp index 8fddd2170f..f0e8d438fa 100644 --- a/editor/spatial_editor_gizmos.cpp +++ b/editor/spatial_editor_gizmos.cpp @@ -2817,7 +2817,7 @@ void BakedIndirectLightGizmo::redraw() { Color gizmo_color = EDITOR_GET("editors/3d_gizmos/gizmo_colors/baked_indirect_light"); Ref<Material> material = create_material("baked_indirect_light_material", gizmo_color); - Ref<Material> icon = create_icon_material("baked_indirect_light_icon", SpatialEditor::get_singleton()->get_icon("GizmoGIProbe", "EditorIcons")); + Ref<Material> icon = create_icon_material("baked_indirect_light_icon", SpatialEditor::get_singleton()->get_icon("GizmoBakedLightmap", "EditorIcons")); Color gizmo_color_internal = gizmo_color; gizmo_color_internal.a = 0.1; Ref<Material> material_internal = create_material("baked_indirect_light_internal_material", gizmo_color_internal); diff --git a/main/SCsub b/main/SCsub index 2cc617fc2c..5748bc38d2 100644 --- a/main/SCsub +++ b/main/SCsub @@ -24,6 +24,27 @@ def make_splash(target, source, env): g.write("#endif") +def make_splash_editor(target, source, env): + + src = source[0].srcnode().abspath + dst = target[0].srcnode().abspath + f = open(src, "rb") + g = open(dst, "w") + + buf = f.read() + + g.write("/* THIS FILE IS GENERATED DO NOT EDIT */\n") + g.write("#ifndef BOOT_SPLASH_EDITOR_H\n") + g.write("#define BOOT_SPLASH_EDITOR_H\n") + g.write('static const Color boot_splash_editor_bg_color = Color::html("#232323");\n') + g.write("static const unsigned char boot_splash_editor_png[] = {\n") + for i in range(len(buf)): + g.write(byte_to_str(buf[i]) + ",\n") + g.write("};\n") + g.write("#endif") + + + def make_app_icon(target, source, env): src = source[0].srcnode().abspath @@ -51,6 +72,9 @@ Export('env') env.Depends("#main/splash.gen.h", "#main/splash.png") env.Command("#main/splash.gen.h", "#main/splash.png", make_splash) +env.Depends("#main/splash_editor.gen.h", "#main/splash_editor.png") +env.Command("#main/splash_editor.gen.h", "#main/splash_editor.png", make_splash_editor) + env.Depends("#main/app_icon.gen.h", "#main/app_icon.png") env.Command("#main/app_icon.gen.h", "#main/app_icon.png", make_app_icon) diff --git a/main/input_default.cpp b/main/input_default.cpp index 8c91a1a5de..f637e77d56 100644 --- a/main/input_default.cpp +++ b/main/input_default.cpp @@ -635,7 +635,7 @@ static const char *s_ControllerMappings[] = { "d81d0b00000000000000504944564944,BUFFALO BSGP1601 Series ,x:b4,a:b5,b:b3,y:b2,back:b12,start:b13,dpleft:h0.8,dpdown:h0.4,dpright:h0.2,dpup:h0.1,leftshoulder:b8,lefttrigger:b6,rightshoulder:b9,righttrigger:b7,leftstick:b10,rightstick:b11,leftx:a0,lefty:a1,rightx:a2,righty:a3,", "d81d0f00000000000000504944564944,iBUFFALO BSGP1204 Series,x:b3,a:b2,b:b1,y:b0,back:b8,start:b9,dpleft:h0.8,dpdown:h0.4,dpright:h0.2,dpup:h0.1,leftshoulder:b6,lefttrigger:b4,rightshoulder:b7,righttrigger:b5,leftstick:b10,rightstick:b11,leftx:a0,lefty:a1,rightx:a2,righty:a3,", "d81d1000000000000000504944564944,iBUFFALO BSGP1204P Series,x:b3,a:b2,b:b1,y:b0,back:b8,start:b9,dpleft:h0.8,dpdown:h0.4,dpright:h0.2,dpup:h0.1,leftshoulder:b6,lefttrigger:b4,rightshoulder:b7,righttrigger:b5,leftstick:b10,rightstick:b11,leftx:a0,lefty:a1,rightx:a2,righty:a3,", - "ff113133000000000000504944564944,Gembird JPD-DualForce,a:b2,b:b3,x:b0,y:b1,start:b9,back:b8,leftshoulder:b4,rightshoulder:b5,dpup:h0.1,dpleft:h0.8,dpdown:h0.4,dpright:h0.2,leftx:a0,lefty:a1,rightx:a2,righty:a4,lefttrigger:b6,righttrigger:b7,leftstick:b10,rightstick:b11,", + "ff113133000000000000504944564944,SVEN X-PAD,a:b2,b:b3,y:b1,x:b0,start:b5,back:b4,leftshoulder:b6,rightshoulder:b7,dpup:h0.1,dpleft:h0.8,dpdown:h0.4,dpright:h0.2,leftx:a0,lefty:a1,rightx:a2,righty:a4,lefttrigger:b8,righttrigger:b9,", "ffff0000000000000000504944564944,GameStop Gamepad,a:b0,b:b1,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b2,y:b3,", "__XINPUT_DEVICE__,XInput Gamepad,a:b12,b:b13,x:b14,y:b15,start:b4,back:b5,leftstick:b6,rightstick:b7,leftshoulder:b8,rightshoulder:b9,dpup:b0,dpdown:b1,dpleft:b2,dpright:b3,leftx:a0,lefty:a1,rightx:a2,righty:a3,lefttrigger:a4,righttrigger:a5,", #endif @@ -684,7 +684,7 @@ static const char *s_ControllerMappings[] = { "0300000000f00000f100000000010000,RetroUSB.com Super RetroPort,a:b1,b:b5,x:b0,y:b4,back:b2,start:b3,leftshoulder:b6,rightshoulder:b7,leftx:a0,lefty:a1,", "030000000d0f00000d00000000010000,hori,a:b0,b:b6,y:b2,x:b1,dpup:h0.1,dpleft:h0.8,dpdown:h0.4,dpright:h0.2,start:b9,guide:b10,back:b8,leftshoulder:b3,rightshoulder:b7,leftx:b4,lefty:b5,", "030000000d0f00001000000011010000,HORI CO. LTD. FIGHTING STICK 3,x:b0,a:b1,b:b2,y:b3,back:b8,guide:b12,start:b9,dpleft:h0.8,dpdown:h0.4,dpright:h0.2,dpup:h0.1,leftshoulder:b4,lefttrigger:b6,rightshoulder:b5,righttrigger:b7", - "030000000d0f00002200000011010000,HORI CO.,LTD. REAL ARCADE Pro.V3,x:b0,a:b1,b:b2,y:b3,back:b8,guide:b12,start:b9,leftshoulder:b4,lefttrigger:b6,rightshoulder:b5,righttrigger:b7,dpleft:h0.8,dpdown:h0.4,dpright:h0.2,dpup:h0.1,", + "030000000d0f00002200000011010000,HORI CO. LTD. REAL ARCADE Pro.V3,x:b0,a:b1,b:b2,y:b3,back:b8,guide:b12,start:b9,leftshoulder:b4,lefttrigger:b6,rightshoulder:b5,righttrigger:b7,dpleft:h0.8,dpdown:h0.4,dpright:h0.2,dpup:h0.1,", "030000000d0f00004d00000011010000,HORI Gem Pad 3,x:b0,a:b1,b:b2,y:b3,back:b8,guide:b12,start:b9,dpleft:h0.8,dpdown:h0.4,dpright:h0.2,dpup:h0.1,leftshoulder:b4,lefttrigger:b6,rightshoulder:b5,righttrigger:b7,leftstick:b10,rightstick:b11,leftx:a0,lefty:a1,rightx:a2,righty:a3,", "03000000100800000100000010010000,Twin USB PS2 Adapter,a:b2,b:b1,y:b0,x:b3,start:b9,guide:,back:b8,leftstick:b10,rightstick:b11,leftshoulder:b6,rightshoulder:b7,dpup:h0.1,dpleft:h0.8,dpdown:h0.4,dpright:h0.2,leftx:a0,lefty:a1,rightx:a3,righty:a2,lefttrigger:b4,righttrigger:b5,", "030000001008000001e5000010010000,NEXT Classic USB Game Controller,a:b0,b:b1,back:b8,start:b9,rightx:a2,righty:a3,leftx:a0,lefty:a1,", @@ -698,8 +698,8 @@ static const char *s_ControllerMappings[] = { "03000000451300000830000010010000,NYKO CORE,a:b1,b:b2,y:b3,x:b0,start:b9,guide:b12,back:b8,leftstick:b10,rightstick:b11,leftshoulder:b4,rightshoulder:b5,dpup:h0.1,dpleft:h0.8,dpdown:h0.4,dpright:h0.2,leftx:a0,lefty:a1,rightx:a2,righty:a5,lefttrigger:b6,righttrigger:b7,", "030000004c0500006802000011010000,PS3 Controller,a:b14,b:b13,back:b0,dpdown:b6,dpleft:b7,dpright:b5,dpup:b4,guide:b16,leftshoulder:b10,leftstick:b1,lefttrigger:b8,leftx:a0,lefty:a1,rightshoulder:b11,rightstick:b2,righttrigger:b9,rightx:a2,righty:a3,start:b3,x:b15,y:b12,", "030000004c050000a00b000011010000,Sony DualShock 4 Wireless Adaptor,a:b1,b:b2,y:b3,x:b0,start:b9,guide:b12,back:b13,leftstick:b10,rightstick:b11,leftshoulder:b4,rightshoulder:b5,dpup:h0.1,dpleft:h0.8,dpdown:h0.4,dpright:h0.2,leftx:a0,lefty:a1,rightx:a2,righty:a5,lefttrigger:a3,righttrigger:a4,", - "030000004c050000c405000011010000,Sony DualShock 4,a:b1,b:b2,y:b3,x:b0,start:b9,guide:b12,back:b8,leftstick:b10,rightstick:b11,leftshoulder:b4,rightshoulder:b5,dpup:h0.1,dpleft:h0.8,dpdown:h0.4,dpright:h0.2,leftx:a0,lefty:a1,rightx:a2,righty:a5,lefttrigger:a3,righttrigger:a4,", - "030000004c050000c405000011810000,Sony Computer Entertainment Wireless Controller,leftx:a0,lefty:a1,dpdown:h0.4,rightstick:h0.1,rightshoulder:b5,rightx:a3,start:b9,righty:a4,dpleft:h0.8,lefttrigger:a2,x:b3,dpup:h0.1,back:b8,leftstick:b11,leftshoulder:b4,y:b2,a:b0,dpright:h0.2,righttrigger:a5,b:b1,", + "030000004c050000c405000011010000,Sony DualShock 4,a:b1,b:b2,y:b3,x:b0,start:b9,guide:b12,back:b8,leftstick:b10,rightstick:b11,leftshoulder:b4,rightshoulder:b5,dpup:h0.1,dpleft:h0.8,dpdown:h0.4,dpright:h0.2,leftx:a0,lefty:a1,rightx:a2,righty:a5,lefttrigger:b6,righttrigger:b7,", + "030000004c050000c405000011810000,Sony DualShock 4,a:b0,b:b1,y:b2,x:b3,start:b9,guide:b10,back:b8,leftstick:b11,rightstick:b12,leftshoulder:b4,rightshoulder:b5,dpup:h0.1,dpleft:h0.8,dpdown:h0.4,dpright:h0.2,leftx:a0,lefty:a1,rightx:a3,righty:a4,lefttrigger:a2,righttrigger:a5,", "030000004c050000cc09000011010000,Sony DualShock 4 V2,a:b1,b:b2,y:b3,x:b0,start:b9,guide:b12,back:b13,leftstick:b10,rightstick:b11,leftshoulder:b4,rightshoulder:b5,dpup:h0.1,dpleft:h0.8,dpdown:h0.4,dpright:h0.2,leftx:a0,lefty:a1,rightx:a2,righty:a5,lefttrigger:a3,righttrigger:a4,", "030000004c050000cc09000011810000,Sony DualShock 4 (CUH-ZCT2U) (USB),a:b0,b:b1,y:b2,x:b3,leftshoulder:b4,rightshoulder:b5,back:b8,start:b9,guide:b10,leftstick:b11,rightstick:b12,leftx:a0,lefty:a1,lefttrigger:a2,rightx:a3,righty:a4,righttrigger:a5,dpup:h0.1,dpright:h0.2,dpdown:h0.4,dpleft:h0.8,", "030000004f04000000b3000010010000,Thrustmaster Firestorm Dual Power,a:b0,b:b2,y:b3,x:b1,start:b10,guide:b8,back:b9,leftstick:b11,rightstick:b12,leftshoulder:b4,rightshoulder:b6,dpup:h0.1,dpleft:h0.8,dpdown:h0.4,dpright:h0.2,leftx:a0,lefty:a1,rightx:a2,righty:a3,lefttrigger:b5,righttrigger:b7,", @@ -718,7 +718,7 @@ static const char *s_ControllerMappings[] = { "030000005e0400008e02000020200000,SpeedLink XEOX Pro Analog Gamepad pad,x:b2,a:b0,b:b1,y:b3,back:b6,guide:b8,start:b7,dpleft:h0.8,dpdown:h0.4,dpright:h0.2,dpup:h0.1,leftshoulder:b4,lefttrigger:a2,rightshoulder:b5,righttrigger:a5,leftstick:b9,rightstick:b10,leftx:a0,lefty:a1,rightx:a3,righty:a4,", "030000005e0400008e02000062230000,Microsoft X-Box 360 pad,x:b2,a:b0,b:b1,y:b3,back:b6,guide:b8,start:b7,dpleft:h0.8,dpdown:h0.4,dpright:h0.2,dpup:h0.1,leftshoulder:b4,lefttrigger:a2,rightshoulder:b5,righttrigger:a5,leftstick:b9,rightstick:b10,leftx:a0,lefty:a1,rightx:a3,righty:a4,", "030000005e0400008e02000073050000,Speedlink TORID Wireless Gamepad,x:b2,a:b0,b:b1,y:b3,back:b6,guide:b8,start:b7,dpleft:h0.8,dpdown:h0.4,dpright:h0.2,dpup:h0.1,leftshoulder:b4,lefttrigger:a2,rightshoulder:b5,righttrigger:a5,leftstick:b9,rightstick:b10,leftx:a0,lefty:a1,rightx:a3,righty:a4,", - "030000005e0400009102000007010000,X360 Wireless Controller,a:b0,b:b1,back:b6,dpdown:b14,dpleft:b11,dpright:b12,dpup:b13,guide:b8,leftshoulder:b4,leftstick:b9,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b10,righttrigger:a5,rightx:a3,righty:a4,start:b7,x:b2,y:b3,", + "030000005e0400009102000007010000,X360 Wireless Controller,a:b0,b:b1,y:b3,x:b2,start:b7,guide:b8,back:b6,leftstick:b9,rightstick:b10,leftshoulder:b4,rightshoulder:b5,dpup:b13,dpleft:b11,dpdown:b14,dpright:b12,leftx:a0,lefty:a1,rightx:a3,righty:a4,lefttrigger:a2,righttrigger:a5,", "030000005e040000a102000000010000,X360 Wireless Controller,a:b0,b:b1,back:b6,dpdown:b14,dpleft:b11,dpright:b12,dpup:b13,guide:b8,leftshoulder:b4,leftstick:b9,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b10,righttrigger:a5,rightx:a3,righty:a4,start:b7,x:b2,y:b3,", "030000005e040000d102000001010000,Microsoft X-Box One pad,x:b2,a:b0,b:b1,y:b3,back:b6,guide:b8,start:b7,dpleft:h0.8,dpdown:h0.0,dpdown:h0.4,dpright:h0.0,dpright:h0.2,dpup:h0.0,dpup:h0.1,leftshoulder:h0.0,leftshoulder:b4,lefttrigger:a2,rightshoulder:b5,righttrigger:a5,leftstick:b9,rightstick:b10,leftx:a0,lefty:a1,rightx:a3,righty:a4,", "030000005e040000dd02000003020000,Microsoft X-Box One pad v2,x:b2,a:b0,b:b1,y:b3,back:b6,guide:b8,start:b7,dpleft:h0.8,dpdown:h0.0,dpdown:h0.4,dpright:h0.0,dpright:h0.2,dpup:h0.0,dpup:h0.1,leftshoulder:h0.0,leftshoulder:b4,lefttrigger:a2,rightshoulder:b5,righttrigger:a5,leftstick:b9,rightstick:b10,leftx:a0,lefty:a1,rightx:a3,righty:a4,", @@ -734,7 +734,7 @@ static const char *s_ControllerMappings[] = { "030000006d0400001fc2000005030000,Logitech F710 Gamepad (XInput),a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b8,leftshoulder:b4,leftstick:b9,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b10,righttrigger:a5,rightx:a3,righty:a4,start:b7,x:b2,y:b3,", "030000006e0500000320000010010000,JC-U3613M - DirectInput Mode,x:b0,a:b2,b:b3,y:b1,back:b10,guide:b12,start:b11,dpleft:h0.8,dpdown:h0.4,dpright:h0.2,dpup:h0.1,leftshoulder:b4,lefttrigger:b6,rightshoulder:b5,righttrigger:b7,leftstick:b8,rightstick:b9,leftx:a0,lefty:a1,rightx:a2,righty:a3,", "030000006f0e00000103000000020000,Logic3 Controller,x:b2,a:b0,b:b1,y:b3,back:b6,guide:b8,start:b7,dpleft:h0.8,dpdown:h0.0,dpdown:h0.4,dpright:h0.0,dpright:h0.2,dpup:h0.0,dpup:h0.1,leftshoulder:h0.0,leftshoulder:b4,lefttrigger:a2,rightshoulder:b5,righttrigger:a5,leftstick:b9,rightstick:b10,leftx:a0,lefty:a1,rightx:a3,righty:a4,", - "030000006f0e00001304000000010000,Generic X-Box pad,x:b2,a:b0,b:b1,y:b3,back:b6,guide:b8,start:b7,dpleft:h0.8,dpdown:h0.4,dpright:h0.2,dpup:h0.1,leftshoulder:b4,lefttrigger:a2,rightshoulder:b5,righttrigger:a5,leftstick:b9,rightstick:b10,leftx:a0,lefty:a1,rightx:a3,righty:a4,", + "030000006f0e00001304000000010000,Generic X-Box pad,x:b2,a:b0,b:b1,y:b3,back:b6,guide:b8,start:b7,dpleft:h0.8,dpdown:h0.0,dpdown:h0.4,dpright:h0.0,dpright:h0.2,dpup:h0.0,dpup:h0.1,leftshoulder:h0.0,leftshoulder:b4,lefttrigger:a2,rightshoulder:b5,righttrigger:a5,leftstick:a0,rightstick:a3,leftstick:b9,rightstick:b10,leftx:a0,lefty:a1,rightx:a3,righty:a4,", "030000006f0e00001e01000011010000,Rock Candy Gamepad for PS3,a:b1,b:b2,x:b0,y:b3,back:b8,start:b9,guide:b12,leftshoulder:b4,rightshoulder:b5,leftstick:b10,rightstick:b11,leftx:a0,lefty:a1,rightx:a2,righty:a3,lefttrigger:b6,righttrigger:b7,dpup:h0.1,dpleft:h0.8,dpdown:h0.4,dpright:h0.2,", "030000006f0e00001f01000000010000,Generic X-Box pad,x:b2,a:b0,b:b1,y:b3,back:b6,guide:b8,start:b7,dpleft:h0.8,dpdown:h0.4,dpright:h0.2,dpup:h0.1,leftshoulder:b4,lefttrigger:a2,rightshoulder:b5,righttrigger:a5,leftstick:b9,rightstick:b10,leftx:a0,lefty:a1,rightx:a3,righty:a4,", "030000006f0e00002801000011010000,PDP Rock Candy Wireless Controller for PS3,leftx:a0,lefty:a1,dpdown:h0.4,rightstick:b11,rightshoulder:b5,rightx:a2,start:b9,righty:a3,dpleft:h0.8,lefttrigger:b6,x:b0,dpup:h0.1,back:b8,leftstick:b10,leftshoulder:b4,y:b3,a:b1,dpright:h0.2,righttrigger:b7,b:b2,", @@ -742,13 +742,13 @@ static const char *s_ControllerMappings[] = { "030000006f0e00003901000020060000,Afterglow Wired Controller for Xbox One,x:b2,a:b0,b:b1,y:b3,back:b6,guide:b8,start:b7,dpleft:h0.8,dpdown:h0.4,dpright:h0.2,dpup:h0.1,leftshoulder:b4,lefttrigger:a2,rightshoulder:b5,righttrigger:a5,leftstick:b9,rightstick:b10,leftx:a0,lefty:a1,rightx:a3,righty:a4,", "030000006f0e00004601000001010000,Rock Candy Wired Controller for Xbox One,a:b0,b:b1,x:b2,y:b3,leftshoulder:b4,rightshoulder:b5,back:b6,start:b7,guide:b8,leftstick:b9,rightstick:b10,lefttrigger:a2,righttrigger:a5,leftx:a0,lefty:a1,rightx:a3,righty:a4,", "03000000780000000600000010010000,Microntek USB Joystick,x:b3,a:b2,b:b1,y:b0,back:b8,start:b9,leftshoulder:b6,lefttrigger:b4,rightshoulder:b7,righttrigger:b5,leftx:a0,lefty:a1,", - "03000000790000000600000010010000,DragonRise Inc. Generic USB Joystick,x:b3,a:b2,b:b1,y:b0,back:b8,start:b9,dpleft:h0.8,dpdown:h0.4,dpright:h0.2,dpup:h0.1,leftshoulder:b4,lefttrigger:b6,rightshoulder:b5,righttrigger:b7,leftstick:b10,rightstick:b11,leftx:a0,lefty:a1,rightx:a3,righty:a4,", - "03000000790000001100000010010000,Retrolink Classic Controller,x:b3,a:b2,b:b1,y:b0,back:b8,start:b9,leftshoulder:b4,rightshoulder:b5,leftx:a0,lefty:a1,", + "03000000790000000600000010010000,DragonRise Inc. Generic USB Joystick ,x:b3,a:b2,b:b1,y:b0,back:b8,start:b9,dpleft:h0.8,dpdown:h0.4,dpright:h0.2,dpup:h0.1,leftshoulder:b4,lefttrigger:b6,rightshoulder:b5,righttrigger:b7,leftstick:b10,rightstick:b11,leftx:a0,lefty:a1,rightx:a3,righty:a4,", + "03000000790000001100000010010000,RetroLink Saturn Classic Controller,x:b3,a:b0,b:b1,y:b4,back:b5,guide:b2,start:b8,leftshoulder:b6,rightshoulder:b7,leftx:a0,lefty:a1,", "03000000830500006020000010010000,iBuffalo USB 2-axis 8-button Gamepad,a:b1,b:b0,x:b3,y:b2,back:b6,start:b7,leftshoulder:b4,rightshoulder:b5,leftx:a0,lefty:a1,", "030000008916000000fd000024010000,Razer Onza Tournament,a:b0,b:b1,y:b3,x:b2,start:b7,guide:b8,back:b6,leftstick:b9,rightstick:b10,leftshoulder:b4,rightshoulder:b5,dpup:b13,dpleft:b11,dpdown:b14,dpright:b12,leftx:a0,lefty:a1,rightx:a3,righty:a4,lefttrigger:a2,righttrigger:a5,", "030000008916000001fd000024010000,Razer Onza Classic Edition,x:b2,a:b0,b:b1,y:b3,back:b6,guide:b8,start:b7,dpleft:b11,dpdown:b14,dpright:b12,dpup:b13,leftshoulder:b4,lefttrigger:a2,rightshoulder:b5,righttrigger:a5,leftstick:b9,rightstick:b10,leftx:a0,lefty:a1,rightx:a3,righty:a4,", - "030000008f0e00000300000010010000,GreenAsia Inc. USB Joystick,x:b3,a:b2,b:b1,y:b0,back:b8,start:b9,dpleft:h0.8,dpdown:h0.0,dpdown:h0.4,dpright:h0.0,dpright:h0.2,dpup:h0.0,dpup:h0.1,leftshoulder:h0.0,leftshoulder:b6,lefttrigger:b4,rightshoulder:b7,righttrigger:b5,leftstick:b10,rightstick:b11,leftx:a0,lefty:a1,rightx:a3,righty:a2,", - "030000008f0e00001200000010010000,GreenAsia Inc. USB Joystick,x:b2,a:b0,b:b1,y:b3,back:b8,start:b9,dpleft:h0.8,dpdown:h0.4,dpright:h0.2,dpup:h0.1,leftshoulder:b4,lefttrigger:b5,rightshoulder:b6,righttrigger:b7,leftstick:b10,rightstick:b11,leftx:a0,lefty:a1,rightx:a3,righty:a2,", + "030000008f0e00000300000010010000,GreenAsia Inc. USB Joystick ,x:b3,a:b2,b:b1,y:b0,back:b8,start:b9,dpleft:h0.8,dpdown:h0.0,dpdown:h0.4,dpright:h0.0,dpright:h0.2,dpup:h0.0,dpup:h0.1,leftshoulder:h0.0,leftshoulder:b6,lefttrigger:b4,rightshoulder:b7,righttrigger:b5,leftstick:b10,rightstick:b11,leftx:a0,lefty:a1,rightx:a3,righty:a2,", + "030000008f0e00001200000010010000,GreenAsia Inc. USB Joystick ,x:b2,a:b0,b:b1,y:b3,back:b8,start:b9,dpleft:h0.8,dpdown:h0.4,dpright:h0.2,dpup:h0.1,leftshoulder:b4,lefttrigger:b5,rightshoulder:b6,righttrigger:b7,leftstick:b10,rightstick:b11,leftx:a0,lefty:a1,rightx:a3,righty:a2,", "030000009b2800000300000001010000,raphnet.net 4nes4snes v1.5,x:b1,a:b0,b:b4,y:b5,back:b2,start:b3,leftshoulder:b6,rightshoulder:b7,leftx:a0,lefty:a1,", "03000000a30600000901000000010000,Saitek P880,a:b2,b:b3,y:b1,x:b0,leftstick:b8,rightstick:b9,leftshoulder:b4,rightshoulder:b5,dpup:h0.1,dpleft:h0.8,dpdown:h0.4,dpright:h0.2,leftx:a0,lefty:a1,rightx:a3,righty:a2,lefttrigger:b6,righttrigger:b7,", "03000000a30600000c04000011010000,Saitek P2900 Wireless Pad,a:b1,b:b2,y:b3,x:b0,start:b12,guide:b9,back:b8,leftstick:b10,rightstick:b11,leftshoulder:b6,rightshoulder:b7,dpup:h0.1,dpleft:h0.8,dpdown:h0.4,dpright:h0.2,leftx:a0,lefty:a1,rightx:a3,righty:a2,lefttrigger:b4,righttrigger:b5,", @@ -761,7 +761,7 @@ static const char *s_ControllerMappings[] = { "03000000bd12000015d0000010010000,Tomee SNES USB Controller,x:b3,a:b2,b:b1,y:b0,back:b8,start:b9,leftshoulder:b4,rightshoulder:b5,leftx:a0,lefty:a1,", "03000000c01600008704000011010000,Serial/Keyboard/Mouse/Joystick,a:b12,b:b10,x:b13,y:b11,back:b4,start:b5,leftstick:b14,rightstick:b15,leftshoulder:b9,rightshoulder:b8,dpup:b0,dpdown:b2,dpleft:b3,dpright:b1,leftx:a1,lefty:a0,rightx:a2,righty:a3,lefttrigger:b6,righttrigger:b7,", "03000000c0160000e105000001010000,Xin-Mo Xin-Mo Dual Arcade,y:b0,x:b1,b:b3,a:b4,leftshoulder:b2,rightshoulder:b5,back:b6,start:b7,guide:b9,dpleft:b13,dpdown:b12,dpright:b14,dpup:b11,leftx:a0,lefty:a1,", - "03000000c9110000f055000011010000,HJC Game GAMEPAD,x:b2,a:b0,b:b1,y:b3,back:b4,back:b8,start:b9,dpleft:h0.8,dpdown:h0.0,dpdown:h0.4,dpright:h0.0,dpright:h0.2,dpup:h0.0,dpup:h0.1,leftshoulder:h0.0,leftshoulder:b4,lefttrigger:b6,rightshoulder:b5,righttrigger:b7,leftstick:b10,rightstick:b11,leftx:a0,lefty:a1,rightx:a2,righty:a3,platform:Linux,", + "03000000c9110000f055000011010000,HJC Game GAMEPAD,leftx:a0,lefty:a1,dpdown:h0.4,rightstick:b11,rightshoulder:b5,rightx:a2,start:b9,righty:a3,dpleft:h0.8,lefttrigger:b6,x:b2,dpup:h0.1,back:b8,leftstick:b10,leftshoulder:b4,y:b3,a:b0,dpright:h0.2,righttrigger:b7,b:b1,", "03000000d814000007cd000011010000,Toodles 2008 Chimp PC/PS3,a:b0,b:b1,y:b2,x:b3,start:b9,back:b8,leftshoulder:b4,rightshoulder:b5,leftx:a0,lefty:a1,lefttrigger:b6,righttrigger:b7,", "03000000d81400000862000011010000,HitBox (PS3/PC) Analog Mode,a:b1,b:b2,y:b3,x:b0,start:b12,guide:b9,back:b8,leftshoulder:b4,rightshoulder:b5,lefttrigger:b6,righttrigger:b7,leftx:a0,lefty:a1,", "03000000de280000ff11000001000000,Valve Streaming Gamepad,a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b8,leftshoulder:b4,leftstick:b9,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b10,righttrigger:a5,rightx:a3,righty:a4,start:b7,x:b2,y:b3,", @@ -778,7 +778,7 @@ static const char *s_ControllerMappings[] = { "05000000380700006652000025010000,Mad Catz C.T.R.L.R ,x:b0,a:b1,b:b2,y:b3,back:b8,guide:b12,start:b9,dpleft:h0.8,dpdown:h0.4,dpright:h0.2,dpup:h0.1,leftshoulder:b4,lefttrigger:b6,rightshoulder:b5,righttrigger:b7,leftstick:b10,rightstick:b11,leftx:a0,lefty:a1,rightx:a2,righty:a3,", "0500000047532047616d657061640000,GameStop Gamepad,a:b0,b:b1,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b2,y:b3,", "050000004c0500006802000000010000,PS3 Controller (Bluetooth),a:b14,b:b13,y:b12,x:b15,start:b3,guide:b16,back:b0,leftstick:b1,rightstick:b2,leftshoulder:b10,rightshoulder:b11,dpup:b4,dpleft:b7,dpdown:b6,dpright:b5,leftx:a0,lefty:a1,rightx:a2,righty:a3,lefttrigger:b8,righttrigger:b9,", - "050000004c050000c405000000010000,PS4 Controller (Bluetooth),a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:a3,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:a4,rightx:a2,righty:a5,start:b9,x:b0,y:b3,", + "050000004c050000c405000000010000,Sony DualShock 4 BT,a:b1,b:b2,back:b13,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:a3,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:a4,rightx:a2,righty:a5,start:b9,x:b0,y:b3,", "050000004c050000cc09000000010000,Sony DualShock 4 V2 BT,a:b1,b:b2,y:b3,x:b0,start:b9,guide:b12,back:b13,leftstick:b10,rightstick:b11,leftshoulder:b4,rightshoulder:b5,dpup:h0.1,dpleft:h0.8,dpdown:h0.4,dpright:h0.2,leftx:a0,lefty:a1,rightx:a2,righty:a5,lefttrigger:a3,righttrigger:a4,", "050000004c050000cc09000000810000,Sony DualShock 4 (CUH-ZCT2U) (Bluetooth),a:b0,b:b1,y:b2,x:b3,leftshoulder:b4,rightshoulder:b5,back:b8,start:b9,guide:b10,leftstick:b11,rightstick:b12,leftx:a0,lefty:a1,lefttrigger:a2,rightx:a3,righty:a4,righttrigger:a5,dpup:h0.1,dpright:h0.2,dpdown:h0.4,dpleft:h0.8,", "05000000504c415953544154494f4e00,PS3 Controller (Bluetooth),a:b14,b:b13,y:b12,x:b15,start:b3,guide:b16,back:b0,leftstick:b1,rightstick:b2,leftshoulder:b10,rightshoulder:b11,dpup:b4,dpleft:b7,dpdown:b6,dpright:b5,leftx:a0,lefty:a1,rightx:a2,righty:a3,lefttrigger:b8,righttrigger:b9,", diff --git a/main/main.cpp b/main/main.cpp index 1328807121..ab520c5e7f 100644 --- a/main/main.cpp +++ b/main/main.cpp @@ -42,6 +42,7 @@ #include "script_debugger_remote.h" #include "servers/register_server_types.h" #include "splash.gen.h" +#include "splash_editor.gen.h" #include "input_map.h" #include "io/resource_loader.h" @@ -1051,7 +1052,12 @@ Error Main::setup2(Thread::ID p_main_tid_override) { #ifndef NO_DEFAULT_BOOT_LOGO MAIN_PRINT("Main: Create bootsplash"); +#if defined(TOOLS_ENABLED) && !defined(NO_EDITOR_SPLASH) + + Ref<Image> splash = editor ? memnew(Image(boot_splash_editor_png)) : memnew(Image(boot_splash_png)); +#else Ref<Image> splash = memnew(Image(boot_splash_png)); +#endif MAIN_PRINT("Main: ClearColor"); VisualServer::get_singleton()->set_default_clear_color(boot_splash_bg_color); @@ -1136,6 +1142,8 @@ Error Main::setup2(Thread::ID p_main_tid_override) { translation_server->load_translations(); ResourceLoader::load_translation_remaps(); //load remaps for resources + ResourceLoader::load_path_remaps(); + audio_server->load_default_bus_layout(); if (use_debug_profiler && script_debugger) { @@ -1816,6 +1824,9 @@ void Main::cleanup() { OS::get_singleton()->_execpath = ""; OS::get_singleton()->_local_clipboard = ""; + ResourceLoader::clear_translation_remaps(); + ResourceLoader::clear_path_remaps(); + ScriptServer::finish_languages(); #ifdef TOOLS_ENABLED diff --git a/main/splash_sponsors.png b/main/splash_editor.png Binary files differindex d8677f1749..d8677f1749 100644 --- a/main/splash_sponsors.png +++ b/main/splash_editor.png diff --git a/modules/enet/networked_multiplayer_enet.cpp b/modules/enet/networked_multiplayer_enet.cpp index ce485956b4..396bebf0ea 100644 --- a/modules/enet/networked_multiplayer_enet.cpp +++ b/modules/enet/networked_multiplayer_enet.cpp @@ -386,7 +386,7 @@ int NetworkedMultiplayerENet::get_available_packet_count() const { return incoming_packets.size(); } -Error NetworkedMultiplayerENet::get_packet(const uint8_t **r_buffer, int &r_buffer_size) const { +Error NetworkedMultiplayerENet::get_packet(const uint8_t **r_buffer, int &r_buffer_size) { ERR_FAIL_COND_V(incoming_packets.size() == 0, ERR_UNAVAILABLE); @@ -480,7 +480,7 @@ int NetworkedMultiplayerENet::get_max_packet_size() const { return 1 << 24; //anything is good } -void NetworkedMultiplayerENet::_pop_current_packet() const { +void NetworkedMultiplayerENet::_pop_current_packet() { if (current_packet.packet) { enet_packet_destroy(current_packet.packet); diff --git a/modules/enet/networked_multiplayer_enet.h b/modules/enet/networked_multiplayer_enet.h index 81d517147d..d7bc5c7849 100644 --- a/modules/enet/networked_multiplayer_enet.h +++ b/modules/enet/networked_multiplayer_enet.h @@ -86,12 +86,12 @@ private: CompressionMode compression_mode; - mutable List<Packet> incoming_packets; + List<Packet> incoming_packets; - mutable Packet current_packet; + Packet current_packet; uint32_t _gen_unique_id() const; - void _pop_current_packet() const; + void _pop_current_packet(); Vector<uint8_t> src_compressor_mem; Vector<uint8_t> dst_compressor_mem; @@ -123,7 +123,7 @@ public: virtual bool is_server() const; virtual int get_available_packet_count() const; - virtual Error get_packet(const uint8_t **r_buffer, int &r_buffer_size) const; ///< buffer is GONE after next get_packet + virtual Error get_packet(const uint8_t **r_buffer, int &r_buffer_size); ///< buffer is GONE after next get_packet virtual Error put_packet(const uint8_t *p_buffer, int p_buffer_size); virtual int get_max_packet_size() const; diff --git a/modules/gdnative/gdnative/gdnative.cpp b/modules/gdnative/gdnative/gdnative.cpp index 92a88e354b..8ff67b10b1 100644 --- a/modules/gdnative/gdnative/gdnative.cpp +++ b/modules/gdnative/gdnative/gdnative.cpp @@ -52,10 +52,6 @@ godot_object GDAPI *godot_global_get_singleton(char *p_name) { return (godot_object *)Engine::get_singleton()->get_singleton_object(String(p_name)); } // result shouldn't be freed -void GDAPI *godot_get_stack_bottom() { - return OS::get_singleton()->get_stack_bottom(); -} - // MethodBind API godot_method_bind GDAPI *godot_method_bind_get_method(const char *p_classname, const char *p_methodname) { diff --git a/modules/gdnative/gdnative_api.json b/modules/gdnative/gdnative_api.json index 31f3b0b77b..06c6e9f410 100644 --- a/modules/gdnative/gdnative_api.json +++ b/modules/gdnative/gdnative_api.json @@ -5569,6 +5569,12 @@ ] }, { + "name": "godot_get_global_constants", + "return_type": "godot_dictionary", + "arguments": [ + ] + }, + { "name": "godot_register_native_call_type", "return_type": "void", "arguments": [ diff --git a/modules/gdnative/include/gdnative/gdnative.h b/modules/gdnative/include/gdnative/gdnative.h index f7f5606428..9d7829a51f 100644 --- a/modules/gdnative/include/gdnative/gdnative.h +++ b/modules/gdnative/include/gdnative/gdnative.h @@ -212,10 +212,6 @@ void GDAPI godot_object_destroy(godot_object *p_o); godot_object GDAPI *godot_global_get_singleton(char *p_name); // result shouldn't be freed -////// OS API - -void GDAPI *godot_get_stack_bottom(); // returns stack bottom of the main thread - ////// MethodBind API typedef struct { diff --git a/modules/gdscript/gdscript_parser.cpp b/modules/gdscript/gdscript_parser.cpp index 36ae61e388..8c110143b8 100644 --- a/modules/gdscript/gdscript_parser.cpp +++ b/modules/gdscript/gdscript_parser.cpp @@ -597,12 +597,36 @@ GDScriptParser::Node *GDScriptParser::_parse_expression(Node *p_parent, bool p_s OperatorNode *op = alloc_node<OperatorNode>(); op->op = OperatorNode::OP_CALL; + //Do a quick Array and Dictionary Check. Replace if either require no arguments. + bool replaced = false; + if (tokenizer->get_token() == GDScriptTokenizer::TK_BUILT_IN_TYPE) { + Variant::Type ct = tokenizer->get_token_type(); + if (p_parsing_constant == false) { + if (ct == Variant::ARRAY) { + if (tokenizer->get_token(2) == GDScriptTokenizer::TK_PARENTHESIS_CLOSE) { + ArrayNode *arr = alloc_node<ArrayNode>(); + expr = arr; + replaced = true; + tokenizer->advance(3); + } + } + if (ct == Variant::DICTIONARY) { + if (tokenizer->get_token(2) == GDScriptTokenizer::TK_PARENTHESIS_CLOSE) { + DictionaryNode *dict = alloc_node<DictionaryNode>(); + expr = dict; + replaced = true; + tokenizer->advance(3); + } + } + } - TypeNode *tn = alloc_node<TypeNode>(); - tn->vtype = tokenizer->get_token_type(); - op->arguments.push_back(tn); - tokenizer->advance(2); + if (!replaced) { + TypeNode *tn = alloc_node<TypeNode>(); + tn->vtype = tokenizer->get_token_type(); + op->arguments.push_back(tn); + tokenizer->advance(2); + } } else if (tokenizer->get_token() == GDScriptTokenizer::TK_BUILT_IN_FUNC) { BuiltInFunctionNode *bn = alloc_node<BuiltInFunctionNode>(); @@ -628,11 +652,11 @@ GDScriptParser::Node *GDScriptParser::_parse_expression(Node *p_parent, bool p_s _make_completable_call(0); completion_node = op; } - if (!_parse_arguments(op, op->arguments, p_static, true)) - return NULL; - - expr = op; - + if (!replaced) { + if (!_parse_arguments(op, op->arguments, p_static, true)) + return NULL; + expr = op; + } } else if (tokenizer->is_token_literal(0, true)) { // We check with is_token_literal, as this allows us to use match/sync/etc. as a name //identifier (reference) diff --git a/modules/gdscript/register_types.cpp b/modules/gdscript/register_types.cpp index 1e007ddb0f..e707032ed8 100644 --- a/modules/gdscript/register_types.cpp +++ b/modules/gdscript/register_types.cpp @@ -30,6 +30,7 @@ #include "register_types.h" #include "gdscript.h" +#include "gdscript_tokenizer.h" #include "io/file_access_encrypted.h" #include "io/resource_loader.h" #include "os/file_access.h" @@ -38,6 +39,45 @@ GDScriptLanguage *script_language_gd = NULL; ResourceFormatLoaderGDScript *resource_loader_gd = NULL; ResourceFormatSaverGDScript *resource_saver_gd = NULL; +#ifdef TOOLS_ENABLED + +#include "editor/editor_export.h" +#include "editor/editor_node.h" +#include "editor/editor_settings.h" + +class EditorExportGDScript : public EditorExportPlugin { + + GDCLASS(EditorExportGDScript, EditorExportPlugin); + +public: + virtual void _export_file(const String &p_path, const String &p_type, const Set<String> &p_features) { + + if (!p_path.ends_with(".gd")) + return; + + Vector<uint8_t> file = FileAccess::get_file_as_array(p_path); + if (file.empty()) + return; + String txt; + txt.parse_utf8((const char *)file.ptr(), file.size()); + file = GDScriptTokenizerBuffer::parse_code_string(txt); + + if (file.empty()) + return; + + add_file(p_path.get_basename() + ".gdc", file, true); + } +}; + +static void _editor_init() { + + Ref<EditorExportGDScript> gd_export; + gd_export.instance(); + EditorExport::get_singleton()->add_export_plugin(gd_export); +} + +#endif + void register_gdscript_types() { ClassDB::register_class<GDScript>(); @@ -49,6 +89,10 @@ void register_gdscript_types() { ResourceLoader::add_resource_format_loader(resource_loader_gd); resource_saver_gd = memnew(ResourceFormatSaverGDScript); ResourceSaver::add_resource_format_saver(resource_saver_gd); + +#ifdef TOOLS_ENABLED + EditorNode::add_init_callback(_editor_init); +#endif } void unregister_gdscript_types() { diff --git a/modules/gridmap/grid_map.cpp b/modules/gridmap/grid_map.cpp index b3a1947647..bebf8bcf8f 100644 --- a/modules/gridmap/grid_map.cpp +++ b/modules/gridmap/grid_map.cpp @@ -469,7 +469,7 @@ bool GridMap::_octant_update(const OctantKey &p_key) { nm.xform = xform; if (navigation) { - nm.id = navigation->navmesh_create(navmesh, xform, this); + nm.id = navigation->navmesh_add(navmesh, xform, this); } else { nm.id = -1; } @@ -556,7 +556,7 @@ void GridMap::_octant_enter_world(const OctantKey &p_key) { if (cell_map.has(F->key()) && F->get().id < 0) { Ref<NavigationMesh> nm = theme->get_item_navmesh(cell_map[F->key()].item); if (nm.is_valid()) { - F->get().id = navigation->navmesh_create(nm, F->get().xform, this); + F->get().id = navigation->navmesh_add(nm, F->get().xform, this); } } } diff --git a/modules/gridmap/grid_map.h b/modules/gridmap/grid_map.h index 5bfdf1dac3..ab66bf123e 100644 --- a/modules/gridmap/grid_map.h +++ b/modules/gridmap/grid_map.h @@ -186,6 +186,11 @@ class GridMap : public Spatial { Vector3 _get_offset() const; + struct BakedMesh { + Ref<Mesh> mesh; + Transform transform; + }; + protected: bool _set(const StringName &p_name, const Variant &p_value); bool _get(const StringName &p_name, Variant &r_ret) const; diff --git a/modules/thekla_unwrap/SCsub b/modules/thekla_unwrap/SCsub index b489fcc9e7..c57bf326ea 100644 --- a/modules/thekla_unwrap/SCsub +++ b/modules/thekla_unwrap/SCsub @@ -67,7 +67,7 @@ if env['builtin_thekla_atlas']: if env.msvc: env_thekla_unwrap.Append(CCFLAGS=["-DNV_OS_WIN32", "-DNV_CC_MSVC", "-DPOSH_COMPILER_MSVC" ]) else: - env_thekla_unwrap.Append(CCFLAGS=["-DNV_OS_MINGW", "-DNV_CC_GNUC", "-DPOSH_COMPILER_GCC"]) + env_thekla_unwrap.Append(CCFLAGS=["-DNV_OS_MINGW", "-DNV_CC_GNUC", "-DPOSH_COMPILER_GCC", "-U__STRICT_ANSI__"]) env.Append(LIBS=["dbghelp"]) # Godot source files diff --git a/platform/android/detect.py b/platform/android/detect.py index bc67f6e6dc..892b1b6a85 100644 --- a/platform/android/detect.py +++ b/platform/android/detect.py @@ -277,7 +277,7 @@ def get_ndk_version(path): try: with open(prop_file_path) as prop_file: for line in prop_file: - key_value = map(lambda x: string.strip(x), line.split("=")) + key_value = list(map(lambda x: x.strip(), line.split("="))) if key_value[0] == "Pkg.Revision": return key_value[1] except: diff --git a/platform/android/export/export.cpp b/platform/android/export/export.cpp index 255413bf2c..d4c079cfc6 100644 --- a/platform/android/export/export.cpp +++ b/platform/android/export/export.cpp @@ -352,10 +352,11 @@ class EditorExportAndroid : public EditorExportPlatform { ea->device_lock->unlock(); } + uint64_t sleep = OS::get_singleton()->get_power_state() == OS::POWERSTATE_ON_BATTERY ? 1000 : 100; uint64_t wait = 3000000; uint64_t time = OS::get_singleton()->get_ticks_usec(); while (OS::get_singleton()->get_ticks_usec() - time < wait) { - OS::get_singleton()->delay_usec(1000); + OS::get_singleton()->delay_usec(1000 * sleep); if (ea->quit_request) break; } @@ -1305,7 +1306,7 @@ public: return valid; } - virtual String get_binary_extension() const { + virtual String get_binary_extension(const Ref<EditorExportPreset> &p_preset) const { return "apk"; } diff --git a/platform/iphone/export/export.cpp b/platform/iphone/export/export.cpp index 1833bdf2b3..9ea8d58db0 100644 --- a/platform/iphone/export/export.cpp +++ b/platform/iphone/export/export.cpp @@ -108,7 +108,7 @@ public: virtual String get_os_name() const { return "iOS"; } virtual Ref<Texture> get_logo() const { return logo; } - virtual String get_binary_extension() const { return "ipa"; } + virtual String get_binary_extension(const Ref<EditorExportPreset> &p_preset) const { return "ipa"; } virtual Error export_project(const Ref<EditorExportPreset> &p_preset, bool p_debug, const String &p_path, int p_flags = 0); virtual bool can_export(const Ref<EditorExportPreset> &p_preset, String &r_error, bool &r_missing_templates) const; diff --git a/platform/javascript/export/export.cpp b/platform/javascript/export/export.cpp index 775e9c7ee0..ec5010f330 100644 --- a/platform/javascript/export/export.cpp +++ b/platform/javascript/export/export.cpp @@ -57,7 +57,7 @@ public: virtual Ref<Texture> get_logo() const; virtual bool can_export(const Ref<EditorExportPreset> &p_preset, String &r_error, bool &r_missing_templates) const; - virtual String get_binary_extension() const; + virtual String get_binary_extension(const Ref<EditorExportPreset> &p_preset) const; virtual Error export_project(const Ref<EditorExportPreset> &p_preset, bool p_debug, const String &p_path, int p_flags = 0); virtual bool poll_devices(); @@ -149,7 +149,7 @@ bool EditorExportPlatformJavaScript::can_export(const Ref<EditorExportPreset> &p return !r_missing_templates; } -String EditorExportPlatformJavaScript::get_binary_extension() const { +String EditorExportPlatformJavaScript::get_binary_extension(const Ref<EditorExportPreset> &p_preset) const { return "html"; } diff --git a/platform/javascript/http_client_javascript.cpp b/platform/javascript/http_client_javascript.cpp index 0b105dcb40..b170ba6f35 100644 --- a/platform/javascript/http_client_javascript.cpp +++ b/platform/javascript/http_client_javascript.cpp @@ -37,16 +37,31 @@ Error HTTPClient::connect_to_host(const String &p_host, int p_port, bool p_ssl, WARN_PRINT("Disabling HTTPClient's host verification is not supported for the HTML5 platform, host will be verified"); } + port = p_port; + use_tls = p_ssl; + host = p_host; - if (host.begins_with("http://")) { - host.replace_first("http://", ""); - } else if (host.begins_with("https://")) { - host.replace_first("https://", ""); + + String host_lower = host.to_lower(); + if (host_lower.begins_with("http://")) { + host = host.substr(7, host.length() - 7); + } else if (host_lower.begins_with("https://")) { + use_tls = true; + host = host.substr(8, host.length() - 8); + } + + ERR_FAIL_COND_V(host.length() < HOST_MIN_LEN, ERR_INVALID_PARAMETER); + + if (port < 0) { + if (use_tls) { + port = PORT_HTTPS; + } else { + port = PORT_HTTP; + } } status = host.is_valid_ip_address() ? STATUS_CONNECTING : STATUS_RESOLVING; - port = p_port; - use_tls = p_ssl; + return OK; } @@ -68,17 +83,7 @@ Error HTTPClient::prepare_request(Method p_method, const String &p_url, const Ve ERR_FAIL_COND_V(status != STATUS_CONNECTED, ERR_INVALID_PARAMETER); ERR_FAIL_COND_V(host.empty(), ERR_UNCONFIGURED); ERR_FAIL_COND_V(port < 0, ERR_UNCONFIGURED); - - static const char *_methods[HTTPClient::METHOD_MAX] = { - "GET", - "HEAD", - "POST", - "PUT", - "DELETE", - "OPTIONS", - "TRACE", - "CONNECT" - }; + ERR_FAIL_COND_V(!p_url.begins_with("/"), ERR_INVALID_PARAMETER); String url = (use_tls ? "https://" : "http://") + host + ":" + itos(port) + "/" + p_url; godot_xhr_reset(xhr_id); diff --git a/platform/osx/SCsub b/platform/osx/SCsub index 13ce14f040..029e3d808c 100644 --- a/platform/osx/SCsub +++ b/platform/osx/SCsub @@ -4,9 +4,10 @@ import os Import('env') def make_debug(target, source, env): - if (env["macports_clang"]): + if (env["macports_clang"] != 'no'): mpprefix = os.environ.get("MACPORTS_PREFIX", "/opt/local") - os.system(mpprefix + '/libexec/llvm-5.0/bin/llvm-dsymutil %s -o %s.dSYM' % (target[0], target[0])) + mpclangver = env["macports_clang"] + os.system(mpprefix + '/libexec/llvm-' + mpclangver + '/bin/llvm-dsymutil %s -o %s.dSYM' % (target[0], target[0])) else: os.system('dsymutil %s -o %s.dSYM' % (target[0], target[0])) diff --git a/platform/osx/detect.py b/platform/osx/detect.py index 77a4ee1a48..e8a8319431 100644 --- a/platform/osx/detect.py +++ b/platform/osx/detect.py @@ -72,19 +72,19 @@ def configure(env): else: # 64-bit, default env.Append(CCFLAGS=['-arch', 'x86_64']) env.Append(LINKFLAGS=['-arch', 'x86_64']) - if (env["macports_clang"]): + if (env["macports_clang"] != 'no'): mpprefix = os.environ.get("MACPORTS_PREFIX", "/opt/local") - env["CC"] = mpprefix + "/libexec/llvm-5.0/bin/clang" - env["LD"] = mpprefix + "/libexec/llvm-5.0/bin/clang++" - env["CXX"] = mpprefix + "/libexec/llvm-5.0/bin/clang++" - env['AR'] = mpprefix + "/libexec/llvm-5.0/bin/llvm-ar" - env['RANLIB'] = mpprefix + "/libexec/llvm-5.0/bin/llvm-ranlib" - env['AS'] = mpprefix + "/libexec/llvm-5.0/bin/llvm-as" + mpclangver = env["macports_clang"] + env["CC"] = mpprefix + "/libexec/llvm-" + mpclangver + "/bin/clang" + env["LD"] = mpprefix + "/libexec/llvm-" + mpclangver + "/bin/clang++" + env["CXX"] = mpprefix + "/libexec/llvm-" + mpclangver + "/bin/clang++" + env['AR'] = mpprefix + "/libexec/llvm-" + mpclangver + "/bin/llvm-ar" + env['RANLIB'] = mpprefix + "/libexec/llvm-" + mpclangver + "/bin/llvm-ranlib" + env['AS'] = mpprefix + "/libexec/llvm-" + mpclangver + "/bin/llvm-as" env.Append(CCFLAGS=['-D__MACPORTS__']) #hack to fix libvpx MM256_BROADCASTSI128_SI256 define if (env["openmp"]): env.Append(CPPFLAGS=['-fopenmp']) - env.Append(LINKFLAGS=['-L' + mpprefix + '/lib/libomp/']) - env.Append(LIBS=['gomp']) + env.Append(LINKFLAGS=['-fopenmp']) else: # osxcross build root = os.environ.get("OSXCROSS_ROOT", 0) diff --git a/platform/osx/export/export.cpp b/platform/osx/export/export.cpp index d3b763b42e..8a09aa634e 100644 --- a/platform/osx/export/export.cpp +++ b/platform/osx/export/export.cpp @@ -74,7 +74,7 @@ public: virtual String get_os_name() const { return "OSX"; } virtual Ref<Texture> get_logo() const { return logo; } - virtual String get_binary_extension() const { return use_dmg() ? "dmg" : "zip"; } + virtual String get_binary_extension(const Ref<EditorExportPreset> &p_preset) const { return use_dmg() ? "dmg" : "zip"; } virtual Error export_project(const Ref<EditorExportPreset> &p_preset, bool p_debug, const String &p_path, int p_flags = 0); virtual bool can_export(const Ref<EditorExportPreset> &p_preset, String &r_error, bool &r_missing_templates) const; diff --git a/platform/osx/os_osx.h b/platform/osx/os_osx.h index 33127a8c2a..2381b85658 100644 --- a/platform/osx/os_osx.h +++ b/platform/osx/os_osx.h @@ -204,7 +204,7 @@ public: virtual void request_attention(); virtual String get_joy_guid(int p_device) const; - virtual void set_borderless_window(int p_borderless); + virtual void set_borderless_window(bool p_borderless); virtual bool get_borderless_window(); virtual void set_ime_position(const Point2 &p_pos); virtual void set_ime_intermediate_text_callback(ImeCallback p_callback, void *p_inp); @@ -215,8 +215,8 @@ public: virtual bool _check_internal_feature_support(const String &p_feature); - virtual void set_use_vsync(bool p_enable); - virtual bool is_vsync_enabled() const; + virtual void _set_use_vsync(bool p_enable); + //virtual bool is_vsync_enabled() const; void run(); diff --git a/platform/osx/os_osx.mm b/platform/osx/os_osx.mm index 3d4883e269..aab37cb59c 100644 --- a/platform/osx/os_osx.mm +++ b/platform/osx/os_osx.mm @@ -1818,7 +1818,7 @@ void OS_OSX::request_attention() { [NSApp requestUserAttention:NSCriticalRequest]; } -void OS_OSX::set_borderless_window(int p_borderless) { +void OS_OSX::set_borderless_window(bool p_borderless) { // OrderOut prevents a lose focus bug with the window [window_object orderOut:nil]; @@ -1975,7 +1975,6 @@ void OS_OSX::force_process_input() { process_events(); // get rid of pending events joypad_osx->process_joypads(); - } void OS_OSX::run() { @@ -2064,14 +2063,14 @@ Error OS_OSX::move_to_trash(const String &p_path) { return OK; } -void OS_OSX::set_use_vsync(bool p_enable) { +void OS_OSX::_set_use_vsync(bool p_enable) { CGLContextObj ctx = CGLGetCurrentContext(); if (ctx) { GLint swapInterval = p_enable ? 1 : 0; CGLSetParameter(ctx, kCGLCPSwapInterval, &swapInterval); } } - +/* bool OS_OSX::is_vsync_enabled() const { GLint swapInterval = 0; CGLContextObj ctx = CGLGetCurrentContext(); @@ -2080,7 +2079,7 @@ bool OS_OSX::is_vsync_enabled() const { } return swapInterval ? true : false; } - +*/ OS_OSX *OS_OSX::singleton = NULL; OS_OSX::OS_OSX() { diff --git a/platform/uwp/SCsub b/platform/uwp/SCsub index f0d69fef33..fb0c4a92ae 100644 --- a/platform/uwp/SCsub +++ b/platform/uwp/SCsub @@ -4,9 +4,6 @@ Import('env') files = [ 'thread_uwp.cpp', - '#platform/windows/tcp_server_winsock.cpp', - '#platform/windows/packet_peer_udp_winsock.cpp', - '#platform/windows/stream_peer_winsock.cpp', '#platform/windows/key_mapping_win.cpp', '#platform/windows/windows_terminal_logger.cpp', 'joypad_uwp.cpp', diff --git a/platform/uwp/export/export.cpp b/platform/uwp/export/export.cpp index 7f86b4ae53..45ca097de5 100644 --- a/platform/uwp/export/export.cpp +++ b/platform/uwp/export/export.cpp @@ -1013,7 +1013,7 @@ public: return "UWP"; } - virtual String get_binary_extension() const { + virtual String get_binary_extension(const Ref<EditorExportPreset> &p_preset) const { return "appx"; } diff --git a/platform/uwp/os_uwp.cpp b/platform/uwp/os_uwp.cpp index 659f162724..3018ac0bef 100644 --- a/platform/uwp/os_uwp.cpp +++ b/platform/uwp/os_uwp.cpp @@ -34,13 +34,13 @@ #include "drivers/windows/dir_access_windows.h" #include "drivers/windows/file_access_windows.h" #include "drivers/windows/mutex_windows.h" +#include "drivers/windows/packet_peer_udp_winsock.h" #include "drivers/windows/rw_lock_windows.h" #include "drivers/windows/semaphore_windows.h" +#include "drivers/windows/stream_peer_tcp_winsock.h" +#include "drivers/windows/tcp_server_winsock.h" #include "io/marshalls.h" #include "main/main.h" -#include "platform/windows/packet_peer_udp_winsock.h" -#include "platform/windows/stream_peer_winsock.h" -#include "platform/windows/tcp_server_winsock.h" #include "platform/windows/windows_terminal_logger.h" #include "project_settings.h" #include "servers/audio_server.h" @@ -163,7 +163,7 @@ void OSUWP::initialize_core() { DirAccess::make_default<DirAccessWindows>(DirAccess::ACCESS_FILESYSTEM); TCPServerWinsock::make_default(); - StreamPeerWinsock::make_default(); + StreamPeerTCPWinsock::make_default(); PacketPeerUDPWinsock::make_default(); // We need to know how often the clock is updated diff --git a/platform/windows/SCsub b/platform/windows/SCsub index 135ccd902a..604896b0db 100644 --- a/platform/windows/SCsub +++ b/platform/windows/SCsub @@ -9,9 +9,9 @@ def make_debug_mingw(target, source, env): mingw_prefix = env["mingw_prefix_32"] else: mingw_prefix = env["mingw_prefix_64"] - os.system(mingw_prefix + 'objcopy --only-keep-debug %s %s.debug' % (target[0], target[0])) + os.system(mingw_prefix + 'objcopy --only-keep-debug %s %s.debugsymbols' % (target[0], target[0])) os.system(mingw_prefix + 'strip --strip-debug --strip-unneeded %s' % (target[0])) - os.system(mingw_prefix + 'objcopy --add-gnu-debuglink=%s.debug %s' % (target[0], target[0])) + os.system(mingw_prefix + 'objcopy --add-gnu-debuglink=%s.debugsymbols %s' % (target[0], target[0])) common_win = [ "context_gl_win.cpp", @@ -19,9 +19,6 @@ common_win = [ "os_windows.cpp", "ctxgl_procaddr.cpp", "key_mapping_win.cpp", - "tcp_server_winsock.cpp", - "packet_peer_udp_winsock.cpp", - "stream_peer_winsock.cpp", "joypad.cpp", "power_windows.cpp", "windows_terminal_logger.cpp" diff --git a/platform/windows/context_gl_win.cpp b/platform/windows/context_gl_win.cpp index 81aa18dd23..ccb0a41d13 100644 --- a/platform/windows/context_gl_win.cpp +++ b/platform/windows/context_gl_win.cpp @@ -181,8 +181,6 @@ Error ContextGL_Win::initialize() { MessageBox(NULL, "Can't Activate The GL 3.3 Rendering Context.", "ERROR", MB_OK | MB_ICONEXCLAMATION); return ERR_CANT_CREATE; // Return FALSE } - - printf("Activated GL 3.3 context"); } wglSwapIntervalEXT = (PFNWGLSWAPINTERVALEXTPROC)wglGetProcAddress("wglSwapIntervalEXT"); diff --git a/platform/windows/detect.py b/platform/windows/detect.py index bc8be7f034..564359d743 100644 --- a/platform/windows/detect.py +++ b/platform/windows/detect.py @@ -188,6 +188,9 @@ def configure(env): else: VC_PATH = "" + if (env["use_lto"]): + env.Append(CCFLAGS=['/GL']) + env.Append(LINKFLAGS=['/LTCG']) if (env["openmp"]): env.Append(CPPFLAGS=['/openmp']) @@ -269,7 +272,7 @@ def configure(env): if (env["openmp"]): env.Append(CPPFLAGS=['-fopenmp']) - env.Append(LIBS=['gomp']) + env.Append(LINKFLAGS=['-fopenmp']) ## Compile flags diff --git a/platform/windows/os_windows.cpp b/platform/windows/os_windows.cpp index bbfeff74e8..d3fa2bbc0d 100644 --- a/platform/windows/os_windows.cpp +++ b/platform/windows/os_windows.cpp @@ -34,19 +34,19 @@ #include "drivers/windows/dir_access_windows.h" #include "drivers/windows/file_access_windows.h" #include "drivers/windows/mutex_windows.h" +#include "drivers/windows/packet_peer_udp_winsock.h" #include "drivers/windows/rw_lock_windows.h" #include "drivers/windows/semaphore_windows.h" +#include "drivers/windows/stream_peer_tcp_winsock.h" +#include "drivers/windows/tcp_server_winsock.h" #include "drivers/windows/thread_windows.h" #include "io/marshalls.h" #include "joypad.h" #include "lang_table.h" #include "main/main.h" -#include "packet_peer_udp_winsock.h" #include "servers/audio_server.h" #include "servers/visual/visual_server_raster.h" #include "servers/visual/visual_server_wrap_mt.h" -#include "stream_peer_winsock.h" -#include "tcp_server_winsock.h" #include "version_generated.gen.h" #include "windows_terminal_logger.h" @@ -196,7 +196,7 @@ void OS_Windows::initialize_core() { DirAccess::make_default<DirAccessWindows>(DirAccess::ACCESS_FILESYSTEM); TCPServerWinsock::make_default(); - StreamPeerWinsock::make_default(); + StreamPeerTCPWinsock::make_default(); PacketPeerUDPWinsock::make_default(); // We need to know how often the clock is updated @@ -1253,7 +1253,7 @@ void OS_Windows::finalize_core() { memdelete(process_map); TCPServerWinsock::cleanup(); - StreamPeerWinsock::cleanup(); + StreamPeerTCPWinsock::cleanup(); } void OS_Windows::alert(const String &p_alert, const String &p_title) { @@ -1598,7 +1598,7 @@ bool OS_Windows::is_window_maximized() const { return maximized; } -void OS_Windows::set_borderless_window(int p_borderless) { +void OS_Windows::set_borderless_window(bool p_borderless) { if (video_mode.borderless_window == p_borderless) return; @@ -2288,19 +2288,19 @@ String OS_Windows::get_joy_guid(int p_device) const { return input->get_joy_guid_remapped(p_device); } -void OS_Windows::set_use_vsync(bool p_enable) { +void OS_Windows::_set_use_vsync(bool p_enable) { if (gl_context) gl_context->set_use_vsync(p_enable); } - +/* bool OS_Windows::is_vsync_enabled() const { if (gl_context) return gl_context->is_using_vsync(); return true; -} +}*/ OS::PowerState OS_Windows::get_power_state() { return power_manager->get_power_state(); diff --git a/platform/windows/os_windows.h b/platform/windows/os_windows.h index 0b0269a372..7c5490a0a4 100644 --- a/platform/windows/os_windows.h +++ b/platform/windows/os_windows.h @@ -210,7 +210,7 @@ public: virtual bool is_window_maximized() const; virtual void request_attention(); - virtual void set_borderless_window(int p_borderless); + virtual void set_borderless_window(bool p_borderless); virtual bool get_borderless_window(); virtual Error open_dynamic_library(const String p_path, void *&p_library_handle, bool p_also_set_library_path = false); @@ -275,8 +275,8 @@ public: virtual bool is_joy_known(int p_device); virtual String get_joy_guid(int p_device) const; - virtual void set_use_vsync(bool p_enable); - virtual bool is_vsync_enabled() const; + virtual void _set_use_vsync(bool p_enable); + //virtual bool is_vsync_enabled() const; virtual OS::PowerState get_power_state(); virtual int get_power_seconds_left(); diff --git a/platform/x11/SCsub b/platform/x11/SCsub index 6378553638..38dd2ddd88 100644 --- a/platform/x11/SCsub +++ b/platform/x11/SCsub @@ -4,9 +4,9 @@ import os Import('env') def make_debug(target, source, env): - os.system('objcopy --only-keep-debug %s %s.debug' % (target[0], target[0])) + os.system('objcopy --only-keep-debug %s %s.debugsymbols' % (target[0], target[0])) os.system('strip --strip-debug --strip-unneeded %s' % (target[0])) - os.system('objcopy --add-gnu-debuglink=%s.debug %s' % (target[0], target[0])) + os.system('objcopy --add-gnu-debuglink=%s.debugsymbols %s' % (target[0], target[0])) common_x11 = [ "context_gl_x11.cpp", diff --git a/platform/x11/detect.py b/platform/x11/detect.py index 0f07e22e6b..09bf57c5f1 100644 --- a/platform/x11/detect.py +++ b/platform/x11/detect.py @@ -265,9 +265,9 @@ def configure(env): env.Append(LINKFLAGS=['-m64', '-L/usr/lib/i686-linux-gnu']) - if (env["openmp"]): + if env["openmp"]: env.Append(CPPFLAGS=['-fopenmp']) - env.Append(LIBS=['gomp']) + env.Append(LINKFLAGS=['-fopenmp']) if env['use_static_cpp']: env.Append(LINKFLAGS=['-static-libstdc++']) diff --git a/platform/x11/export/export.cpp b/platform/x11/export/export.cpp index fdb43c9ae0..1baa3e127f 100644 --- a/platform/x11/export/export.cpp +++ b/platform/x11/export/export.cpp @@ -44,7 +44,8 @@ void register_x11_exporter() { logo->create_from_image(img); platform->set_logo(logo); platform->set_name("Linux/X11"); - platform->set_extension("bin"); + platform->set_extension("x86"); + platform->set_extension("x86_64", "binary_format/64_bits"); platform->set_release_32("linux_x11_32_release"); platform->set_debug_32("linux_x11_32_debug"); platform->set_release_64("linux_x11_64_release"); diff --git a/platform/x11/os_x11.cpp b/platform/x11/os_x11.cpp index b2e023d991..6616e47317 100644 --- a/platform/x11/os_x11.cpp +++ b/platform/x11/os_x11.cpp @@ -1098,7 +1098,7 @@ bool OS_X11::is_window_maximized() const { return false; } -void OS_X11::set_borderless_window(int p_borderless) { +void OS_X11::set_borderless_window(bool p_borderless) { if (current_videomode.borderless_window == p_borderless) return; @@ -2306,11 +2306,11 @@ String OS_X11::get_joy_guid(int p_device) const { return input->get_joy_guid_remapped(p_device); } -void OS_X11::set_use_vsync(bool p_enable) { +void OS_X11::_set_use_vsync(bool p_enable) { if (context_gl) return context_gl->set_use_vsync(p_enable); } - +/* bool OS_X11::is_vsync_enabled() const { if (context_gl) @@ -2318,7 +2318,7 @@ bool OS_X11::is_vsync_enabled() const { return true; } - +*/ void OS_X11::set_context(int p_context) { XClassHint *classHint = XAllocClassHint(); diff --git a/platform/x11/os_x11.h b/platform/x11/os_x11.h index ec8d12da27..86f25918fd 100644 --- a/platform/x11/os_x11.h +++ b/platform/x11/os_x11.h @@ -258,7 +258,7 @@ public: virtual bool is_window_maximized() const; virtual void request_attention(); - virtual void set_borderless_window(int p_borderless); + virtual void set_borderless_window(bool p_borderless); virtual bool get_borderless_window(); virtual void set_ime_position(const Point2 &p_pos); @@ -270,8 +270,8 @@ public: virtual void set_context(int p_context); - virtual void set_use_vsync(bool p_enable); - virtual bool is_vsync_enabled() const; + virtual void _set_use_vsync(bool p_enable); + //virtual bool is_vsync_enabled() const; virtual OS::PowerState get_power_state(); virtual int get_power_seconds_left(); diff --git a/scene/2d/navigation2d.cpp b/scene/2d/navigation2d.cpp index 9eff107827..40013814f8 100644 --- a/scene/2d/navigation2d.cpp +++ b/scene/2d/navigation2d.cpp @@ -205,7 +205,7 @@ void Navigation2D::_navpoly_unlink(int p_id) { nm.linked = false; } -int Navigation2D::navpoly_create(const Ref<NavigationPolygon> &p_mesh, const Transform2D &p_xform, Object *p_owner) { +int Navigation2D::navpoly_add(const Ref<NavigationPolygon> &p_mesh, const Transform2D &p_xform, Object *p_owner) { int id = last_id++; NavMesh nm; @@ -708,7 +708,7 @@ Object *Navigation2D::get_closest_point_owner(const Vector2 &p_point) { void Navigation2D::_bind_methods() { - ClassDB::bind_method(D_METHOD("navpoly_create", "mesh", "xform", "owner"), &Navigation2D::navpoly_create, DEFVAL(Variant())); + ClassDB::bind_method(D_METHOD("navpoly_add", "mesh", "xform", "owner"), &Navigation2D::navpoly_add, DEFVAL(Variant())); ClassDB::bind_method(D_METHOD("navpoly_set_transform", "id", "xform"), &Navigation2D::navpoly_set_transform); ClassDB::bind_method(D_METHOD("navpoly_remove", "id"), &Navigation2D::navpoly_remove); diff --git a/scene/2d/navigation2d.h b/scene/2d/navigation2d.h index bb97e1a9a9..02dbcb0f96 100644 --- a/scene/2d/navigation2d.h +++ b/scene/2d/navigation2d.h @@ -159,7 +159,7 @@ protected: public: //API should be as dynamic as possible - int navpoly_create(const Ref<NavigationPolygon> &p_mesh, const Transform2D &p_xform, Object *p_owner = NULL); + int navpoly_add(const Ref<NavigationPolygon> &p_mesh, const Transform2D &p_xform, Object *p_owner = NULL); void navpoly_set_transform(int p_id, const Transform2D &p_xform); void navpoly_remove(int p_id); diff --git a/scene/2d/navigation_polygon.cpp b/scene/2d/navigation_polygon.cpp index c53241e985..5a6a5128e6 100644 --- a/scene/2d/navigation_polygon.cpp +++ b/scene/2d/navigation_polygon.cpp @@ -293,7 +293,7 @@ void NavigationPolygonInstance::set_enabled(bool p_enabled) { if (navpoly.is_valid()) { - nav_id = navigation->navpoly_create(navpoly, get_relative_transform_to_parent(navigation), this); + nav_id = navigation->navpoly_add(navpoly, get_relative_transform_to_parent(navigation), this); } } } @@ -324,7 +324,7 @@ void NavigationPolygonInstance::_notification(int p_what) { if (enabled && navpoly.is_valid()) { - nav_id = navigation->navpoly_create(navpoly, get_relative_transform_to_parent(navigation), this); + nav_id = navigation->navpoly_add(navpoly, get_relative_transform_to_parent(navigation), this); } break; } @@ -419,7 +419,7 @@ void NavigationPolygonInstance::set_navigation_polygon(const Ref<NavigationPolyg } if (navigation && navpoly.is_valid() && enabled) { - nav_id = navigation->navpoly_create(navpoly, get_relative_transform_to_parent(navigation), this); + nav_id = navigation->navpoly_add(navpoly, get_relative_transform_to_parent(navigation), this); } //update_gizmo(); _change_notify("navpoly"); diff --git a/scene/2d/tile_map.cpp b/scene/2d/tile_map.cpp index 1e34372d1e..7b30ddaa56 100644 --- a/scene/2d/tile_map.cpp +++ b/scene/2d/tile_map.cpp @@ -486,7 +486,7 @@ void TileMap::_update_dirty_quadrants() { xform.set_origin(offset.floor() + q.pos); _fix_cell_transform(xform, c, npoly_ofs + center_ofs, s); - int pid = navigation->navpoly_create(navpoly, nav_rel * xform); + int pid = navigation->navpoly_add(navpoly, nav_rel * xform); Quadrant::NavPoly np; np.id = pid; @@ -739,6 +739,26 @@ void TileMap::update_bitmask_area(const Vector2 &p_pos) { } } +void TileMap::update_bitmask_region(const Vector2 &p_start, const Vector2 &p_end) { + + if ((p_end.x < p_start.x || p_end.y < p_start.y) || (p_end.x == p_start.x && p_end.y == p_start.y)) { + int i; + Array a = get_used_cells(); + for (i = 0; i < a.size(); i++) { + // update_bitmask_area() in order to update cells adjacent to the + // current cell, since ordering in array may not be reliable + Vector2 vector = (Vector2)a[i]; + update_bitmask_area(Vector2(vector.x, vector.y)); + } + return; + } + for (int x = p_start.x - 1; x <= p_end.x + 1; x++) { + for (int y = p_start.y - 1; y <= p_end.y + 1; y++) { + update_cell_bitmask(x, y); + } + } +} + void TileMap::update_cell_bitmask(int p_x, int p_y) { PosKey p(p_x, p_y); @@ -1507,6 +1527,9 @@ void TileMap::_bind_methods() { ClassDB::bind_method(D_METHOD("_recreate_quadrants"), &TileMap::_recreate_quadrants); ClassDB::bind_method(D_METHOD("_update_dirty_quadrants"), &TileMap::_update_dirty_quadrants); + ClassDB::bind_method(D_METHOD("update_bitmask_area"), &TileMap::update_bitmask_area); + ClassDB::bind_method(D_METHOD("update_bitmask_region", "start", "end"), &TileMap::update_bitmask_region, DEFVAL(Vector2()), DEFVAL(Vector2())); + ClassDB::bind_method(D_METHOD("_set_tile_data"), &TileMap::_set_tile_data); ClassDB::bind_method(D_METHOD("_get_tile_data"), &TileMap::_get_tile_data); diff --git a/scene/2d/tile_map.h b/scene/2d/tile_map.h index e5608884c4..8f0b2e6e4c 100644 --- a/scene/2d/tile_map.h +++ b/scene/2d/tile_map.h @@ -245,6 +245,7 @@ public: void make_bitmask_area_dirty(const Vector2 &p_pos); void update_bitmask_area(const Vector2 &p_pos); + void update_bitmask_region(const Vector2 &p_start = Vector2(), const Vector2 &p_end = Vector2()); void update_cell_bitmask(int p_x, int p_y); void update_dirty_bitmask(); diff --git a/scene/3d/baked_lightmap.cpp b/scene/3d/baked_lightmap.cpp index 8af8c2f7da..99d14e7f74 100644 --- a/scene/3d/baked_lightmap.cpp +++ b/scene/3d/baked_lightmap.cpp @@ -175,6 +175,7 @@ BakedLightmap::Subdiv BakedLightmap::get_capture_subdiv() const { void BakedLightmap::set_extents(const Vector3 &p_extents) { extents = p_extents; + update_gizmo(); } Vector3 BakedLightmap::get_extents() const { @@ -701,6 +702,12 @@ void BakedLightmap::_bind_methods() { BIND_ENUM_CONSTANT(BAKE_QUALITY_HIGH); BIND_ENUM_CONSTANT(BAKE_MODE_CONE_TRACE); BIND_ENUM_CONSTANT(BAKE_MODE_RAY_TRACE); + + BIND_ENUM_CONSTANT(BAKE_ERROR_OK); + BIND_ENUM_CONSTANT(BAKE_ERROR_NO_SAVE_PATH); + BIND_ENUM_CONSTANT(BAKE_ERROR_NO_MESHES); + BIND_ENUM_CONSTANT(BAKE_ERROR_CANT_CREATE_IMAGE); + BIND_ENUM_CONSTANT(BAKE_ERROR_USER_ABORTED); } BakedLightmap::BakedLightmap() { diff --git a/scene/3d/camera.cpp b/scene/3d/camera.cpp index af210fff1c..72c0b979af 100644 --- a/scene/3d/camera.cpp +++ b/scene/3d/camera.cpp @@ -56,126 +56,16 @@ void Camera::_update_camera_mode() { } } -bool Camera::_set(const StringName &p_name, const Variant &p_value) { - - bool changed_all = false; - if (p_name == "projection") { - - int proj = p_value; - if (proj == PROJECTION_PERSPECTIVE) - mode = PROJECTION_PERSPECTIVE; - if (proj == PROJECTION_ORTHOGONAL) - mode = PROJECTION_ORTHOGONAL; - - changed_all = true; - } else if (p_name == "fov" || p_name == "fovy" || p_name == "fovx") - fov = p_value; - else if (p_name == "size" || p_name == "sizex" || p_name == "sizey") - size = p_value; - else if (p_name == "near") - near = p_value; - else if (p_name == "far") - far = p_value; - else if (p_name == "keep_aspect") - set_keep_aspect_mode(KeepAspect(int(p_value))); - else if (p_name == "vaspect") - set_keep_aspect_mode(p_value ? KEEP_WIDTH : KEEP_HEIGHT); - else if (p_name == "h_offset") - h_offset = p_value; - else if (p_name == "v_offset") - v_offset = p_value; - else if (p_name == "current") { - if (p_value.operator bool()) { - make_current(); - } else { - clear_current(); +void Camera::_validate_property(PropertyInfo &p_property) const { + if (p_property.name == "fov") { + if (mode == PROJECTION_ORTHOGONAL) { + p_property.usage = PROPERTY_USAGE_NOEDITOR; } - } else if (p_name == "cull_mask") { - set_cull_mask(p_value); - } else if (p_name == "environment") { - set_environment(p_value); - } else if (p_name == "doppler/tracking") { - set_doppler_tracking(DopplerTracking(int(p_value))); - } else - return false; - - _update_camera_mode(); - if (changed_all) - _change_notify(); - return true; -} -bool Camera::_get(const StringName &p_name, Variant &r_ret) const { - - if (p_name == "projection") { - r_ret = mode; - } else if (p_name == "fov" || p_name == "fovy" || p_name == "fovx") - r_ret = fov; - else if (p_name == "size" || p_name == "sizex" || p_name == "sizey") - r_ret = size; - else if (p_name == "near") - r_ret = near; - else if (p_name == "far") - r_ret = far; - else if (p_name == "keep_aspect") - r_ret = int(keep_aspect); - else if (p_name == "current") { - - if (is_inside_tree() && get_tree()->is_node_being_edited(this)) { - r_ret = current; - } else { - r_ret = is_current(); + } else if (p_property.name == "size") { + if (mode == PROJECTION_PERSPECTIVE) { + p_property.usage = PROPERTY_USAGE_NOEDITOR; } - } else if (p_name == "cull_mask") { - r_ret = get_cull_mask(); - } else if (p_name == "h_offset") { - r_ret = get_h_offset(); - } else if (p_name == "v_offset") { - r_ret = get_v_offset(); - } else if (p_name == "environment") { - r_ret = get_environment(); - } else if (p_name == "doppler/tracking") { - r_ret = get_doppler_tracking(); - } else - return false; - - return true; -} - -void Camera::_get_property_list(List<PropertyInfo> *p_list) const { - - p_list->push_back(PropertyInfo(Variant::INT, "projection", PROPERTY_HINT_ENUM, "Perspective,Orthogonal")); - - switch (mode) { - - case PROJECTION_PERSPECTIVE: { - - p_list->push_back(PropertyInfo(Variant::REAL, "fov", PROPERTY_HINT_RANGE, "1,179,0.1", PROPERTY_USAGE_NOEDITOR)); - if (keep_aspect == KEEP_WIDTH) - p_list->push_back(PropertyInfo(Variant::REAL, "fovx", PROPERTY_HINT_RANGE, "1,179,0.1", PROPERTY_USAGE_EDITOR)); - else - p_list->push_back(PropertyInfo(Variant::REAL, "fovy", PROPERTY_HINT_RANGE, "1,179,0.1", PROPERTY_USAGE_EDITOR)); - - } break; - case PROJECTION_ORTHOGONAL: { - - p_list->push_back(PropertyInfo(Variant::REAL, "size", PROPERTY_HINT_RANGE, "1,16384,0.01", PROPERTY_USAGE_NOEDITOR)); - if (keep_aspect == KEEP_WIDTH) - p_list->push_back(PropertyInfo(Variant::REAL, "sizex", PROPERTY_HINT_RANGE, "0.1,16384,0.01", PROPERTY_USAGE_EDITOR)); - else - p_list->push_back(PropertyInfo(Variant::REAL, "sizey", PROPERTY_HINT_RANGE, "0.1,16384,0.01", PROPERTY_USAGE_EDITOR)); - - } break; } - - p_list->push_back(PropertyInfo(Variant::REAL, "near", PROPERTY_HINT_EXP_RANGE, "0.01,4096.0,0.01")); - p_list->push_back(PropertyInfo(Variant::REAL, "far", PROPERTY_HINT_EXP_RANGE, "0.01,4096.0,0.01")); - p_list->push_back(PropertyInfo(Variant::INT, "keep_aspect", PROPERTY_HINT_ENUM, "Keep Width,Keep Height")); - p_list->push_back(PropertyInfo(Variant::BOOL, "current")); - p_list->push_back(PropertyInfo(Variant::INT, "cull_mask", PROPERTY_HINT_LAYERS_3D_RENDER)); - p_list->push_back(PropertyInfo(Variant::OBJECT, "environment", PROPERTY_HINT_RESOURCE_TYPE, "Environment")); - p_list->push_back(PropertyInfo(Variant::REAL, "h_offset")); - p_list->push_back(PropertyInfo(Variant::REAL, "v_offset")); - p_list->push_back(PropertyInfo(Variant::INT, "doppler/tracking", PROPERTY_HINT_ENUM, "Disabled,Idle,Physics")); } void Camera::_update_camera() { @@ -282,6 +172,14 @@ void Camera::set_orthogonal(float p_size, float p_z_near, float p_z_far) { update_gizmo(); } +void Camera::set_projection(Camera::Projection p_mode) { + if (p_mode == PROJECTION_PERSPECTIVE || p_mode == PROJECTION_ORTHOGONAL) { + mode = p_mode; + _update_camera_mode(); + _change_notify(); + } +} + RID Camera::get_camera() const { return camera; @@ -311,6 +209,14 @@ void Camera::clear_current() { } } +void Camera::set_current(bool p_current) { + if (p_current) { + make_current(); + } else { + clear_current(); + } +} + bool Camera::is_current() const { if (is_inside_tree() && !get_tree()->is_node_being_edited(this)) { @@ -481,6 +387,7 @@ void Camera::set_environment(const Ref<Environment> &p_environment) { VS::get_singleton()->camera_set_environment(camera, environment->get_rid()); else VS::get_singleton()->camera_set_environment(camera, RID()); + _update_camera_mode(); } Ref<Environment> Camera::get_environment() const { @@ -489,10 +396,9 @@ Ref<Environment> Camera::get_environment() const { } void Camera::set_keep_aspect_mode(KeepAspect p_aspect) { - keep_aspect = p_aspect; VisualServer::get_singleton()->camera_set_use_vertical_aspect(camera, p_aspect == KEEP_WIDTH); - + _update_camera_mode(); _change_notify(); } @@ -501,6 +407,15 @@ Camera::KeepAspect Camera::get_keep_aspect_mode() const { return keep_aspect; } +void Camera::set_vaspect(bool p_vaspect) { + set_keep_aspect_mode(p_vaspect ? KEEP_WIDTH : KEEP_HEIGHT); + _update_camera_mode(); +} + +bool Camera::get_vaspect() const { + return keep_aspect == KEEP_HEIGHT; +} + void Camera::set_doppler_tracking(DopplerTracking p_tracking) { if (doppler_tracking == p_tracking) @@ -511,6 +426,7 @@ void Camera::set_doppler_tracking(DopplerTracking p_tracking) { velocity_tracker->set_track_physics_step(doppler_tracking == DOPPLER_TRACKING_PHYSICS_STEP); velocity_tracker->reset(get_global_transform().origin); } + _update_camera_mode(); } Camera::DopplerTracking Camera::get_doppler_tracking() const { @@ -529,13 +445,19 @@ void Camera::_bind_methods() { ClassDB::bind_method(D_METHOD("set_orthogonal", "size", "z_near", "z_far"), &Camera::set_orthogonal); ClassDB::bind_method(D_METHOD("make_current"), &Camera::make_current); ClassDB::bind_method(D_METHOD("clear_current"), &Camera::clear_current); + ClassDB::bind_method(D_METHOD("set_current"), &Camera::set_current); ClassDB::bind_method(D_METHOD("is_current"), &Camera::is_current); ClassDB::bind_method(D_METHOD("get_camera_transform"), &Camera::get_camera_transform); ClassDB::bind_method(D_METHOD("get_fov"), &Camera::get_fov); ClassDB::bind_method(D_METHOD("get_size"), &Camera::get_size); ClassDB::bind_method(D_METHOD("get_zfar"), &Camera::get_zfar); ClassDB::bind_method(D_METHOD("get_znear"), &Camera::get_znear); + ClassDB::bind_method(D_METHOD("set_fov"), &Camera::set_fov); + ClassDB::bind_method(D_METHOD("set_size"), &Camera::set_size); + ClassDB::bind_method(D_METHOD("set_zfar"), &Camera::set_zfar); + ClassDB::bind_method(D_METHOD("set_znear"), &Camera::set_znear); ClassDB::bind_method(D_METHOD("get_projection"), &Camera::get_projection); + ClassDB::bind_method(D_METHOD("set_projection"), &Camera::set_projection); ClassDB::bind_method(D_METHOD("set_h_offset", "ofs"), &Camera::set_h_offset); ClassDB::bind_method(D_METHOD("get_h_offset"), &Camera::get_h_offset); ClassDB::bind_method(D_METHOD("set_v_offset", "ofs"), &Camera::set_v_offset); @@ -546,10 +468,26 @@ void Camera::_bind_methods() { ClassDB::bind_method(D_METHOD("get_environment"), &Camera::get_environment); ClassDB::bind_method(D_METHOD("set_keep_aspect_mode", "mode"), &Camera::set_keep_aspect_mode); ClassDB::bind_method(D_METHOD("get_keep_aspect_mode"), &Camera::get_keep_aspect_mode); + ClassDB::bind_method(D_METHOD("set_vaspect"), &Camera::set_vaspect); + ClassDB::bind_method(D_METHOD("get_vaspect"), &Camera::get_vaspect); ClassDB::bind_method(D_METHOD("set_doppler_tracking", "mode"), &Camera::set_doppler_tracking); ClassDB::bind_method(D_METHOD("get_doppler_tracking"), &Camera::get_doppler_tracking); //ClassDB::bind_method(D_METHOD("_camera_make_current"),&Camera::_camera_make_current ); + ADD_PROPERTY(PropertyInfo(Variant::INT, "keep_aspect", PROPERTY_HINT_ENUM, "Keep Width,Keep Height"), "set_keep_aspect_mode", "get_keep_aspect_mode"); + ADD_PROPERTY(PropertyInfo(Variant::BOOL, "vaspect"), "set_vaspect", "get_vaspect"); + ADD_PROPERTY(PropertyInfo(Variant::INT, "cull_mask", PROPERTY_HINT_LAYERS_3D_RENDER), "set_cull_mask", "get_cull_mask"); + ADD_PROPERTY(PropertyInfo(Variant::OBJECT, "environment", PROPERTY_HINT_RESOURCE_TYPE, "Environment"), "set_environment", "get_environment"); + ADD_PROPERTY(PropertyInfo(Variant::REAL, "h_offset"), "set_h_offset", "get_h_offset"); + ADD_PROPERTY(PropertyInfo(Variant::REAL, "v_offset"), "set_v_offset", "get_v_offset"); + ADD_PROPERTY(PropertyInfo(Variant::INT, "doppler_tracking", PROPERTY_HINT_ENUM, "Disabled,Idle,Physics"), "set_doppler_tracking", "get_doppler_tracking"); + ADD_PROPERTY(PropertyInfo(Variant::INT, "projection", PROPERTY_HINT_ENUM, "Perspective,Orthogonal"), "set_projection", "get_projection"); + ADD_PROPERTY(PropertyInfo(Variant::BOOL, "current"), "set_current", "is_current"); + ADD_PROPERTY(PropertyInfo(Variant::REAL, "fov", PROPERTY_HINT_RANGE, "1,179,0.1"), "set_fov", "get_fov"); + ADD_PROPERTY(PropertyInfo(Variant::REAL, "size", PROPERTY_HINT_RANGE, "0.1,16384,0.01"), "set_size", "get_size"); + ADD_PROPERTY(PropertyInfo(Variant::REAL, "near"), "set_znear", "get_znear"); + ADD_PROPERTY(PropertyInfo(Variant::REAL, "far"), "set_zfar", "get_zfar"); + BIND_ENUM_CONSTANT(PROJECTION_PERSPECTIVE); BIND_ENUM_CONSTANT(PROJECTION_ORTHOGONAL); @@ -586,10 +524,30 @@ Camera::Projection Camera::get_projection() const { return mode; } -void Camera::set_cull_mask(uint32_t p_layers) { +void Camera::set_fov(float p_fov) { + fov = p_fov; + _update_camera_mode(); +} + +void Camera::set_size(float p_size) { + size = p_size; + _update_camera_mode(); +} + +void Camera::set_znear(float p_znear) { + near = p_znear; + _update_camera_mode(); +} +void Camera::set_zfar(float p_zfar) { + far = p_zfar; + _update_camera_mode(); +} + +void Camera::set_cull_mask(uint32_t p_layers) { layers = p_layers; VisualServer::get_singleton()->camera_set_cull_mask(camera, layers); + _update_camera_mode(); } uint32_t Camera::get_cull_mask() const { diff --git a/scene/3d/camera.h b/scene/3d/camera.h index 73c6844c1a..520afb962b 100644 --- a/scene/3d/camera.h +++ b/scene/3d/camera.h @@ -95,10 +95,8 @@ protected: virtual void _request_camera_update(); void _update_camera_mode(); - bool _set(const StringName &p_name, const Variant &p_value); - bool _get(const StringName &p_name, Variant &r_ret) const; - void _get_property_list(List<PropertyInfo> *p_list) const; void _notification(int p_what); + virtual void _validate_property(PropertyInfo &property) const; static void _bind_methods(); @@ -111,9 +109,11 @@ public: void set_perspective(float p_fovy_degrees, float p_z_near, float p_z_far); void set_orthogonal(float p_size, float p_z_near, float p_z_far); + void set_projection(Camera::Projection p_mode); void make_current(); void clear_current(); + void set_current(bool p_current); bool is_current() const; RID get_camera() const; @@ -124,6 +124,11 @@ public: float get_znear() const; Projection get_projection() const; + void set_fov(float p_fov); + void set_size(float p_size); + void set_zfar(float p_zfar); + void set_znear(float p_znear); + virtual Transform get_camera_transform() const; Vector3 project_ray_normal(const Point2 &p_pos) const; @@ -143,6 +148,8 @@ public: void set_keep_aspect_mode(KeepAspect p_aspect); KeepAspect get_keep_aspect_mode() const; + void set_vaspect(bool p_vaspect); + bool get_vaspect() const; void set_v_offset(float p_offset); float get_v_offset() const; diff --git a/scene/3d/navigation.cpp b/scene/3d/navigation.cpp index b6507aedb3..78cf75e3b3 100644 --- a/scene/3d/navigation.cpp +++ b/scene/3d/navigation.cpp @@ -202,7 +202,7 @@ void Navigation::_navmesh_unlink(int p_id) { nm.linked = false; } -int Navigation::navmesh_create(const Ref<NavigationMesh> &p_mesh, const Transform &p_xform, Object *p_owner) { +int Navigation::navmesh_add(const Ref<NavigationMesh> &p_mesh, const Transform &p_xform, Object *p_owner) { int id = last_id++; NavMesh nm; @@ -686,7 +686,7 @@ Vector3 Navigation::get_up_vector() const { void Navigation::_bind_methods() { - ClassDB::bind_method(D_METHOD("navmesh_create", "mesh", "xform", "owner"), &Navigation::navmesh_create, DEFVAL(Variant())); + ClassDB::bind_method(D_METHOD("navmesh_add", "mesh", "xform", "owner"), &Navigation::navmesh_add, DEFVAL(Variant())); ClassDB::bind_method(D_METHOD("navmesh_set_transform", "id", "xform"), &Navigation::navmesh_set_transform); ClassDB::bind_method(D_METHOD("navmesh_remove", "id"), &Navigation::navmesh_remove); diff --git a/scene/3d/navigation.h b/scene/3d/navigation.h index d9a38f7b00..134afa2278 100644 --- a/scene/3d/navigation.h +++ b/scene/3d/navigation.h @@ -166,7 +166,7 @@ public: Vector3 get_up_vector() const; //API should be as dynamic as possible - int navmesh_create(const Ref<NavigationMesh> &p_mesh, const Transform &p_xform, Object *p_owner = NULL); + int navmesh_add(const Ref<NavigationMesh> &p_mesh, const Transform &p_xform, Object *p_owner = NULL); void navmesh_set_transform(int p_id, const Transform &p_xform); void navmesh_remove(int p_id); diff --git a/scene/3d/navigation_mesh.cpp b/scene/3d/navigation_mesh.cpp index 40750cdfe8..4fb12b8fac 100644 --- a/scene/3d/navigation_mesh.cpp +++ b/scene/3d/navigation_mesh.cpp @@ -471,7 +471,7 @@ void NavigationMeshInstance::set_enabled(bool p_enabled) { if (navmesh.is_valid()) { - nav_id = navigation->navmesh_create(navmesh, get_relative_transform(navigation), this); + nav_id = navigation->navmesh_add(navmesh, get_relative_transform(navigation), this); } } } @@ -508,7 +508,7 @@ void NavigationMeshInstance::_notification(int p_what) { if (enabled && navmesh.is_valid()) { - nav_id = navigation->navmesh_create(navmesh, get_relative_transform(navigation), this); + nav_id = navigation->navmesh_add(navmesh, get_relative_transform(navigation), this); } break; } @@ -568,7 +568,7 @@ void NavigationMeshInstance::set_navigation_mesh(const Ref<NavigationMesh> &p_na navmesh = p_navmesh; if (navigation && navmesh.is_valid() && enabled) { - nav_id = navigation->navmesh_create(navmesh, get_relative_transform(navigation), this); + nav_id = navigation->navmesh_add(navmesh, get_relative_transform(navigation), this); } if (debug_view && navmesh.is_valid()) { diff --git a/scene/3d/particles.cpp b/scene/3d/particles.cpp index 821f1a5a78..b445ccc5a9 100644 --- a/scene/3d/particles.cpp +++ b/scene/3d/particles.cpp @@ -598,6 +598,11 @@ void ParticlesMaterial::_update_shader() { code += "}\n"; code += "\n"; + code += "float rand_from_seed_m1_p1(inout uint seed) {\n"; + code += " return rand_from_seed(seed)*2.0-1.0;\n"; + code += "}\n"; + code += "\n"; + //improve seed quality code += "uint hash(uint x) {\n"; code += " x = ((x >> uint(16)) ^ x) * uint(73244475);\n"; @@ -614,6 +619,8 @@ void ParticlesMaterial::_update_shader() { code += " float scale_rand = rand_from_seed(alt_seed);\n"; code += " float hue_rot_rand = rand_from_seed(alt_seed);\n"; code += " float anim_offset_rand = rand_from_seed(alt_seed);\n"; + code += " float pi = 3.14159;\n"; + code += " float degree_to_rad = pi / 180.0;\n"; code += "\n"; if (emission_shape >= EMISSION_SHAPE_POINTS) { @@ -638,23 +645,28 @@ void ParticlesMaterial::_update_shader() { else code += " float tex_anim_offset = 0.0;\n"; + code += " float spread_rad = spread*degree_to_rad;\n"; + if (flags[FLAG_DISABLE_Z]) { - code += " float angle1 = (rand_from_seed(alt_seed)*2.0-1.0)*spread/180.0*3.1416;\n"; - code += " vec3 rot = vec3( cos(angle1), sin(angle1),0.0 );\n"; + code += " float angle1_rad = rand_from_seed_m1_p1(alt_seed)*spread_rad;\n"; + code += " vec3 rot = vec3( cos(angle1_rad), sin(angle1_rad),0.0 );\n"; code += " VELOCITY = rot*initial_linear_velocity*mix(1.0, rand_from_seed(alt_seed), initial_linear_velocity_random);\n"; } else { //initiate velocity spread in 3D - code += " float angle1 = rand_from_seed(alt_seed)*spread*3.1416;\n"; - code += " float angle2 = rand_from_seed(alt_seed)*20.0*3.1416; // make it more random like\n"; - code += " vec3 rot_xz = vec3( sin(angle1), 0.0, cos(angle1) );\n"; - code += " vec3 rot = vec3( cos(angle2)*rot_xz.x,sin(angle2)*rot_xz.x, rot_xz.z);\n"; - code += " VELOCITY = rot*initial_linear_velocity*mix(1.0, rand_from_seed(alt_seed), initial_linear_velocity_random);\n"; + code += " float angle1_rad = rand_from_seed_m1_p1(alt_seed)*spread_rad;\n"; + code += " float angle2_rad = rand_from_seed_m1_p1(alt_seed)*spread_rad*(1.0-flatness);\n"; + code += " vec3 direction_xz = vec3( sin(angle1_rad), 0, cos(angle1_rad));\n"; + code += " vec3 direction_yz = vec3( 0, sin(angle2_rad), cos(angle2_rad));\n"; + code += " direction_yz.z = direction_yz.z / sqrt(direction_yz.z); //better uniform distribution\n"; + code += " vec3 direction = vec3(direction_xz.x * direction_yz.z, direction_yz.y, direction_xz.z * direction_yz.z);\n"; + code += " direction = normalize(direction);\n"; + code += " VELOCITY = direction*initial_linear_velocity*mix(1.0, rand_from_seed(alt_seed), initial_linear_velocity_random);\n"; } code += " float base_angle = (initial_angle+tex_angle)*mix(1.0,angle_rand,initial_angle_random);\n"; - code += " CUSTOM.x = base_angle*3.1416/180.0;\n"; //angle + code += " CUSTOM.x = base_angle*degree_to_rad;\n"; //angle code += " CUSTOM.y = 0.0;\n"; //phase code += " CUSTOM.z = (anim_offset+tex_anim_offset)*mix(1.0,anim_offset_rand,anim_offset_random);\n"; //animation offset (0-1) switch (emission_shape) { @@ -777,7 +789,7 @@ void ParticlesMaterial::_update_shader() { code += " float orbit_amount = (orbit_velocity+tex_orbit_velocity)*mix(1.0,rand_from_seed(alt_seed),orbit_velocity_random);\n"; code += " if (orbit_amount!=0.0) {\n"; - code += " float ang = orbit_amount * DELTA * 3.1416 * 2.0;\n"; + code += " float ang = orbit_amount * DELTA * pi * 2.0;\n"; code += " mat2 rot = mat2(vec2(cos(ang),-sin(ang)),vec2(sin(ang),cos(ang)));\n"; code += " TRANSFORM[3].xy-=diff.xy;\n"; code += " TRANSFORM[3].xy+=rot * diff.xy;\n"; @@ -800,7 +812,7 @@ void ParticlesMaterial::_update_shader() { code += " }\n"; code += " float base_angle = (initial_angle+tex_angle)*mix(1.0,angle_rand,initial_angle_random);\n"; code += " base_angle += CUSTOM.y*LIFETIME*(angular_velocity+tex_angular_velocity)*mix(1.0,rand_from_seed(alt_seed)*2.0-1.0,angular_velocity_random);\n"; - code += " CUSTOM.x = base_angle*3.1416/180.0;\n"; //angle + code += " CUSTOM.x = base_angle*degree_to_rad;\n"; //angle code += " CUSTOM.z = (anim_offset+tex_anim_offset)*mix(1.0,anim_offset_rand,anim_offset_random)+CUSTOM.y*(anim_speed+tex_anim_speed)*mix(1.0,rand_from_seed(alt_seed),anim_speed_random);\n"; //angle if (flags[FLAG_ANIM_LOOP]) { code += " CUSTOM.z = mod(CUSTOM.z,1.0);\n"; //loop @@ -821,7 +833,7 @@ void ParticlesMaterial::_update_shader() { else code += " float tex_hue_variation = 0.0;\n"; - code += " float hue_rot_angle = (hue_variation+tex_hue_variation)*3.1416*2.0*mix(1.0,hue_rot_rand*2.0-1.0,hue_variation_random);\n"; + code += " float hue_rot_angle = (hue_variation+tex_hue_variation)*pi*2.0*mix(1.0,hue_rot_rand*2.0-1.0,hue_variation_random);\n"; code += " float hue_rot_c = cos(hue_rot_angle);\n"; code += " float hue_rot_s = sin(hue_rot_angle);\n"; code += " mat4 hue_rot_mat = mat4( vec4(0.299, 0.587, 0.114, 0.0),\n"; diff --git a/scene/3d/voxel_light_baker.cpp b/scene/3d/voxel_light_baker.cpp index 98dc1590d8..c05dfddeca 100644 --- a/scene/3d/voxel_light_baker.cpp +++ b/scene/3d/voxel_light_baker.cpp @@ -1781,7 +1781,7 @@ Error VoxelLightBaker::make_lightmap(const Transform &p_xform, Ref<Mesh> &p_mesh //print_line("bake line " + itos(i) + " / " + itos(height)); #ifdef _OPENMP -#pragma omp parallel for +#pragma omp parallel for schedule(dynamic, 1) #endif for (int j = 0; j < width; j++) { @@ -1878,12 +1878,14 @@ Error VoxelLightBaker::make_lightmap(const Transform &p_xform, Ref<Mesh> &p_mesh LightMap *lightmap_ptr = lightmap.ptrw(); const Cell *cells = bake_cells.ptr(); const Light *light = bake_light.ptr(); - +#ifdef _OPENMP +#pragma omp parallel +#endif for (int i = 0; i < height; i++) { //print_line("bake line " + itos(i) + " / " + itos(height)); #ifdef _OPENMP -#pragma omp parallel for +#pragma omp parallel for schedule(dynamic, 1) #endif for (int j = 0; j < width; j++) { diff --git a/scene/gui/dialogs.cpp b/scene/gui/dialogs.cpp index d4912339da..9a55073bb6 100644 --- a/scene/gui/dialogs.cpp +++ b/scene/gui/dialogs.cpp @@ -289,10 +289,17 @@ bool WindowDialog::get_resizable() const { Size2 WindowDialog::get_minimum_size() const { Ref<Font> font = get_font("title_font", "WindowDialog"); - int msx = close_button->get_combined_minimum_size().x; - msx += font->get_string_size(title).x; - return Size2(msx, 1); + const int button_width = close_button->get_combined_minimum_size().x; + const int title_width = font->get_string_size(title).x; + const int padding = button_width / 2; + const int button_area = button_width + padding; + + // as the title gets centered, title_width + close_button_width is not enough. + // we want a width w, such that w / 2 - title_width / 2 >= button_area, i.e. + // w >= 2 * button_area + title_width + + return Size2(2 * button_area + title_width, 1); } TextureButton *WindowDialog::get_close_button() { diff --git a/scene/gui/popup_menu.cpp b/scene/gui/popup_menu.cpp index 32f889e826..698676cc39 100644 --- a/scene/gui/popup_menu.cpp +++ b/scene/gui/popup_menu.cpp @@ -42,24 +42,6 @@ String PopupMenu::_get_accel_text(int p_item) const { else if (items[p_item].accel) return keycode_get_string(items[p_item].accel); return String(); - - /* - String atxt; - if (p_accel&KEY_MASK_SHIFT) - atxt+="Shift+"; - if (p_accel&KEY_MASK_ALT) - atxt+="Alt+"; - if (p_accel&KEY_MASK_CTRL) - atxt+="Ctrl+"; - if (p_accel&KEY_MASK_META) - atxt+="Meta+"; - - p_accel&=KEY_CODE_MASK; - - atxt+=String::chr(p_accel).to_upper(); - - return atxt; -*/ } Size2 PopupMenu::get_minimum_size() const { @@ -136,7 +118,6 @@ int PopupMenu::_get_mouse_over(const Point2 &p_over) const { Ref<Font> font = get_font("font"); int vseparation = get_constant("vseparation"); - //int hseparation = get_constant("hseparation"); float font_h = font->get_height(); for (int i = 0; i < items.size(); i++) { @@ -230,6 +211,11 @@ void PopupMenu::_gui_input(const Ref<InputEvent> &p_event) { mouse_over = i; update(); + + if (items[i].submenu != "" && submenu_over != i) { + submenu_over = i; + submenu_timer->start(); + } break; } } @@ -245,6 +231,11 @@ void PopupMenu::_gui_input(const Ref<InputEvent> &p_event) { mouse_over = i; update(); + + if (items[i].submenu != "" && submenu_over != i) { + submenu_over = i; + submenu_timer->start(); + } break; } } @@ -500,6 +491,13 @@ void PopupMenu::_notification(int p_what) { } break; case NOTIFICATION_MOUSE_EXIT: { + if (mouse_over >= 0 && (items[mouse_over].submenu == "" || submenu_over != -1)) { + mouse_over = -1; + update(); + } + } break; + case NOTIFICATION_POPUP_HIDE: { + if (mouse_over >= 0) { mouse_over = -1; update(); @@ -1217,6 +1215,7 @@ void PopupMenu::set_invalidate_click_until_motion() { PopupMenu::PopupMenu() { mouse_over = -1; + submenu_over = -1; set_focus_mode(FOCUS_ALL); set_as_toplevel(true); diff --git a/scene/gui/rich_text_label.cpp b/scene/gui/rich_text_label.cpp index 05c6e9f77e..6fbc58a38a 100644 --- a/scene/gui/rich_text_label.cpp +++ b/scene/gui/rich_text_label.cpp @@ -31,6 +31,11 @@ #include "os/keyboard.h" #include "os/os.h" #include "scene/scene_string_names.h" + +#ifdef TOOLS_ENABLED +#include "editor/editor_node.h" +#endif + RichTextLabel::Item *RichTextLabel::_get_next_item(Item *p_item, bool p_free) { if (p_free) { @@ -370,7 +375,11 @@ int RichTextLabel::_process_line(ItemFrame *p_frame, const Vector2 &p_ofs, int & Color uc = color; uc.a *= 0.5; int uy = y + lh - fh + ascent + 2; - VS::get_singleton()->canvas_item_add_line(ci, p_ofs + Point2(align_ofs + pofs, uy), p_ofs + Point2(align_ofs + pofs + cw, uy), uc); + float underline_width = 1.0; +#ifdef TOOLS_ENABLED + underline_width *= EDSCALE; +#endif + VS::get_singleton()->canvas_item_add_line(ci, p_ofs + Point2(align_ofs + pofs, uy), p_ofs + Point2(align_ofs + pofs + cw, uy), uc, underline_width); } ofs += cw; } diff --git a/scene/gui/slider.cpp b/scene/gui/slider.cpp index 665ae8b6dd..70b8616af1 100644 --- a/scene/gui/slider.cpp +++ b/scene/gui/slider.cpp @@ -184,10 +184,10 @@ void Slider::_notification(int p_what) { focus->draw(ci,Rect2i(Point2i(),Size2i(style->get_minimum_size().width+style->get_center_size().width,size.height))); */ if (ticks > 1) { - int tickarea = size.height - tick->get_height(); + int grabber_offset = (grabber->get_size().height / 2 - tick->get_height() / 2); for (int i = 0; i < ticks; i++) { if (!ticks_on_borders && (i == 0 || i + 1 == ticks)) continue; - int ofs = i * tickarea / (ticks - 1); + int ofs = (i * areasize / (ticks - 1)) + grabber_offset; tick->draw(ci, Point2i((size.width - widget_width) / 2, ofs)); } } @@ -205,10 +205,10 @@ void Slider::_notification(int p_what) { */ if (ticks > 1) { - int tickarea = size.width - tick->get_width(); + int grabber_offset = (grabber->get_size().width / 2 - tick->get_width() / 2); for (int i = 0; i < ticks; i++) { if ((!ticks_on_borders) && ((i == 0) || ((i + 1) == ticks))) continue; - int ofs = i * tickarea / (ticks - 1); + int ofs = (i * areasize / (ticks - 1)) + grabber_offset; tick->draw(ci, Point2i(ofs, (size.height - widget_height) / 2)); } } diff --git a/scene/gui/text_edit.cpp b/scene/gui/text_edit.cpp index e5169089f2..83aee5ca30 100644 --- a/scene/gui/text_edit.cpp +++ b/scene/gui/text_edit.cpp @@ -1664,17 +1664,22 @@ void TextEdit::backspace_at_cursor() { cursor_set_column(prev_column); } -void TextEdit::indent_selection_right() { +void TextEdit::indent_right() { - if (!is_selection_active()) { - return; - } + int start_line; + int end_line; begin_complex_operation(); - int start_line = get_selection_from_line(); - int end_line = get_selection_to_line(); + + if (is_selection_active()) { + start_line = get_selection_from_line(); + end_line = get_selection_to_line(); + } else { + start_line = cursor.line; + end_line = start_line; + } // ignore if the cursor is not past the first column - if (get_selection_to_column() == 0) { + if (is_selection_active() && get_selection_to_column() == 0) { end_line--; } @@ -1688,23 +1693,32 @@ void TextEdit::indent_selection_right() { set_line(i, line_text); } - // fix selection being off by one on the last line - selection.to_column++; + // fix selection and cursor being off by one on the last line + if (is_selection_active()) { + selection.to_column++; + selection.from_column++; + } + cursor.column++; end_complex_operation(); update(); } -void TextEdit::indent_selection_left() { +void TextEdit::indent_left() { - if (!is_selection_active()) { - return; - } + int start_line; + int end_line; begin_complex_operation(); - int start_line = get_selection_from_line(); - int end_line = get_selection_to_line(); + + if (is_selection_active()) { + start_line = get_selection_from_line(); + end_line = get_selection_to_line(); + } else { + start_line = cursor.line; + end_line = start_line; + } // ignore if the cursor is not past the first column - if (get_selection_to_column() == 0) { + if (is_selection_active() && get_selection_to_column() == 0) { end_line--; } String last_line_text = get_line(end_line); @@ -1721,9 +1735,15 @@ void TextEdit::indent_selection_left() { } } - // fix selection being off by one on the last line - if (last_line_text != get_line(end_line) && selection.to_column > 0) { - selection.to_column--; + // fix selection and cursor being off by one on the last line + if (is_selection_active() && last_line_text != get_line(end_line)) { + if (selection.to_column > 0) + selection.to_column--; + if (selection.from_column > 0) + selection.from_column--; + } + if (cursor.column > 0) { + cursor.column--; } end_complex_operation(); update(); @@ -2216,9 +2236,9 @@ void TextEdit::_gui_input(const Ref<InputEvent> &p_gui_input) { case KEY_TAB: { if (k->get_shift()) { - indent_selection_left(); + indent_left(); } else { - indent_selection_right(); + indent_right(); } dobreak = true; accept_event(); @@ -2389,8 +2409,12 @@ void TextEdit::_gui_input(const Ref<InputEvent> &p_gui_input) { if (readonly) break; - if (selection.active) { - + if (is_selection_active()) { + if (k->get_shift()) { + indent_left(); + } else { + indent_right(); + } } else { if (k->get_shift()) { @@ -5444,8 +5468,10 @@ void TextEdit::_bind_methods() { ClassDB::bind_method(D_METHOD("cut"), &TextEdit::cut); ClassDB::bind_method(D_METHOD("copy"), &TextEdit::copy); ClassDB::bind_method(D_METHOD("paste"), &TextEdit::paste); - ClassDB::bind_method(D_METHOD("select_all"), &TextEdit::select_all); + ClassDB::bind_method(D_METHOD("select", "from_line", "from_column", "to_line", "to_column"), &TextEdit::select); + ClassDB::bind_method(D_METHOD("select_all"), &TextEdit::select_all); + ClassDB::bind_method(D_METHOD("deselect"), &TextEdit::deselect); ClassDB::bind_method(D_METHOD("is_selection_active"), &TextEdit::is_selection_active); ClassDB::bind_method(D_METHOD("get_selection_from_line"), &TextEdit::get_selection_from_line); diff --git a/scene/gui/text_edit.h b/scene/gui/text_edit.h index dd305d5822..edef28cc25 100644 --- a/scene/gui/text_edit.h +++ b/scene/gui/text_edit.h @@ -443,8 +443,8 @@ public: void set_line(int line, String new_text); void backspace_at_cursor(); - void indent_selection_left(); - void indent_selection_right(); + void indent_left(); + void indent_right(); int get_indent_level(int p_line) const; inline void set_scroll_pass_end_of_file(bool p_enabled) { diff --git a/scene/gui/tree.cpp b/scene/gui/tree.cpp index ab12d123ba..b5b42e8f29 100644 --- a/scene/gui/tree.cpp +++ b/scene/gui/tree.cpp @@ -30,6 +30,7 @@ #include "tree.h" #include <limits.h> +#include "math_funcs.h" #include "os/input.h" #include "os/keyboard.h" #include "os/os.h" @@ -37,6 +38,10 @@ #include "project_settings.h" #include "scene/main/viewport.h" +#ifdef TOOLS_ENABLED +#include "editor/editor_node.h" +#endif + void TreeItem::move_to_top() { if (!parent || parent->childs == this) @@ -1412,9 +1417,14 @@ int Tree::draw_item(const Point2i &p_pos, const Point2 &p_draw_ofs, const Size2 if (c->get_children() != NULL) root_pos -= Point2i(cache.arrow->get_width(), 0); + float line_width = 1.0; +#ifdef TOOLS_ENABLED + line_width *= EDSCALE; +#endif + Point2i parent_pos = Point2i(parent_ofs - cache.arrow->get_width() / 2, p_pos.y + label_h / 2 + cache.arrow->get_height() / 2) - cache.offset + p_draw_ofs; - VisualServer::get_singleton()->canvas_item_add_line(ci, root_pos, Point2i(parent_pos.x, root_pos.y), cache.relationship_line_color); - VisualServer::get_singleton()->canvas_item_add_line(ci, Point2i(parent_pos.x, root_pos.y), parent_pos, cache.relationship_line_color); + VisualServer::get_singleton()->canvas_item_add_line(ci, root_pos, Point2i(parent_pos.x - Math::floor(line_width / 2), root_pos.y), cache.relationship_line_color, line_width); + VisualServer::get_singleton()->canvas_item_add_line(ci, Point2i(parent_pos.x, root_pos.y), parent_pos, cache.relationship_line_color, line_width); } int child_h = draw_item(children_pos, p_draw_ofs, p_draw_size, c); diff --git a/scene/main/http_request.cpp b/scene/main/http_request.cpp index 672e893f1b..4afdb56f86 100644 --- a/scene/main/http_request.cpp +++ b/scene/main/http_request.cpp @@ -36,7 +36,6 @@ void HTTPRequest::_redirect_request(const String &p_new_url) { Error HTTPRequest::_request() { - //print_line("Requesting:\n\tURL: "+url+"\n\tString: "+request_string+"\n\tPort: "+itos(port)+"\n\tSSL: "+itos(use_ssl)+"\n\tValidate SSL: "+itos(validate_ssl)); return client->connect_to_host(url, port, use_ssl, validate_ssl); } @@ -54,37 +53,32 @@ Error HTTPRequest::_parse_url(const String &p_url) { downloaded = 0; redirections = 0; - //print_line("1 url: "+url); - if (url.begins_with("http://")) { - + String url_lower = url.to_lower(); + if (url_lower.begins_with("http://")) { url = url.substr(7, url.length() - 7); - //print_line("no SSL"); - - } else if (url.begins_with("https://")) { + } else if (url_lower.begins_with("https://")) { url = url.substr(8, url.length() - 8); use_ssl = true; port = 443; - //print_line("yes SSL"); } else { ERR_EXPLAIN("Malformed URL"); ERR_FAIL_V(ERR_INVALID_PARAMETER); } - //print_line("2 url: "+url); + if (url.length() < 1) { + ERR_EXPLAIN("URL too short"); + ERR_FAIL_V(ERR_INVALID_PARAMETER); + } int slash_pos = url.find("/"); if (slash_pos != -1) { request_string = url.substr(slash_pos, url.length()); url = url.substr(0, slash_pos); - //print_line("request string: "+request_string); } else { request_string = "/"; - //print_line("no request"); } - //print_line("3 url: "+url); - int colon_pos = url.find(":"); if (colon_pos != -1) { port = url.substr(colon_pos + 1, url.length()).to_int(); @@ -92,8 +86,6 @@ Error HTTPRequest::_parse_url(const String &p_url) { ERR_FAIL_COND_V(port < 1 || port > 65535, ERR_INVALID_PARAMETER); } - //print_line("4 url: "+url); - return OK; } @@ -198,10 +190,8 @@ void HTTPRequest::cancel_request() { } client->close(); body.resize(0); - //downloaded=0; got_response = false; response_code = -1; - //body_len=-1; request_sent = false; requesting = false; } @@ -221,12 +211,12 @@ bool HTTPRequest::_handle_response(bool *ret_value) { response_headers.resize(0); downloaded = 0; for (List<String>::Element *E = rheaders.front(); E; E = E->next()) { - //print_line("HEADER: "+E->get()); response_headers.push_back(E->get()); } if (response_code == 301 || response_code == 302) { - //redirect + // Handle redirect + if (max_redirects >= 0 && redirections >= max_redirects) { call_deferred("_request_done", RESULT_REDIRECT_LIMIT_REACHED, response_code, response_headers, PoolByteArray()); @@ -242,15 +232,13 @@ bool HTTPRequest::_handle_response(bool *ret_value) { } } - //print_line("NEW LOCATION: "+new_request); - if (new_request != "") { - //process redirect + // Process redirect client->close(); - int new_redirs = redirections + 1; //because _request() will clear it + int new_redirs = redirections + 1; // Because _request() will clear it Error err; if (new_request.begins_with("http")) { - //new url, request all again + // New url, request all again err = _parse_url(new_request); } else { request_string = new_request; @@ -258,7 +246,6 @@ bool HTTPRequest::_handle_response(bool *ret_value) { err = _request(); - //print_line("new connection: "+itos(err)); if (err == OK) { request_sent = false; got_response = false; @@ -280,11 +267,11 @@ bool HTTPRequest::_update_connection() { switch (client->get_status()) { case HTTPClient::STATUS_DISCONNECTED: { call_deferred("_request_done", RESULT_CANT_CONNECT, 0, PoolStringArray(), PoolByteArray()); - return true; //end it, since it's doing something + return true; // End it, since it's doing something } break; case HTTPClient::STATUS_RESOLVING: { client->poll(); - //must wait + // Must wait return false; } break; case HTTPClient::STATUS_CANT_RESOLVE: { @@ -294,9 +281,9 @@ bool HTTPRequest::_update_connection() { } break; case HTTPClient::STATUS_CONNECTING: { client->poll(); - //must wait + // Must wait return false; - } break; //connecting to ip + } break; // Connecting to IP case HTTPClient::STATUS_CANT_CONNECT: { call_deferred("_request_done", RESULT_CANT_CONNECT, 0, PoolStringArray(), PoolByteArray()); @@ -309,7 +296,7 @@ bool HTTPRequest::_update_connection() { if (!got_response) { - //no body + // No body bool ret_value; @@ -320,16 +307,16 @@ bool HTTPRequest::_update_connection() { return true; } if (got_response && body_len < 0) { - //chunked transfer is done + // Chunked transfer is done call_deferred("_request_done", RESULT_SUCCESS, response_code, response_headers, body); return true; } call_deferred("_request_done", RESULT_CHUNKED_BODY_SIZE_MISMATCH, response_code, response_headers, PoolByteArray()); return true; - //request migh have been done + // Request migh have been done } else { - //did not request yet, do request + // Did not request yet, do request Error err = client->request(method, request_string, headers, request_data); if (err != OK) { @@ -340,13 +327,13 @@ bool HTTPRequest::_update_connection() { request_sent = true; return false; } - } break; //connected: { } break requests only accepted here + } break; // Connected: break requests only accepted here case HTTPClient::STATUS_REQUESTING: { - //must wait, it's requesting + // Must wait, still requesting client->poll(); return false; - } break; // request in progress + } break; // Request in progress case HTTPClient::STATUS_BODY: { if (!got_response) { @@ -363,7 +350,7 @@ bool HTTPRequest::_update_connection() { } if (client->is_response_chunked()) { - body_len = -1; //no body len because chunked, change your webserver configuration if you want body len + body_len = -1; // No body len because chunked, change your webserver configuration if you want body len } else { body_len = client->get_response_body_length(); @@ -383,7 +370,6 @@ bool HTTPRequest::_update_connection() { } } - //print_line("BODY: "+itos(body.size())); client->poll(); PoolByteArray chunk = client->read_response_body_chunk(); @@ -411,15 +397,11 @@ bool HTTPRequest::_update_connection() { call_deferred("_request_done", RESULT_SUCCESS, response_code, response_headers, body); return true; } - /*if (body.size()>=body_len) { - call_deferred("_request_done",RESULT_BODY_SIZE_MISMATCH,response_code,response_headers,ByteArray()); - return true; - }*/ } return false; - } break; // request resulted in body: { } break which must be read + } break; // Request resulted in body: break which must be read case HTTPClient::STATUS_CONNECTION_ERROR: { call_deferred("_request_done", RESULT_CONNECTION_ERROR, 0, PoolStringArray(), PoolByteArray()); return true; @@ -449,7 +431,7 @@ void HTTPRequest::_notification(int p_what) { if (done) { set_process_internal(false); - //cancel_request(); called from _request done now + // cancel_request(); called from _request done now } } @@ -543,7 +525,7 @@ void HTTPRequest::_bind_methods() { ADD_PROPERTY(PropertyInfo(Variant::BOOL, "use_threads"), "set_use_threads", "is_using_threads"); ADD_PROPERTY(PropertyInfo(Variant::INT, "body_size_limit", PROPERTY_HINT_RANGE, "-1,2000000000"), "set_body_size_limit", "get_body_size_limit"); - ADD_PROPERTY(PropertyInfo(Variant::INT, "max_redirects", PROPERTY_HINT_RANGE, "-1,1024"), "set_max_redirects", "get_max_redirects"); + ADD_PROPERTY(PropertyInfo(Variant::INT, "max_redirects", PROPERTY_HINT_RANGE, "-1,64"), "set_max_redirects", "get_max_redirects"); ADD_SIGNAL(MethodInfo("request_completed", PropertyInfo(Variant::INT, "result"), PropertyInfo(Variant::INT, "response_code"), PropertyInfo(Variant::POOL_STRING_ARRAY, "headers"), PropertyInfo(Variant::POOL_BYTE_ARRAY, "body"))); diff --git a/scene/main/http_request.h b/scene/main/http_request.h index 790ff5f7ef..ab5a79c40d 100644 --- a/scene/main/http_request.h +++ b/scene/main/http_request.h @@ -42,7 +42,6 @@ class HTTPRequest : public Node { public: enum Result { RESULT_SUCCESS, - //RESULT_NO_BODY, RESULT_CHUNKED_BODY_SIZE_MISMATCH, RESULT_CANT_CONNECT, RESULT_CANT_RESOLVE, diff --git a/scene/main/node.cpp b/scene/main/node.cpp index efc5d269a6..af7a6bddd9 100644 --- a/scene/main/node.cpp +++ b/scene/main/node.cpp @@ -2110,6 +2110,7 @@ Node *Node::_duplicate(int p_flags, Map<const Node *, Node *> *r_duplimap) const StringName script_property_name = CoreStringNames::get_singleton()->_script; + List<const Node *> hidden_roots; List<const Node *> node_tree; node_tree.push_front(this); @@ -2120,11 +2121,16 @@ Node *Node::_duplicate(int p_flags, Map<const Node *, Node *> *r_duplimap) const for (List<const Node *>::Element *N = node_tree.front(); N; N = N->next()) { for (int i = 0; i < N->get()->get_child_count(); ++i) { + Node *descendant = N->get()->get_child(i); // Skip nodes not really belonging to the instanced hierarchy; they'll be processed normally later - if (N->get()->get_child(i)->data.owner != this) + // but remember non-instanced nodes that are hidden below instanced ones + if (descendant->data.owner != this) { + if (descendant->get_parent() && descendant->get_parent() != this && descendant->get_parent()->data.owner == this) + hidden_roots.push_back(descendant); continue; + } - node_tree.push_back(N->get()->get_child(i)); + node_tree.push_back(descendant); } } } @@ -2201,6 +2207,34 @@ Node *Node::_duplicate(int p_flags, Map<const Node *, Node *> *r_duplimap) const } node->add_child(dup); + if (i < node->get_child_count() - 1) { + node->move_child(dup, i); + } + } + + for (List<const Node *>::Element *E = hidden_roots.front(); E; E = E->next()) { + + Node *parent = node->get_node(get_path_to(E->get()->data.parent)); + if (!parent) { + + memdelete(node); + return NULL; + } + + Node *dup = E->get()->_duplicate(p_flags, r_duplimap); + if (!dup) { + + memdelete(node); + return NULL; + } + + parent->add_child(dup); + int pos = E->get()->get_position_in_parent(); + + if (pos < parent->get_child_count() - 1) { + + parent->move_child(dup, pos); + } } return node; diff --git a/scene/main/viewport.cpp b/scene/main/viewport.cpp index 4635de81e8..f5d7043a40 100644 --- a/scene/main/viewport.cpp +++ b/scene/main/viewport.cpp @@ -1421,7 +1421,7 @@ void Viewport::_gui_show_tooltip() { gui.tooltip_label->set_anchor_and_margin(MARGIN_TOP, Control::ANCHOR_BEGIN, ttp->get_margin(MARGIN_TOP)); gui.tooltip_label->set_anchor_and_margin(MARGIN_RIGHT, Control::ANCHOR_END, -ttp->get_margin(MARGIN_RIGHT)); gui.tooltip_label->set_anchor_and_margin(MARGIN_BOTTOM, Control::ANCHOR_END, -ttp->get_margin(MARGIN_BOTTOM)); - gui.tooltip_label->set_text(tooltip); + gui.tooltip_label->set_text(tooltip.strip_edges()); Rect2 r(gui.tooltip_pos + Point2(10, 10), gui.tooltip_label->get_combined_minimum_size() + ttp->get_minimum_size()); Rect2 vr = gui.tooltip_label->get_viewport_rect(); if (r.size.x + r.position.x > vr.size.x) diff --git a/scene/resources/packed_scene.cpp b/scene/resources/packed_scene.cpp index 3a5cb7da2e..879f76e6d8 100644 --- a/scene/resources/packed_scene.cpp +++ b/scene/resources/packed_scene.cpp @@ -270,6 +270,8 @@ Node *SceneState::instance(GenEditState p_edit_state) const { if (i > 0) { if (parent) { parent->_add_child_nocheck(node, snames[n.name]); + if (n.index >= 0 && n.index < parent->get_child_count() - 1) + parent->move_child(node, n.index); } else { //it may be possible that an instanced scene has changed //and the node has nowhere to go anymore @@ -386,6 +388,7 @@ Error SceneState::_parse_node(Node *p_owner, Node *p_node, int p_parent_idx, Map nd.name = _nm_get_string(p_node->get_name(), name_map); nd.instance = -1; //not instanced by default + nd.index = p_node->get_index(); // if this node is part of an instanced scene or sub-instanced scene // we need to get the corresponding instance states. @@ -1114,7 +1117,10 @@ void SceneState::set_bundled_scene(const Dictionary &p_dictionary) { nd.parent = r[idx++]; nd.owner = r[idx++]; nd.type = r[idx++]; - nd.name = r[idx++]; + uint32_t name_index = r[idx++]; + nd.name = name_index & ((1 << NAME_INDEX_BITS) - 1); + nd.index = (name_index >> NAME_INDEX_BITS); + nd.index--; //0 is invaild, stored as 1 nd.instance = r[idx++]; nd.properties.resize(r[idx++]); for (int j = 0; j < nd.properties.size(); j++) { @@ -1206,7 +1212,11 @@ Dictionary SceneState::get_bundled_scene() const { rnodes.push_back(nd.parent); rnodes.push_back(nd.owner); rnodes.push_back(nd.type); - rnodes.push_back(nd.name); + uint32_t name_index = nd.name; + if (nd.index < (1 << (32 - NAME_INDEX_BITS)) - 1) { //save if less than 16k childs + name_index |= uint32_t(nd.index + 1) << NAME_INDEX_BITS; //for backwards compatibility, index 0 is no index + } + rnodes.push_back(name_index); rnodes.push_back(nd.instance); rnodes.push_back(nd.properties.size()); for (int j = 0; j < nd.properties.size(); j++) { @@ -1284,6 +1294,11 @@ StringName SceneState::get_node_name(int p_idx) const { return names[nodes[p_idx].name]; } +int SceneState::get_node_index(int p_idx) const { + ERR_FAIL_INDEX_V(p_idx, nodes.size(), -1); + return nodes[p_idx].index; +} + bool SceneState::is_node_instance_placeholder(int p_idx) const { ERR_FAIL_INDEX_V(p_idx, nodes.size(), false); @@ -1524,7 +1539,7 @@ int SceneState::add_node_path(const NodePath &p_path) { node_paths.push_back(p_path); return (node_paths.size() - 1) | FLAG_ID_IS_PATH; } -int SceneState::add_node(int p_parent, int p_owner, int p_type, int p_name, int p_instance) { +int SceneState::add_node(int p_parent, int p_owner, int p_type, int p_name, int p_instance, int p_index) { NodeData nd; nd.parent = p_parent; @@ -1532,6 +1547,7 @@ int SceneState::add_node(int p_parent, int p_owner, int p_type, int p_name, int nd.type = p_type; nd.name = p_name; nd.instance = p_instance; + nd.index = p_index; nodes.push_back(nd); @@ -1605,6 +1621,7 @@ void SceneState::_bind_methods() { ClassDB::bind_method(D_METHOD("get_node_instance_placeholder", "idx"), &SceneState::get_node_instance_placeholder); ClassDB::bind_method(D_METHOD("get_node_instance", "idx"), &SceneState::get_node_instance); ClassDB::bind_method(D_METHOD("get_node_groups", "idx"), &SceneState::_get_node_groups); + ClassDB::bind_method(D_METHOD("get_node_index", "idx"), &SceneState::get_node_index); ClassDB::bind_method(D_METHOD("get_node_property_count", "idx"), &SceneState::get_node_property_count); ClassDB::bind_method(D_METHOD("get_node_property_name", "idx", "prop_idx"), &SceneState::get_node_property_name); ClassDB::bind_method(D_METHOD("get_node_property_value", "idx", "prop_idx"), &SceneState::get_node_property_value); diff --git a/scene/resources/packed_scene.h b/scene/resources/packed_scene.h index 20bfb19b1f..70deea24ff 100644 --- a/scene/resources/packed_scene.h +++ b/scene/resources/packed_scene.h @@ -48,6 +48,8 @@ class SceneState : public Reference { enum { NO_PARENT_SAVED = 0x7FFFFFFF, + NAME_INDEX_BITS = 18, + NAME_MASK = (1 << NAME_INDEX_BITS) - 1, }; struct NodeData { @@ -57,6 +59,7 @@ class SceneState : public Reference { int type; int name; int instance; + int index; struct Property { @@ -151,6 +154,7 @@ public: String get_node_instance_placeholder(int p_idx) const; bool is_node_instance_placeholder(int p_idx) const; Vector<StringName> get_node_groups(int p_idx) const; + int get_node_index(int p_idx) const; int get_node_property_count(int p_idx) const; StringName get_node_property_name(int p_idx, int p_prop) const; @@ -174,7 +178,7 @@ public: int find_name(const StringName &p_name) const; int add_value(const Variant &p_value); int add_node_path(const NodePath &p_path); - int add_node(int p_parent, int p_owner, int p_type, int p_name, int p_instance); + int add_node(int p_parent, int p_owner, int p_type, int p_name, int p_instance, int p_index); void add_node_property(int p_node, int p_name, int p_value); void add_node_group(int p_node, int p_group); void set_base_scene(int p_idx); diff --git a/scene/resources/scene_format_text.cpp b/scene/resources/scene_format_text.cpp index fe23fbf6b3..7bf5f24269 100644 --- a/scene/resources/scene_format_text.cpp +++ b/scene/resources/scene_format_text.cpp @@ -28,7 +28,7 @@ /* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ /*************************************************************************/ #include "scene_format_text.h" - +#include "core/io/resource_format_binary.h" #include "os/dir_access.h" #include "project_settings.h" #include "version.h" @@ -53,6 +53,60 @@ Ref<Resource> ResourceInteractiveLoaderText::get_resource() { return resource; } +Error ResourceInteractiveLoaderText::_parse_sub_resource_dummy(DummyReadData *p_data, VariantParser::Stream *p_stream, Ref<Resource> &r_res, int &line, String &r_err_str) { + + VariantParser::Token token; + VariantParser::get_token(p_stream, token, line, r_err_str); + if (token.type != VariantParser::TK_NUMBER) { + r_err_str = "Expected number (sub-resource index)"; + return ERR_PARSE_ERROR; + } + + int index = token.value; + + if (!p_data->resource_map.has(index)) { + Ref<DummyResource> dr; + dr.instance(); + dr->set_subindex(index); + p_data->resource_map[index] = dr; + p_data->resource_set.insert(dr); + } + + r_res = p_data->resource_map[index]; + + VariantParser::get_token(p_stream, token, line, r_err_str); + if (token.type != VariantParser::TK_PARENTHESIS_CLOSE) { + r_err_str = "Expected ')'"; + return ERR_PARSE_ERROR; + } + + return OK; +} + +Error ResourceInteractiveLoaderText::_parse_ext_resource_dummy(DummyReadData *p_data, VariantParser::Stream *p_stream, Ref<Resource> &r_res, int &line, String &r_err_str) { + + VariantParser::Token token; + VariantParser::get_token(p_stream, token, line, r_err_str); + if (token.type != VariantParser::TK_NUMBER) { + r_err_str = "Expected number (sub-resource index)"; + return ERR_PARSE_ERROR; + } + + int id = token.value; + + ERR_FAIL_COND_V(!p_data->rev_external_resources.has(id), ERR_PARSE_ERROR); + + r_res = p_data->rev_external_resources[id]; + + VariantParser::get_token(p_stream, token, line, r_err_str); + if (token.type != VariantParser::TK_PARENTHESIS_CLOSE) { + r_err_str = "Expected ')'"; + return ERR_PARSE_ERROR; + } + + return OK; +} + Error ResourceInteractiveLoaderText::_parse_sub_resource(VariantParser::Stream *p_stream, Ref<Resource> &r_res, int &line, String &r_err_str) { VariantParser::Token token; @@ -131,6 +185,208 @@ Error ResourceInteractiveLoaderText::_parse_ext_resource(VariantParser::Stream * return OK; } +Ref<PackedScene> ResourceInteractiveLoaderText::_parse_node_tag(VariantParser::ResourceParser &parser) { + Ref<PackedScene> packed_scene; + packed_scene.instance(); + + while (true) { + + if (next_tag.name == "node") { + + int parent = -1; + int owner = -1; + int type = -1; + int name = -1; + int instance = -1; + int index = -1; + //int base_scene=-1; + + if (next_tag.fields.has("name")) { + name = packed_scene->get_state()->add_name(next_tag.fields["name"]); + } + + if (next_tag.fields.has("parent")) { + NodePath np = next_tag.fields["parent"]; + np.prepend_period(); //compatible to how it manages paths internally + parent = packed_scene->get_state()->add_node_path(np); + } + + if (next_tag.fields.has("type")) { + type = packed_scene->get_state()->add_name(next_tag.fields["type"]); + } else { + type = SceneState::TYPE_INSTANCED; //no type? assume this was instanced + } + + if (next_tag.fields.has("instance")) { + + instance = packed_scene->get_state()->add_value(next_tag.fields["instance"]); + + if (packed_scene->get_state()->get_node_count() == 0 && parent == -1) { + packed_scene->get_state()->set_base_scene(instance); + instance = -1; + } + } + + if (next_tag.fields.has("instance_placeholder")) { + + String path = next_tag.fields["instance_placeholder"]; + + int path_v = packed_scene->get_state()->add_value(path); + + if (packed_scene->get_state()->get_node_count() == 0) { + error = ERR_FILE_CORRUPT; + error_text = "Instance Placeholder can't be used for inheritance."; + _printerr(); + return Ref<PackedScene>(); + } + + instance = path_v | SceneState::FLAG_INSTANCE_IS_PLACEHOLDER; + } + + if (next_tag.fields.has("owner")) { + owner = packed_scene->get_state()->add_node_path(next_tag.fields["owner"]); + } else { + if (parent != -1 && !(type == SceneState::TYPE_INSTANCED && instance == -1)) + owner = 0; //if no owner, owner is root + } + + if (next_tag.fields.has("index")) { + index = next_tag.fields["index"]; + } + + int node_id = packed_scene->get_state()->add_node(parent, owner, type, name, instance, index); + + if (next_tag.fields.has("groups")) { + + Array groups = next_tag.fields["groups"]; + for (int i = 0; i < groups.size(); i++) { + packed_scene->get_state()->add_node_group(node_id, packed_scene->get_state()->add_name(groups[i])); + } + } + + while (true) { + + String assign; + Variant value; + + error = VariantParser::parse_tag_assign_eof(&stream, lines, error_text, next_tag, assign, value, &parser); + + if (error) { + if (error != ERR_FILE_EOF) { + _printerr(); + return Ref<PackedScene>(); + } else { + return packed_scene; + } + } + + if (assign != String()) { + int nameidx = packed_scene->get_state()->add_name(assign); + int valueidx = packed_scene->get_state()->add_value(value); + packed_scene->get_state()->add_node_property(node_id, nameidx, valueidx); + //it's assignment + } else if (next_tag.name != String()) { + break; + } + } + } else if (next_tag.name == "connection") { + + if (!next_tag.fields.has("from")) { + error = ERR_FILE_CORRUPT; + error_text = "missing 'from' field fron connection tag"; + return Ref<PackedScene>(); + } + + if (!next_tag.fields.has("to")) { + error = ERR_FILE_CORRUPT; + error_text = "missing 'to' field fron connection tag"; + return Ref<PackedScene>(); + } + + if (!next_tag.fields.has("signal")) { + error = ERR_FILE_CORRUPT; + error_text = "missing 'signal' field fron connection tag"; + return Ref<PackedScene>(); + } + + if (!next_tag.fields.has("method")) { + error = ERR_FILE_CORRUPT; + error_text = "missing 'method' field fron connection tag"; + return Ref<PackedScene>(); + } + + NodePath from = next_tag.fields["from"]; + NodePath to = next_tag.fields["to"]; + StringName method = next_tag.fields["method"]; + StringName signal = next_tag.fields["signal"]; + int flags = CONNECT_PERSIST; + Array binds; + + if (next_tag.fields.has("flags")) { + flags = next_tag.fields["flags"]; + } + + if (next_tag.fields.has("binds")) { + binds = next_tag.fields["binds"]; + } + + Vector<int> bind_ints; + for (int i = 0; i < binds.size(); i++) { + bind_ints.push_back(packed_scene->get_state()->add_value(binds[i])); + } + + packed_scene->get_state()->add_connection( + packed_scene->get_state()->add_node_path(from.simplified()), + packed_scene->get_state()->add_node_path(to.simplified()), + packed_scene->get_state()->add_name(signal), + packed_scene->get_state()->add_name(method), + flags, + bind_ints); + + error = VariantParser::parse_tag(&stream, lines, error_text, next_tag, &parser); + + if (error) { + if (error != ERR_FILE_EOF) { + _printerr(); + return Ref<PackedScene>(); + } else { + return packed_scene; + } + } + } else if (next_tag.name == "editable") { + + if (!next_tag.fields.has("path")) { + error = ERR_FILE_CORRUPT; + error_text = "missing 'path' field fron connection tag"; + _printerr(); + return Ref<PackedScene>(); + } + + NodePath path = next_tag.fields["path"]; + + packed_scene->get_state()->add_editable_instance(path.simplified()); + + error = VariantParser::parse_tag(&stream, lines, error_text, next_tag, &parser); + + if (error) { + if (error != ERR_FILE_EOF) { + _printerr(); + return Ref<PackedScene>(); + } else { + return packed_scene; + } + } + } else { + + error = ERR_FILE_CORRUPT; + _printerr(); + return Ref<PackedScene>(); + } + } + + return packed_scene; +} + Error ResourceInteractiveLoaderText::poll() { if (error != OK) @@ -364,231 +620,21 @@ Error ResourceInteractiveLoaderText::poll() { return error; } - /* - int add_name(const StringName& p_name); - int add_value(const Variant& p_value); - int add_node_path(const NodePath& p_path); - int add_node(int p_parent,int p_owner,int p_type,int p_name, int p_instance); - void add_node_property(int p_node,int p_name,int p_value); - void add_node_group(int p_node,int p_group); - void set_base_scene(int p_idx); - void add_connection(int p_from,int p_to, int p_signal, int p_method, int p_flags,const Vector<int>& p_binds); - void add_editable_instance(const NodePath& p_path); - - */ - - int parent = -1; - int owner = -1; - int type = -1; - int name = -1; - int instance = -1; - //int base_scene=-1; - - if (next_tag.fields.has("name")) { - name = packed_scene->get_state()->add_name(next_tag.fields["name"]); - } - - if (next_tag.fields.has("parent")) { - NodePath np = next_tag.fields["parent"]; - np.prepend_period(); //compatible to how it manages paths internally - parent = packed_scene->get_state()->add_node_path(np); - } - - if (next_tag.fields.has("type")) { - type = packed_scene->get_state()->add_name(next_tag.fields["type"]); - } else { - type = SceneState::TYPE_INSTANCED; //no type? assume this was instanced - } - - if (next_tag.fields.has("instance")) { - - instance = packed_scene->get_state()->add_value(next_tag.fields["instance"]); - - if (packed_scene->get_state()->get_node_count() == 0 && parent == -1) { - packed_scene->get_state()->set_base_scene(instance); - instance = -1; - } - } - - if (next_tag.fields.has("instance_placeholder")) { - - String path = next_tag.fields["instance_placeholder"]; - - int path_v = packed_scene->get_state()->add_value(path); - - if (packed_scene->get_state()->get_node_count() == 0) { - error = ERR_FILE_CORRUPT; - error_text = "Instance Placeholder can't be used for inheritance."; - _printerr(); - return error; - } + Ref<PackedScene> packed_scene = _parse_node_tag(rp); - instance = path_v | SceneState::FLAG_INSTANCE_IS_PLACEHOLDER; - } - - if (next_tag.fields.has("owner")) { - owner = packed_scene->get_state()->add_node_path(next_tag.fields["owner"]); - } else { - if (parent != -1 && !(type == SceneState::TYPE_INSTANCED && instance == -1)) - owner = 0; //if no owner, owner is root - } - - int node_id = packed_scene->get_state()->add_node(parent, owner, type, name, instance); - - if (next_tag.fields.has("groups")) { - - Array groups = next_tag.fields["groups"]; - for (int i = 0; i < groups.size(); i++) { - packed_scene->get_state()->add_node_group(node_id, packed_scene->get_state()->add_name(groups[i])); - } - } - - while (true) { - - String assign; - Variant value; - - error = VariantParser::parse_tag_assign_eof(&stream, lines, error_text, next_tag, assign, value, &rp); - - if (error) { - if (error != ERR_FILE_EOF) { - _printerr(); - } else { - resource = packed_scene; - if (!ResourceCache::has(res_path)) { - packed_scene->set_path(res_path); - } - } - return error; - } - - if (assign != String()) { - int nameidx = packed_scene->get_state()->add_name(assign); - int valueidx = packed_scene->get_state()->add_value(value); - packed_scene->get_state()->add_node_property(node_id, nameidx, valueidx); - //it's assignment - } else if (next_tag.name != String()) { - - error = OK; - return error; - } else { - - resource = packed_scene; - error = ERR_FILE_EOF; - return error; - } - } - - return OK; - - } else if (next_tag.name == "connection") { - - if (!is_scene) { - - error_text += "found the 'connection' tag on a resource file!"; - _printerr(); - error = ERR_FILE_CORRUPT; + if (!packed_scene.is_valid()) return error; - } - if (!next_tag.fields.has("from")) { - error = ERR_FILE_CORRUPT; - error_text = "missing 'from' field fron connection tag"; - return error; + error = OK; + //get it here + resource = packed_scene; + if (!ResourceCache::has(res_path)) { + packed_scene->set_path(res_path); } - if (!next_tag.fields.has("to")) { - error = ERR_FILE_CORRUPT; - error_text = "missing 'to' field fron connection tag"; - return error; - } - - if (!next_tag.fields.has("signal")) { - error = ERR_FILE_CORRUPT; - error_text = "missing 'signal' field fron connection tag"; - return error; - } - - if (!next_tag.fields.has("method")) { - error = ERR_FILE_CORRUPT; - error_text = "missing 'method' field fron connection tag"; - return error; - } - - NodePath from = next_tag.fields["from"]; - NodePath to = next_tag.fields["to"]; - StringName method = next_tag.fields["method"]; - StringName signal = next_tag.fields["signal"]; - int flags = CONNECT_PERSIST; - Array binds; - - if (next_tag.fields.has("flags")) { - flags = next_tag.fields["flags"]; - } - - if (next_tag.fields.has("binds")) { - binds = next_tag.fields["binds"]; - } - - Vector<int> bind_ints; - for (int i = 0; i < binds.size(); i++) { - bind_ints.push_back(packed_scene->get_state()->add_value(binds[i])); - } - - packed_scene->get_state()->add_connection( - packed_scene->get_state()->add_node_path(from.simplified()), - packed_scene->get_state()->add_node_path(to.simplified()), - packed_scene->get_state()->add_name(signal), - packed_scene->get_state()->add_name(method), - flags, - bind_ints); - - error = VariantParser::parse_tag(&stream, lines, error_text, next_tag, &rp); - - if (error) { - if (error != ERR_FILE_EOF) { - _printerr(); - } else { - resource = packed_scene; - } - } - - return error; - } else if (next_tag.name == "editable") { - - if (!is_scene) { - - error_text += "found the 'editable' tag on a resource file!"; - _printerr(); - error = ERR_FILE_CORRUPT; - return error; - } - - if (!next_tag.fields.has("path")) { - error = ERR_FILE_CORRUPT; - error_text = "missing 'path' field fron connection tag"; - _printerr(); - return error; - } - - NodePath path = next_tag.fields["path"]; - - packed_scene->get_state()->add_editable_instance(path.simplified()); - - error = VariantParser::parse_tag(&stream, lines, error_text, next_tag, &rp); - - if (error) { - if (error != ERR_FILE_EOF) { - _printerr(); - } else { - resource = packed_scene; - } - } - - return error; + return ERR_FILE_EOF; } else { - error_text += "Unknown tag in file: " + next_tag.name; _printerr(); error = ERR_FILE_CORRUPT; @@ -804,7 +850,6 @@ void ResourceInteractiveLoaderText::open(FileAccess *p_f, bool p_skip_first_tag) if (tag.name == "gd_scene") { is_scene = true; - packed_scene.instance(); } else if (tag.name == "gd_resource") { if (!tag.fields.has("type")) { @@ -846,6 +891,281 @@ void ResourceInteractiveLoaderText::open(FileAccess *p_f, bool p_skip_first_tag) rp.userdata = this; } +static void bs_save_unicode_string(FileAccess *f, const String &p_string, bool p_bit_on_len = false) { + + CharString utf8 = p_string.utf8(); + if (p_bit_on_len) { + f->store_32(utf8.length() + 1 | 0x80000000); + } else { + f->store_32(utf8.length() + 1); + } + f->store_buffer((const uint8_t *)utf8.get_data(), utf8.length() + 1); +} + +Error ResourceInteractiveLoaderText::save_as_binary(FileAccess *p_f, const String &p_path) { + + if (error) + return error; + + FileAccessRef wf = FileAccess::open(p_path, FileAccess::WRITE); + if (!wf) { + return ERR_CANT_OPEN; + } + + //save header compressed + static const uint8_t header[4] = { 'R', 'S', 'R', 'C' }; + wf->store_buffer(header, 4); + + wf->store_32(0); //endianness, little endian + wf->store_32(0); //64 bits file, false for now + wf->store_32(VERSION_MAJOR); + wf->store_32(VERSION_MINOR); + static const int save_format_version = 3; //use format version 3 for saving + wf->store_32(save_format_version); + + bs_save_unicode_string(wf.f, is_scene ? "PackedScene" : resource_type); + wf->store_64(0); //offset to import metadata, this is no longer used + for (int i = 0; i < 14; i++) + wf->store_32(0); // reserved + + wf->store_32(0); //string table size, will not be in use + size_t ext_res_count_pos = wf->get_position(); + + wf->store_32(0); //zero ext resources, still parsing them + + //go with external resources + + DummyReadData dummy_read; + VariantParser::ResourceParser rp; + rp.ext_func = _parse_ext_resource_dummys; + rp.sub_func = _parse_sub_resource_dummys; + rp.userdata = &dummy_read; + + while (next_tag.name == "ext_resource") { + + if (!next_tag.fields.has("path")) { + error = ERR_FILE_CORRUPT; + error_text = "Missing 'path' in external resource tag"; + _printerr(); + return error; + } + + if (!next_tag.fields.has("type")) { + error = ERR_FILE_CORRUPT; + error_text = "Missing 'type' in external resource tag"; + _printerr(); + return error; + } + + if (!next_tag.fields.has("id")) { + error = ERR_FILE_CORRUPT; + error_text = "Missing 'id' in external resource tag"; + _printerr(); + return error; + } + + String path = next_tag.fields["path"]; + String type = next_tag.fields["type"]; + int index = next_tag.fields["id"]; + + bs_save_unicode_string(wf.f, type); + bs_save_unicode_string(wf.f, path); + + int lindex = dummy_read.external_resources.size(); + Ref<DummyResource> dr; + dr.instance(); + dr->set_path("res://dummy" + itos(lindex)); //anything is good to detect it for saving as external + dummy_read.external_resources[dr] = lindex; + dummy_read.rev_external_resources[index] = dr; + + error = VariantParser::parse_tag(&stream, lines, error_text, next_tag, &rp); + + if (error) { + _printerr(); + return error; + } + } + + // save external resource table + wf->seek(ext_res_count_pos); + wf->store_32(dummy_read.external_resources.size()); + wf->seek_end(); + + //now, save resources to a separate file, for now + + size_t sub_res_count_pos = wf->get_position(); + wf->store_32(0); //zero sub resources, still parsing them + + String temp_file = p_path + ".temp"; + FileAccessRef wf2 = FileAccess::open(temp_file, FileAccess::WRITE); + if (!wf2) { + return ERR_CANT_OPEN; + } + + Vector<size_t> local_offsets; + Vector<size_t> local_pointers_pos; + + while (next_tag.name == "sub_resource" || next_tag.name == "resource") { + + String type; + int id = -1; + bool main_res; + + if (next_tag.name == "sub_resource") { + if (!next_tag.fields.has("type")) { + error = ERR_FILE_CORRUPT; + error_text = "Missing 'type' in external resource tag"; + _printerr(); + return error; + } + + if (!next_tag.fields.has("id")) { + error = ERR_FILE_CORRUPT; + error_text = "Missing 'index' in external resource tag"; + _printerr(); + return error; + } + + type = next_tag.fields["type"]; + id = next_tag.fields["id"]; + main_res = false; + } else { + type = res_type; + id = 0; //used for last anyway + main_res = true; + } + + local_offsets.push_back(wf2->get_position()); + + bs_save_unicode_string(wf, "local://" + itos(id)); + local_pointers_pos.push_back(wf->get_position()); + wf->store_64(0); //temp local offset + + bs_save_unicode_string(wf2, type); + size_t propcount_ofs = wf2->get_position(); + wf2->store_32(0); + + int prop_count = 0; + + while (true) { + + String assign; + Variant value; + + error = VariantParser::parse_tag_assign_eof(&stream, lines, error_text, next_tag, assign, value, &rp); + + if (error) { + if (main_res && error == ERR_FILE_EOF) { + next_tag.name = ""; //exit + break; + } + + _printerr(); + return error; + } + + if (assign != String()) { + + Map<StringName, int> empty_string_map; //unused + bs_save_unicode_string(wf2, assign, true); + ResourceFormatSaverBinaryInstance::write_variant(wf2, value, dummy_read.resource_set, dummy_read.external_resources, empty_string_map); + prop_count++; + + } else if (next_tag.name != String()) { + + error = OK; + break; + } else { + error = ERR_FILE_CORRUPT; + error_text = "Premature end of file while parsing [sub_resource]"; + _printerr(); + return error; + } + } + + wf2->seek(propcount_ofs); + wf2->store_32(prop_count); + wf2->seek_end(); + } + + if (next_tag.name == "node") { + //this is a node, must save one more! + + if (!is_scene) { + + error_text += "found the 'node' tag on a resource file!"; + _printerr(); + error = ERR_FILE_CORRUPT; + return error; + } + + Ref<PackedScene> packed_scene = _parse_node_tag(rp); + + if (!packed_scene.is_valid()) + return error; + + error = OK; + //get it here + List<PropertyInfo> props; + packed_scene->get_property_list(&props); + + bs_save_unicode_string(wf, "local://0"); + local_pointers_pos.push_back(wf->get_position()); + wf->store_64(0); //temp local offset + + local_offsets.push_back(wf2->get_position()); + bs_save_unicode_string(wf2, "PackedScene"); + size_t propcount_ofs = wf2->get_position(); + wf2->store_32(0); + + int prop_count = 0; + + for (List<PropertyInfo>::Element *E = props.front(); E; E = E->next()) { + + if (!(E->get().usage & PROPERTY_USAGE_STORAGE)) + continue; + + String name = E->get().name; + Variant value = packed_scene->get(name); + + Map<StringName, int> empty_string_map; //unused + bs_save_unicode_string(wf2, name, true); + ResourceFormatSaverBinaryInstance::write_variant(wf2, value, dummy_read.resource_set, dummy_read.external_resources, empty_string_map); + prop_count++; + } + + wf2->seek(propcount_ofs); + wf2->store_32(prop_count); + wf2->seek_end(); + } + + wf2->close(); + + size_t offset_from = wf->get_position(); + wf->seek(sub_res_count_pos); //plus one because the saved one + wf->store_32(local_offsets.size()); + + for (int i = 0; i < local_offsets.size(); i++) { + wf->seek(local_pointers_pos[i]); + wf->store_64(local_offsets[i] + offset_from); + } + + wf->seek_end(); + + Vector<uint8_t> data = FileAccess::get_file_as_array(temp_file); + wf->store_buffer(data.ptr(), data.size()); + { + DirAccessRef dar = DirAccess::open(temp_file.get_base_dir()); + dar->remove(temp_file); + } + + wf->store_buffer((const uint8_t *)"RSRC", 4); //magic at end + + wf->close(); + + return OK; +} + String ResourceInteractiveLoaderText::recognize(FileAccess *p_f) { error = OK; @@ -991,6 +1311,25 @@ Error ResourceFormatLoaderText::rename_dependencies(const String &p_path, const return ria->rename_dependencies(f, p_path, p_map); } +Error ResourceFormatLoaderText::convert_file_to_binary(const String &p_src_path, const String &p_dst_path) { + + Error err; + FileAccess *f = FileAccess::open(p_src_path, FileAccess::READ, &err); + + if (err != OK) { + + ERR_FAIL_COND_V(err != OK, ERR_CANT_OPEN); + } + + Ref<ResourceInteractiveLoaderText> ria = memnew(ResourceInteractiveLoaderText); + String path = p_src_path; + ria->local_path = ProjectSettings::get_singleton()->localize_path(path); + ria->res_path = ria->local_path; + //ria->set_local_path( ProjectSettings::get_singleton()->localize_path(p_path) ); + ria->open(f); + return ria->save_as_binary(f, p_dst_path); +} + /*****************************************************************************************************/ /*****************************************************************************************************/ /*****************************************************************************************************/ @@ -1275,6 +1614,7 @@ Error ResourceFormatSaverTextInstance::save(const String &p_path, const RES &p_r StringName type = state->get_node_type(i); StringName name = state->get_node_name(i); + int index = state->get_node_index(i); NodePath path = state->get_node_path(i, true); NodePath owner = state->get_node_owner_path(i); Ref<PackedScene> instance = state->get_node_instance(i); @@ -1292,6 +1632,9 @@ Error ResourceFormatSaverTextInstance::save(const String &p_path, const RES &p_r if (owner != NodePath() && owner != NodePath(".")) { header += " owner=\"" + String(owner.simplified()) + "\""; } + if (index >= 0) { + header += " index=\"" + itos(index) + "\""; + } if (groups.size()) { String sgroups = " groups=[\n"; diff --git a/scene/resources/scene_format_text.h b/scene/resources/scene_format_text.h index a72a62037c..5d3c2004c1 100644 --- a/scene/resources/scene_format_text.h +++ b/scene/resources/scene_format_text.h @@ -78,9 +78,26 @@ class ResourceInteractiveLoaderText : public ResourceInteractiveLoader { Error _parse_sub_resource(VariantParser::Stream *p_stream, Ref<Resource> &r_res, int &line, String &r_err_str); Error _parse_ext_resource(VariantParser::Stream *p_stream, Ref<Resource> &r_res, int &line, String &r_err_str); - VariantParser::ResourceParser rp; + // for converter + class DummyResource : public Resource { + public: + }; - Ref<PackedScene> packed_scene; + struct DummyReadData { + + Map<RES, int> external_resources; + Map<int, RES> rev_external_resources; + Set<RES> resource_set; + Map<int, RES> resource_map; + }; + + static Error _parse_sub_resource_dummys(void *p_self, VariantParser::Stream *p_stream, Ref<Resource> &r_res, int &line, String &r_err_str) { return _parse_sub_resource_dummy((DummyReadData *)(p_self), p_stream, r_res, line, r_err_str); } + static Error _parse_ext_resource_dummys(void *p_self, VariantParser::Stream *p_stream, Ref<Resource> &r_res, int &line, String &r_err_str) { return _parse_ext_resource_dummy((DummyReadData *)(p_self), p_stream, r_res, line, r_err_str); } + + static Error _parse_sub_resource_dummy(DummyReadData *p_data, VariantParser::Stream *p_stream, Ref<Resource> &r_res, int &line, String &r_err_str); + static Error _parse_ext_resource_dummy(DummyReadData *p_data, VariantParser::Stream *p_stream, Ref<Resource> &r_res, int &line, String &r_err_str); + + VariantParser::ResourceParser rp; friend class ResourceFormatLoaderText; @@ -89,6 +106,8 @@ class ResourceInteractiveLoaderText : public ResourceInteractiveLoader { RES resource; + Ref<PackedScene> _parse_node_tag(VariantParser::ResourceParser &parser); + public: virtual void set_local_path(const String &p_local_path); virtual Ref<Resource> get_resource(); @@ -102,6 +121,7 @@ public: void get_dependencies(FileAccess *p_f, List<String> *p_dependencies, bool p_add_types); Error rename_dependencies(FileAccess *p_f, const String &p_path, const Map<String, String> &p_map); + Error save_as_binary(FileAccess *p_f, const String &p_path); ResourceInteractiveLoaderText(); ~ResourceInteractiveLoaderText(); }; @@ -115,6 +135,8 @@ public: virtual String get_resource_type(const String &p_path) const; virtual void get_dependencies(const String &p_path, List<String> *p_dependencies, bool p_add_types = false); virtual Error rename_dependencies(const String &p_path, const Map<String, String> &p_map); + + static Error convert_file_to_binary(const String &p_src_path, const String &p_dst_path); }; class ResourceFormatSaverTextInstance { diff --git a/servers/visual/shader_language.cpp b/servers/visual/shader_language.cpp index e10a57c571..c69bbb9343 100644 --- a/servers/visual/shader_language.cpp +++ b/servers/visual/shader_language.cpp @@ -755,12 +755,12 @@ void ShaderLanguage::clear() { } } -bool ShaderLanguage::_find_identifier(const BlockNode *p_block, const Map<StringName, DataType> &p_builtin_types, const StringName &p_identifier, DataType *r_data_type, IdentifierType *r_type) { +bool ShaderLanguage::_find_identifier(const BlockNode *p_block, const Map<StringName, BuiltInInfo> &p_builtin_types, const StringName &p_identifier, DataType *r_data_type, IdentifierType *r_type) { if (p_builtin_types.has(p_identifier)) { if (r_data_type) { - *r_data_type = p_builtin_types[p_identifier]; + *r_data_type = p_builtin_types[p_identifier].type; } if (r_type) { *r_type = IDENTIFIER_BUILTIN_VAR; @@ -2008,7 +2008,7 @@ bool ShaderLanguage::_validate_function_call(BlockNode *p_block, OperatorNode *p return false; } -bool ShaderLanguage::_parse_function_arguments(BlockNode *p_block, const Map<StringName, DataType> &p_builtin_types, OperatorNode *p_func, int *r_complete_arg) { +bool ShaderLanguage::_parse_function_arguments(BlockNode *p_block, const Map<StringName, BuiltInInfo> &p_builtin_types, OperatorNode *p_func, int *r_complete_arg) { TkPos pos = _get_tkpos(); Token tk = _get_token(); @@ -2261,7 +2261,48 @@ bool ShaderLanguage::_get_completable_identifier(BlockNode *p_block, CompletionT return false; } -ShaderLanguage::Node *ShaderLanguage::_parse_expression(BlockNode *p_block, const Map<StringName, DataType> &p_builtin_types) { +bool ShaderLanguage::_is_operator_assign(Operator p_op) const { + switch (p_op) { + case OP_ASSIGN: + case OP_ASSIGN_ADD: + case OP_ASSIGN_SUB: + case OP_ASSIGN_MUL: + case OP_ASSIGN_DIV: + case OP_ASSIGN_MOD: + case OP_ASSIGN_SHIFT_LEFT: + case OP_ASSIGN_SHIFT_RIGHT: + case OP_ASSIGN_BIT_AND: + case OP_ASSIGN_BIT_OR: + case OP_ASSIGN_BIT_XOR: + return true; + default: + return false; + } + + return false; +} + +bool ShaderLanguage::_validate_assign(Node *p_node, const Map<StringName, BuiltInInfo> &p_builtin_types) { + + if (p_node->type == Node::TYPE_OPERATOR) { + + OperatorNode *op = static_cast<OperatorNode *>(p_node); + if (op->type == OP_INDEX) { + return _validate_assign(op->arguments[0], p_builtin_types); + } + } + + if (p_node->type == Node::TYPE_VARIABLE) { + + VariableNode *var = static_cast<VariableNode *>(p_node); + if (p_builtin_types.has(var->name) && p_builtin_types[var->name].constant) { + return false; //ops not valid + } + } + return true; +} + +ShaderLanguage::Node *ShaderLanguage::_parse_expression(BlockNode *p_block, const Map<StringName, BuiltInInfo> &p_builtin_types) { Vector<Expression> expression; //Vector<TokenType> operators; @@ -2765,6 +2806,11 @@ ShaderLanguage::Node *ShaderLanguage::_parse_expression(BlockNode *p_block, cons _set_error("Invalid base type for increment/decrement operator"); return NULL; } + + if (!_validate_assign(expr, p_builtin_types)) { + _set_error("Invalid use of increment/decrement operator in constant expression."); + return NULL; + } expr = op; } else { @@ -2948,6 +2994,11 @@ ShaderLanguage::Node *ShaderLanguage::_parse_expression(BlockNode *p_block, cons OperatorNode *op = alloc_node<OperatorNode>(); op->op = expression[i].op; + if ((op->op == OP_INCREMENT || op->op == OP_DECREMENT) && !_validate_assign(expression[i + 1].node, p_builtin_types)) { + + _set_error("Can't use increment/decrement operator in constant expression."); + return NULL; + } op->arguments.push_back(expression[i + 1].node); expression[i].is_op = false; @@ -3019,6 +3070,12 @@ ShaderLanguage::Node *ShaderLanguage::_parse_expression(BlockNode *p_block, cons ERR_FAIL_V(NULL); } + if (_is_operator_assign(op->op) && !_validate_assign(expression[next_op - 1].node, p_builtin_types)) { + + _set_error("Assignment to constant expression."); + return NULL; + } + if (expression[next_op + 1].is_op) { // this is not invalid and can really appear // but it becomes invalid anyway because no binary op @@ -3142,7 +3199,7 @@ ShaderLanguage::Node *ShaderLanguage::_reduce_expression(BlockNode *p_block, Sha return p_node; } -ShaderLanguage::Node *ShaderLanguage::_parse_and_reduce_expression(BlockNode *p_block, const Map<StringName, DataType> &p_builtin_types) { +ShaderLanguage::Node *ShaderLanguage::_parse_and_reduce_expression(BlockNode *p_block, const Map<StringName, BuiltInInfo> &p_builtin_types) { ShaderLanguage::Node *expr = _parse_expression(p_block, p_builtin_types); if (!expr) //errored @@ -3153,7 +3210,7 @@ ShaderLanguage::Node *ShaderLanguage::_parse_and_reduce_expression(BlockNode *p_ return expr; } -Error ShaderLanguage::_parse_block(BlockNode *p_block, const Map<StringName, DataType> &p_builtin_types, bool p_just_one, bool p_can_break, bool p_can_continue) { +Error ShaderLanguage::_parse_block(BlockNode *p_block, const Map<StringName, BuiltInInfo> &p_builtin_types, bool p_just_one, bool p_can_break, bool p_can_continue) { while (true) { @@ -3636,7 +3693,7 @@ Error ShaderLanguage::_parse_shader(const Map<StringName, FunctionInfo> &p_funct name = tk.text; - if (_find_identifier(NULL, Map<StringName, DataType>(), name)) { + if (_find_identifier(NULL, Map<StringName, BuiltInInfo>(), name)) { _set_error("Redefinition of '" + String(name) + "'"); return ERR_PARSE_ERROR; } @@ -3660,7 +3717,7 @@ Error ShaderLanguage::_parse_shader(const Map<StringName, FunctionInfo> &p_funct tk = _get_token(); if (tk.type == TK_OP_ASSIGN) { - Node *expr = _parse_and_reduce_expression(NULL, Map<StringName, DataType>()); + Node *expr = _parse_and_reduce_expression(NULL, Map<StringName, BuiltInInfo>()); if (!expr) return ERR_PARSE_ERROR; if (expr->type != Node::TYPE_CONSTANT) { @@ -3841,7 +3898,7 @@ Error ShaderLanguage::_parse_shader(const Map<StringName, FunctionInfo> &p_funct return ERR_PARSE_ERROR; } - if (_find_identifier(NULL, Map<StringName, DataType>(), name)) { + if (_find_identifier(NULL, Map<StringName, BuiltInInfo>(), name)) { _set_error("Redefinition of '" + String(name) + "'"); return ERR_PARSE_ERROR; } @@ -3852,7 +3909,7 @@ Error ShaderLanguage::_parse_shader(const Map<StringName, FunctionInfo> &p_funct return ERR_PARSE_ERROR; } - Map<StringName, DataType> builtin_types; + Map<StringName, BuiltInInfo> builtin_types; if (p_functions.has(name)) { builtin_types = p_functions[name].built_ins; } @@ -4109,7 +4166,7 @@ Error ShaderLanguage::complete(const String &p_code, const Map<StringName, Funct if (comp_ident && skip_function != StringName() && p_functions.has(skip_function)) { - for (Map<StringName, DataType>::Element *E = p_functions[skip_function].built_ins.front(); E; E = E->next()) { + for (Map<StringName, BuiltInInfo>::Element *E = p_functions[skip_function].built_ins.front(); E; E = E->next()) { matches.insert(E->key()); } } diff --git a/servers/visual/shader_language.h b/servers/visual/shader_language.h index e092bf931f..4cf8560990 100644 --- a/servers/visual/shader_language.h +++ b/servers/visual/shader_language.h @@ -537,8 +537,18 @@ public: static void get_keyword_list(List<String> *r_keywords); static void get_builtin_funcs(List<String> *r_keywords); + struct BuiltInInfo { + DataType type; + bool constant; + BuiltInInfo() {} + BuiltInInfo(DataType p_type, bool p_constant = false) { + type = p_type; + constant = p_constant; + } + }; + struct FunctionInfo { - Map<StringName, DataType> built_ins; + Map<StringName, BuiltInInfo> built_ins; bool can_discard; }; @@ -601,7 +611,10 @@ private: IDENTIFIER_BUILTIN_VAR, }; - bool _find_identifier(const BlockNode *p_block, const Map<StringName, DataType> &p_builtin_types, const StringName &p_identifier, DataType *r_data_type = NULL, IdentifierType *r_type = NULL); + bool _find_identifier(const BlockNode *p_block, const Map<StringName, BuiltInInfo> &p_builtin_types, const StringName &p_identifier, DataType *r_data_type = NULL, IdentifierType *r_type = NULL); + + bool _is_operator_assign(Operator p_op) const; + bool _validate_assign(Node *p_node, const Map<StringName, BuiltInInfo> &p_builtin_types); bool _validate_operator(OperatorNode *p_op, DataType *r_ret_type = NULL); @@ -625,14 +638,14 @@ private: static const BuiltinFuncDef builtin_func_defs[]; bool _validate_function_call(BlockNode *p_block, OperatorNode *p_func, DataType *r_ret_type); - bool _parse_function_arguments(BlockNode *p_block, const Map<StringName, DataType> &p_builtin_types, OperatorNode *p_func, int *r_complete_arg = NULL); + bool _parse_function_arguments(BlockNode *p_block, const Map<StringName, BuiltInInfo> &p_builtin_types, OperatorNode *p_func, int *r_complete_arg = NULL); - Node *_parse_expression(BlockNode *p_block, const Map<StringName, DataType> &p_builtin_types); + Node *_parse_expression(BlockNode *p_block, const Map<StringName, BuiltInInfo> &p_builtin_types); ShaderLanguage::Node *_reduce_expression(BlockNode *p_block, ShaderLanguage::Node *p_node); - Node *_parse_and_reduce_expression(BlockNode *p_block, const Map<StringName, DataType> &p_builtin_types); + Node *_parse_and_reduce_expression(BlockNode *p_block, const Map<StringName, BuiltInInfo> &p_builtin_types); - Error _parse_block(BlockNode *p_block, const Map<StringName, DataType> &p_builtin_types, bool p_just_one = false, bool p_can_break = false, bool p_can_continue = false); + Error _parse_block(BlockNode *p_block, const Map<StringName, BuiltInInfo> &p_builtin_types, bool p_just_one = false, bool p_can_break = false, bool p_can_continue = false); Error _parse_shader(const Map<StringName, FunctionInfo> &p_functions, const Set<String> &p_render_modes, const Set<String> &p_shader_types); diff --git a/servers/visual/shader_types.cpp b/servers/visual/shader_types.cpp index 7489ca7e3e..a25c5ca65e 100644 --- a/servers/visual/shader_types.cpp +++ b/servers/visual/shader_types.cpp @@ -45,6 +45,11 @@ const Set<String> &ShaderTypes::get_types() { ShaderTypes *ShaderTypes::singleton = NULL; +static ShaderLanguage::BuiltInInfo constt(ShaderLanguage::DataType p_type) { + + return ShaderLanguage::BuiltInInfo(p_type, true); +} + ShaderTypes::ShaderTypes() { singleton = this; @@ -58,32 +63,32 @@ ShaderTypes::ShaderTypes() { shader_modes[VS::SHADER_SPATIAL].functions["vertex"].built_ins["UV2"] = ShaderLanguage::TYPE_VEC2; shader_modes[VS::SHADER_SPATIAL].functions["vertex"].built_ins["COLOR"] = ShaderLanguage::TYPE_VEC4; shader_modes[VS::SHADER_SPATIAL].functions["vertex"].built_ins["POINT_SIZE"] = ShaderLanguage::TYPE_FLOAT; - shader_modes[VS::SHADER_SPATIAL].functions["vertex"].built_ins["INSTANCE_ID"] = ShaderLanguage::TYPE_INT; - shader_modes[VS::SHADER_SPATIAL].functions["vertex"].built_ins["INSTANCE_CUSTOM"] = ShaderLanguage::TYPE_VEC4; + shader_modes[VS::SHADER_SPATIAL].functions["vertex"].built_ins["INSTANCE_ID"] = constt(ShaderLanguage::TYPE_INT); + shader_modes[VS::SHADER_SPATIAL].functions["vertex"].built_ins["INSTANCE_CUSTOM"] = constt(ShaderLanguage::TYPE_VEC4); shader_modes[VS::SHADER_SPATIAL].functions["vertex"].built_ins["ROUGHNESS"] = ShaderLanguage::TYPE_FLOAT; shader_modes[VS::SHADER_SPATIAL].functions["vertex"].can_discard = false; //builtins shader_modes[VS::SHADER_SPATIAL].functions["vertex"].built_ins["WORLD_MATRIX"] = ShaderLanguage::TYPE_MAT4; - shader_modes[VS::SHADER_SPATIAL].functions["vertex"].built_ins["INV_CAMERA_MATRIX"] = ShaderLanguage::TYPE_MAT4; - shader_modes[VS::SHADER_SPATIAL].functions["vertex"].built_ins["CAMERA_MATRIX"] = ShaderLanguage::TYPE_MAT4; + shader_modes[VS::SHADER_SPATIAL].functions["vertex"].built_ins["INV_CAMERA_MATRIX"] = constt(ShaderLanguage::TYPE_MAT4); + shader_modes[VS::SHADER_SPATIAL].functions["vertex"].built_ins["CAMERA_MATRIX"] = constt(ShaderLanguage::TYPE_MAT4); shader_modes[VS::SHADER_SPATIAL].functions["vertex"].built_ins["PROJECTION_MATRIX"] = ShaderLanguage::TYPE_MAT4; shader_modes[VS::SHADER_SPATIAL].functions["vertex"].built_ins["MODELVIEW_MATRIX"] = ShaderLanguage::TYPE_MAT4; shader_modes[VS::SHADER_SPATIAL].functions["vertex"].built_ins["INV_PROJECTION_MATRIX"] = ShaderLanguage::TYPE_MAT4; - shader_modes[VS::SHADER_SPATIAL].functions["vertex"].built_ins["TIME"] = ShaderLanguage::TYPE_FLOAT; - shader_modes[VS::SHADER_SPATIAL].functions["vertex"].built_ins["VIEWPORT_SIZE"] = ShaderLanguage::TYPE_VEC2; + shader_modes[VS::SHADER_SPATIAL].functions["vertex"].built_ins["TIME"] = constt(ShaderLanguage::TYPE_FLOAT); + shader_modes[VS::SHADER_SPATIAL].functions["vertex"].built_ins["VIEWPORT_SIZE"] = constt(ShaderLanguage::TYPE_VEC2); - shader_modes[VS::SHADER_SPATIAL].functions["fragment"].built_ins["VERTEX"] = ShaderLanguage::TYPE_VEC3; - shader_modes[VS::SHADER_SPATIAL].functions["fragment"].built_ins["FRAGCOORD"] = ShaderLanguage::TYPE_VEC4; - shader_modes[VS::SHADER_SPATIAL].functions["fragment"].built_ins["FRONT_FACING"] = ShaderLanguage::TYPE_BOOL; + shader_modes[VS::SHADER_SPATIAL].functions["fragment"].built_ins["VERTEX"] = constt(ShaderLanguage::TYPE_VEC3); + shader_modes[VS::SHADER_SPATIAL].functions["fragment"].built_ins["FRAGCOORD"] = constt(ShaderLanguage::TYPE_VEC4); + shader_modes[VS::SHADER_SPATIAL].functions["fragment"].built_ins["FRONT_FACING"] = constt(ShaderLanguage::TYPE_BOOL); shader_modes[VS::SHADER_SPATIAL].functions["fragment"].built_ins["NORMAL"] = ShaderLanguage::TYPE_VEC3; shader_modes[VS::SHADER_SPATIAL].functions["fragment"].built_ins["TANGENT"] = ShaderLanguage::TYPE_VEC3; shader_modes[VS::SHADER_SPATIAL].functions["fragment"].built_ins["BINORMAL"] = ShaderLanguage::TYPE_VEC3; shader_modes[VS::SHADER_SPATIAL].functions["fragment"].built_ins["NORMALMAP"] = ShaderLanguage::TYPE_VEC3; shader_modes[VS::SHADER_SPATIAL].functions["fragment"].built_ins["NORMALMAP_DEPTH"] = ShaderLanguage::TYPE_FLOAT; - shader_modes[VS::SHADER_SPATIAL].functions["fragment"].built_ins["UV"] = ShaderLanguage::TYPE_VEC2; - shader_modes[VS::SHADER_SPATIAL].functions["fragment"].built_ins["UV2"] = ShaderLanguage::TYPE_VEC2; - shader_modes[VS::SHADER_SPATIAL].functions["fragment"].built_ins["COLOR"] = ShaderLanguage::TYPE_VEC4; + shader_modes[VS::SHADER_SPATIAL].functions["fragment"].built_ins["UV"] = constt(ShaderLanguage::TYPE_VEC2); + shader_modes[VS::SHADER_SPATIAL].functions["fragment"].built_ins["UV2"] = constt(ShaderLanguage::TYPE_VEC2); + shader_modes[VS::SHADER_SPATIAL].functions["fragment"].built_ins["COLOR"] = constt(ShaderLanguage::TYPE_VEC4); shader_modes[VS::SHADER_SPATIAL].functions["fragment"].built_ins["ALBEDO"] = ShaderLanguage::TYPE_VEC3; shader_modes[VS::SHADER_SPATIAL].functions["fragment"].built_ins["ALPHA"] = ShaderLanguage::TYPE_FLOAT; shader_modes[VS::SHADER_SPATIAL].functions["fragment"].built_ins["METALLIC"] = ShaderLanguage::TYPE_FLOAT; @@ -103,33 +108,33 @@ ShaderTypes::ShaderTypes() { shader_modes[VS::SHADER_SPATIAL].functions["fragment"].built_ins["SCREEN_TEXTURE"] = ShaderLanguage::TYPE_SAMPLER2D; shader_modes[VS::SHADER_SPATIAL].functions["fragment"].built_ins["DEPTH_TEXTURE"] = ShaderLanguage::TYPE_SAMPLER2D; shader_modes[VS::SHADER_SPATIAL].functions["fragment"].built_ins["SCREEN_UV"] = ShaderLanguage::TYPE_VEC2; - shader_modes[VS::SHADER_SPATIAL].functions["fragment"].built_ins["POINT_COORD"] = ShaderLanguage::TYPE_VEC2; - shader_modes[VS::SHADER_SPATIAL].functions["fragment"].built_ins["SIDE"] = ShaderLanguage::TYPE_FLOAT; + shader_modes[VS::SHADER_SPATIAL].functions["fragment"].built_ins["POINT_COORD"] = constt(ShaderLanguage::TYPE_VEC2); + shader_modes[VS::SHADER_SPATIAL].functions["fragment"].built_ins["SIDE"] = constt(ShaderLanguage::TYPE_FLOAT); shader_modes[VS::SHADER_SPATIAL].functions["fragment"].built_ins["ALPHA_SCISSOR"] = ShaderLanguage::TYPE_FLOAT; - shader_modes[VS::SHADER_SPATIAL].functions["fragment"].built_ins["WORLD_MATRIX"] = ShaderLanguage::TYPE_MAT4; - shader_modes[VS::SHADER_SPATIAL].functions["fragment"].built_ins["INV_CAMERA_MATRIX"] = ShaderLanguage::TYPE_MAT4; - shader_modes[VS::SHADER_SPATIAL].functions["fragment"].built_ins["PROJECTION_MATRIX"] = ShaderLanguage::TYPE_MAT4; - shader_modes[VS::SHADER_SPATIAL].functions["fragment"].built_ins["INV_PROJECTION_MATRIX"] = ShaderLanguage::TYPE_MAT4; - shader_modes[VS::SHADER_SPATIAL].functions["fragment"].built_ins["TIME"] = ShaderLanguage::TYPE_FLOAT; - shader_modes[VS::SHADER_SPATIAL].functions["fragment"].built_ins["VIEWPORT_SIZE"] = ShaderLanguage::TYPE_VEC2; + shader_modes[VS::SHADER_SPATIAL].functions["fragment"].built_ins["WORLD_MATRIX"] = constt(ShaderLanguage::TYPE_MAT4); + shader_modes[VS::SHADER_SPATIAL].functions["fragment"].built_ins["INV_CAMERA_MATRIX"] = constt(ShaderLanguage::TYPE_MAT4); + shader_modes[VS::SHADER_SPATIAL].functions["fragment"].built_ins["PROJECTION_MATRIX"] = constt(ShaderLanguage::TYPE_MAT4); + shader_modes[VS::SHADER_SPATIAL].functions["fragment"].built_ins["INV_PROJECTION_MATRIX"] = constt(ShaderLanguage::TYPE_MAT4); + shader_modes[VS::SHADER_SPATIAL].functions["fragment"].built_ins["TIME"] = constt(ShaderLanguage::TYPE_FLOAT); + shader_modes[VS::SHADER_SPATIAL].functions["fragment"].built_ins["VIEWPORT_SIZE"] = constt(ShaderLanguage::TYPE_VEC2); shader_modes[VS::SHADER_SPATIAL].functions["fragment"].can_discard = true; - shader_modes[VS::SHADER_SPATIAL].functions["light"].built_ins["WORLD_MATRIX"] = ShaderLanguage::TYPE_MAT4; - shader_modes[VS::SHADER_SPATIAL].functions["light"].built_ins["INV_CAMERA_MATRIX"] = ShaderLanguage::TYPE_MAT4; - shader_modes[VS::SHADER_SPATIAL].functions["light"].built_ins["PROJECTION_MATRIX"] = ShaderLanguage::TYPE_MAT4; - shader_modes[VS::SHADER_SPATIAL].functions["light"].built_ins["INV_PROJECTION_MATRIX"] = ShaderLanguage::TYPE_MAT4; - shader_modes[VS::SHADER_SPATIAL].functions["light"].built_ins["TIME"] = ShaderLanguage::TYPE_FLOAT; - shader_modes[VS::SHADER_SPATIAL].functions["light"].built_ins["VIEWPORT_SIZE"] = ShaderLanguage::TYPE_VEC2; - - shader_modes[VS::SHADER_SPATIAL].functions["light"].built_ins["NORMAL"] = ShaderLanguage::TYPE_VEC3; - shader_modes[VS::SHADER_SPATIAL].functions["light"].built_ins["VIEW"] = ShaderLanguage::TYPE_VEC3; - shader_modes[VS::SHADER_SPATIAL].functions["light"].built_ins["LIGHT"] = ShaderLanguage::TYPE_VEC3; - shader_modes[VS::SHADER_SPATIAL].functions["light"].built_ins["LIGHT_COLOR"] = ShaderLanguage::TYPE_VEC3; - shader_modes[VS::SHADER_SPATIAL].functions["light"].built_ins["ATTENUATION"] = ShaderLanguage::TYPE_VEC3; - shader_modes[VS::SHADER_SPATIAL].functions["light"].built_ins["ALBEDO"] = ShaderLanguage::TYPE_VEC3; - shader_modes[VS::SHADER_SPATIAL].functions["light"].built_ins["TRANSMISSION"] = ShaderLanguage::TYPE_VEC3; - shader_modes[VS::SHADER_SPATIAL].functions["light"].built_ins["ROUGHNESS"] = ShaderLanguage::TYPE_FLOAT; + shader_modes[VS::SHADER_SPATIAL].functions["light"].built_ins["WORLD_MATRIX"] = constt(ShaderLanguage::TYPE_MAT4); + shader_modes[VS::SHADER_SPATIAL].functions["light"].built_ins["INV_CAMERA_MATRIX"] = constt(ShaderLanguage::TYPE_MAT4); + shader_modes[VS::SHADER_SPATIAL].functions["light"].built_ins["PROJECTION_MATRIX"] = constt(ShaderLanguage::TYPE_MAT4); + shader_modes[VS::SHADER_SPATIAL].functions["light"].built_ins["INV_PROJECTION_MATRIX"] = constt(ShaderLanguage::TYPE_MAT4); + shader_modes[VS::SHADER_SPATIAL].functions["light"].built_ins["TIME"] = constt(ShaderLanguage::TYPE_FLOAT); + shader_modes[VS::SHADER_SPATIAL].functions["light"].built_ins["VIEWPORT_SIZE"] = constt(ShaderLanguage::TYPE_VEC2); + + shader_modes[VS::SHADER_SPATIAL].functions["light"].built_ins["NORMAL"] = constt(ShaderLanguage::TYPE_VEC3); + shader_modes[VS::SHADER_SPATIAL].functions["light"].built_ins["VIEW"] = constt(ShaderLanguage::TYPE_VEC3); + shader_modes[VS::SHADER_SPATIAL].functions["light"].built_ins["LIGHT"] = constt(ShaderLanguage::TYPE_VEC3); + shader_modes[VS::SHADER_SPATIAL].functions["light"].built_ins["LIGHT_COLOR"] = constt(ShaderLanguage::TYPE_VEC3); + shader_modes[VS::SHADER_SPATIAL].functions["light"].built_ins["ATTENUATION"] = constt(ShaderLanguage::TYPE_VEC3); + shader_modes[VS::SHADER_SPATIAL].functions["light"].built_ins["ALBEDO"] = constt(ShaderLanguage::TYPE_VEC3); + shader_modes[VS::SHADER_SPATIAL].functions["light"].built_ins["TRANSMISSION"] = constt(ShaderLanguage::TYPE_VEC3); + shader_modes[VS::SHADER_SPATIAL].functions["light"].built_ins["ROUGHNESS"] = constt(ShaderLanguage::TYPE_FLOAT); shader_modes[VS::SHADER_SPATIAL].functions["light"].built_ins["DIFFUSE_LIGHT"] = ShaderLanguage::TYPE_VEC3; shader_modes[VS::SHADER_SPATIAL].functions["light"].built_ins["SPECULAR_LIGHT"] = ShaderLanguage::TYPE_VEC3; @@ -177,38 +182,38 @@ ShaderTypes::ShaderTypes() { shader_modes[VS::SHADER_CANVAS_ITEM].functions["vertex"].built_ins["COLOR"] = ShaderLanguage::TYPE_VEC4; shader_modes[VS::SHADER_CANVAS_ITEM].functions["vertex"].built_ins["POINT_SIZE"] = ShaderLanguage::TYPE_FLOAT; - shader_modes[VS::SHADER_CANVAS_ITEM].functions["vertex"].built_ins["WORLD_MATRIX"] = ShaderLanguage::TYPE_MAT4; - shader_modes[VS::SHADER_CANVAS_ITEM].functions["vertex"].built_ins["PROJECTION_MATRIX"] = ShaderLanguage::TYPE_MAT4; - shader_modes[VS::SHADER_CANVAS_ITEM].functions["vertex"].built_ins["EXTRA_MATRIX"] = ShaderLanguage::TYPE_MAT4; - shader_modes[VS::SHADER_CANVAS_ITEM].functions["vertex"].built_ins["TIME"] = ShaderLanguage::TYPE_FLOAT; - shader_modes[VS::SHADER_CANVAS_ITEM].functions["vertex"].built_ins["INSTANCE_CUSTOM"] = ShaderLanguage::TYPE_VEC4; - shader_modes[VS::SHADER_CANVAS_ITEM].functions["vertex"].built_ins["AT_LIGHT_PASS"] = ShaderLanguage::TYPE_BOOL; + shader_modes[VS::SHADER_CANVAS_ITEM].functions["vertex"].built_ins["WORLD_MATRIX"] = constt(ShaderLanguage::TYPE_MAT4); + shader_modes[VS::SHADER_CANVAS_ITEM].functions["vertex"].built_ins["PROJECTION_MATRIX"] = constt(ShaderLanguage::TYPE_MAT4); + shader_modes[VS::SHADER_CANVAS_ITEM].functions["vertex"].built_ins["EXTRA_MATRIX"] = constt(ShaderLanguage::TYPE_MAT4); + shader_modes[VS::SHADER_CANVAS_ITEM].functions["vertex"].built_ins["TIME"] = constt(ShaderLanguage::TYPE_FLOAT); + shader_modes[VS::SHADER_CANVAS_ITEM].functions["vertex"].built_ins["INSTANCE_CUSTOM"] = constt(ShaderLanguage::TYPE_VEC4); + shader_modes[VS::SHADER_CANVAS_ITEM].functions["vertex"].built_ins["AT_LIGHT_PASS"] = constt(ShaderLanguage::TYPE_BOOL); shader_modes[VS::SHADER_CANVAS_ITEM].functions["vertex"].can_discard = false; - shader_modes[VS::SHADER_CANVAS_ITEM].functions["fragment"].built_ins["FRAGCOORD"] = ShaderLanguage::TYPE_VEC4; + shader_modes[VS::SHADER_CANVAS_ITEM].functions["fragment"].built_ins["FRAGCOORD"] = constt(ShaderLanguage::TYPE_VEC4); shader_modes[VS::SHADER_CANVAS_ITEM].functions["fragment"].built_ins["NORMAL"] = ShaderLanguage::TYPE_VEC3; shader_modes[VS::SHADER_CANVAS_ITEM].functions["fragment"].built_ins["NORMALMAP"] = ShaderLanguage::TYPE_VEC3; shader_modes[VS::SHADER_CANVAS_ITEM].functions["fragment"].built_ins["NORMALMAP_DEPTH"] = ShaderLanguage::TYPE_FLOAT; - shader_modes[VS::SHADER_CANVAS_ITEM].functions["fragment"].built_ins["UV"] = ShaderLanguage::TYPE_VEC2; + shader_modes[VS::SHADER_CANVAS_ITEM].functions["fragment"].built_ins["UV"] = constt(ShaderLanguage::TYPE_VEC2); shader_modes[VS::SHADER_CANVAS_ITEM].functions["fragment"].built_ins["COLOR"] = ShaderLanguage::TYPE_VEC4; - shader_modes[VS::SHADER_CANVAS_ITEM].functions["fragment"].built_ins["TEXTURE"] = ShaderLanguage::TYPE_SAMPLER2D; - shader_modes[VS::SHADER_CANVAS_ITEM].functions["fragment"].built_ins["TEXTURE_PIXEL_SIZE"] = ShaderLanguage::TYPE_VEC2; - shader_modes[VS::SHADER_CANVAS_ITEM].functions["fragment"].built_ins["NORMAL_TEXTURE"] = ShaderLanguage::TYPE_SAMPLER2D; - shader_modes[VS::SHADER_CANVAS_ITEM].functions["fragment"].built_ins["SCREEN_UV"] = ShaderLanguage::TYPE_VEC2; - shader_modes[VS::SHADER_CANVAS_ITEM].functions["fragment"].built_ins["SCREEN_PIXEL_SIZE"] = ShaderLanguage::TYPE_VEC2; - shader_modes[VS::SHADER_CANVAS_ITEM].functions["fragment"].built_ins["POINT_COORD"] = ShaderLanguage::TYPE_VEC2; - shader_modes[VS::SHADER_CANVAS_ITEM].functions["fragment"].built_ins["TIME"] = ShaderLanguage::TYPE_FLOAT; - shader_modes[VS::SHADER_CANVAS_ITEM].functions["fragment"].built_ins["AT_LIGHT_PASS"] = ShaderLanguage::TYPE_BOOL; - shader_modes[VS::SHADER_CANVAS_ITEM].functions["fragment"].built_ins["SCREEN_TEXTURE"] = ShaderLanguage::TYPE_SAMPLER2D; + shader_modes[VS::SHADER_CANVAS_ITEM].functions["fragment"].built_ins["TEXTURE"] = constt(ShaderLanguage::TYPE_SAMPLER2D); + shader_modes[VS::SHADER_CANVAS_ITEM].functions["fragment"].built_ins["TEXTURE_PIXEL_SIZE"] = constt(ShaderLanguage::TYPE_VEC2); + shader_modes[VS::SHADER_CANVAS_ITEM].functions["fragment"].built_ins["NORMAL_TEXTURE"] = constt(ShaderLanguage::TYPE_SAMPLER2D); + shader_modes[VS::SHADER_CANVAS_ITEM].functions["fragment"].built_ins["SCREEN_UV"] = constt(ShaderLanguage::TYPE_VEC2); + shader_modes[VS::SHADER_CANVAS_ITEM].functions["fragment"].built_ins["SCREEN_PIXEL_SIZE"] = constt(ShaderLanguage::TYPE_VEC2); + shader_modes[VS::SHADER_CANVAS_ITEM].functions["fragment"].built_ins["POINT_COORD"] = constt(ShaderLanguage::TYPE_VEC2); + shader_modes[VS::SHADER_CANVAS_ITEM].functions["fragment"].built_ins["TIME"] = constt(ShaderLanguage::TYPE_FLOAT); + shader_modes[VS::SHADER_CANVAS_ITEM].functions["fragment"].built_ins["AT_LIGHT_PASS"] = constt(ShaderLanguage::TYPE_BOOL); + shader_modes[VS::SHADER_CANVAS_ITEM].functions["fragment"].built_ins["SCREEN_TEXTURE"] = constt(ShaderLanguage::TYPE_SAMPLER2D); shader_modes[VS::SHADER_CANVAS_ITEM].functions["fragment"].can_discard = true; - shader_modes[VS::SHADER_CANVAS_ITEM].functions["light"].built_ins["POSITION"] = ShaderLanguage::TYPE_VEC2; - shader_modes[VS::SHADER_CANVAS_ITEM].functions["light"].built_ins["NORMAL"] = ShaderLanguage::TYPE_VEC3; - shader_modes[VS::SHADER_CANVAS_ITEM].functions["light"].built_ins["UV"] = ShaderLanguage::TYPE_VEC2; - shader_modes[VS::SHADER_CANVAS_ITEM].functions["light"].built_ins["COLOR"] = ShaderLanguage::TYPE_VEC4; - shader_modes[VS::SHADER_CANVAS_ITEM].functions["light"].built_ins["TEXTURE"] = ShaderLanguage::TYPE_SAMPLER2D; - shader_modes[VS::SHADER_CANVAS_ITEM].functions["light"].built_ins["TEXTURE_PIXEL_SIZE"] = ShaderLanguage::TYPE_VEC2; - shader_modes[VS::SHADER_CANVAS_ITEM].functions["light"].built_ins["SCREEN_UV"] = ShaderLanguage::TYPE_VEC2; + shader_modes[VS::SHADER_CANVAS_ITEM].functions["light"].built_ins["POSITION"] = constt(ShaderLanguage::TYPE_VEC2); + shader_modes[VS::SHADER_CANVAS_ITEM].functions["light"].built_ins["NORMAL"] = constt(ShaderLanguage::TYPE_VEC3); + shader_modes[VS::SHADER_CANVAS_ITEM].functions["light"].built_ins["UV"] = constt(ShaderLanguage::TYPE_VEC2); + shader_modes[VS::SHADER_CANVAS_ITEM].functions["light"].built_ins["COLOR"] = constt(ShaderLanguage::TYPE_VEC4); + shader_modes[VS::SHADER_CANVAS_ITEM].functions["light"].built_ins["TEXTURE"] = constt(ShaderLanguage::TYPE_SAMPLER2D); + shader_modes[VS::SHADER_CANVAS_ITEM].functions["light"].built_ins["TEXTURE_PIXEL_SIZE"] = constt(ShaderLanguage::TYPE_VEC2); + shader_modes[VS::SHADER_CANVAS_ITEM].functions["light"].built_ins["SCREEN_UV"] = constt(ShaderLanguage::TYPE_VEC2); shader_modes[VS::SHADER_CANVAS_ITEM].functions["light"].built_ins["LIGHT_VEC"] = ShaderLanguage::TYPE_VEC2; shader_modes[VS::SHADER_CANVAS_ITEM].functions["light"].built_ins["LIGHT_HEIGHT"] = ShaderLanguage::TYPE_FLOAT; shader_modes[VS::SHADER_CANVAS_ITEM].functions["light"].built_ins["LIGHT_COLOR"] = ShaderLanguage::TYPE_VEC4; @@ -216,8 +221,8 @@ ShaderTypes::ShaderTypes() { shader_modes[VS::SHADER_CANVAS_ITEM].functions["light"].built_ins["LIGHT_SHADOW"] = ShaderLanguage::TYPE_VEC4; shader_modes[VS::SHADER_CANVAS_ITEM].functions["light"].built_ins["LIGHT"] = ShaderLanguage::TYPE_VEC4; shader_modes[VS::SHADER_CANVAS_ITEM].functions["light"].built_ins["SHADOW"] = ShaderLanguage::TYPE_VEC4; - shader_modes[VS::SHADER_CANVAS_ITEM].functions["light"].built_ins["POINT_COORD"] = ShaderLanguage::TYPE_VEC2; - shader_modes[VS::SHADER_CANVAS_ITEM].functions["light"].built_ins["TIME"] = ShaderLanguage::TYPE_FLOAT; + shader_modes[VS::SHADER_CANVAS_ITEM].functions["light"].built_ins["POINT_COORD"] = constt(ShaderLanguage::TYPE_VEC2); + shader_modes[VS::SHADER_CANVAS_ITEM].functions["light"].built_ins["TIME"] = constt(ShaderLanguage::TYPE_FLOAT); shader_modes[VS::SHADER_CANVAS_ITEM].functions["light"].can_discard = true; shader_modes[VS::SHADER_CANVAS_ITEM].modes.insert("skip_vertex_transform"); @@ -237,16 +242,16 @@ ShaderTypes::ShaderTypes() { shader_modes[VS::SHADER_PARTICLES].functions["vertex"].built_ins["VELOCITY"] = ShaderLanguage::TYPE_VEC3; shader_modes[VS::SHADER_PARTICLES].functions["vertex"].built_ins["MASS"] = ShaderLanguage::TYPE_FLOAT; shader_modes[VS::SHADER_PARTICLES].functions["vertex"].built_ins["ACTIVE"] = ShaderLanguage::TYPE_BOOL; - shader_modes[VS::SHADER_PARTICLES].functions["vertex"].built_ins["RESTART"] = ShaderLanguage::TYPE_BOOL; + shader_modes[VS::SHADER_PARTICLES].functions["vertex"].built_ins["RESTART"] = constt(ShaderLanguage::TYPE_BOOL); shader_modes[VS::SHADER_PARTICLES].functions["vertex"].built_ins["CUSTOM"] = ShaderLanguage::TYPE_VEC4; shader_modes[VS::SHADER_PARTICLES].functions["vertex"].built_ins["TRANSFORM"] = ShaderLanguage::TYPE_MAT4; - shader_modes[VS::SHADER_PARTICLES].functions["vertex"].built_ins["TIME"] = ShaderLanguage::TYPE_FLOAT; - shader_modes[VS::SHADER_PARTICLES].functions["vertex"].built_ins["LIFETIME"] = ShaderLanguage::TYPE_FLOAT; - shader_modes[VS::SHADER_PARTICLES].functions["vertex"].built_ins["DELTA"] = ShaderLanguage::TYPE_FLOAT; - shader_modes[VS::SHADER_PARTICLES].functions["vertex"].built_ins["NUMBER"] = ShaderLanguage::TYPE_UINT; - shader_modes[VS::SHADER_PARTICLES].functions["vertex"].built_ins["INDEX"] = ShaderLanguage::TYPE_INT; - shader_modes[VS::SHADER_PARTICLES].functions["vertex"].built_ins["EMISSION_TRANSFORM"] = ShaderLanguage::TYPE_MAT4; - shader_modes[VS::SHADER_PARTICLES].functions["vertex"].built_ins["RANDOM_SEED"] = ShaderLanguage::TYPE_UINT; + shader_modes[VS::SHADER_PARTICLES].functions["vertex"].built_ins["TIME"] = constt(ShaderLanguage::TYPE_FLOAT); + shader_modes[VS::SHADER_PARTICLES].functions["vertex"].built_ins["LIFETIME"] = constt(ShaderLanguage::TYPE_FLOAT); + shader_modes[VS::SHADER_PARTICLES].functions["vertex"].built_ins["DELTA"] = constt(ShaderLanguage::TYPE_FLOAT); + shader_modes[VS::SHADER_PARTICLES].functions["vertex"].built_ins["NUMBER"] = constt(ShaderLanguage::TYPE_UINT); + shader_modes[VS::SHADER_PARTICLES].functions["vertex"].built_ins["INDEX"] = constt(ShaderLanguage::TYPE_INT); + shader_modes[VS::SHADER_PARTICLES].functions["vertex"].built_ins["EMISSION_TRANSFORM"] = constt(ShaderLanguage::TYPE_MAT4); + shader_modes[VS::SHADER_PARTICLES].functions["vertex"].built_ins["RANDOM_SEED"] = constt(ShaderLanguage::TYPE_UINT); shader_modes[VS::SHADER_PARTICLES].functions["vertex"].can_discard = false; shader_modes[VS::SHADER_PARTICLES].modes.insert("billboard"); diff --git a/servers/visual/visual_server_raster.cpp b/servers/visual/visual_server_raster.cpp index 6b527b5cd1..7bb7d04fcd 100644 --- a/servers/visual/visual_server_raster.cpp +++ b/servers/visual/visual_server_raster.cpp @@ -181,6 +181,10 @@ void VisualServerRaster::set_debug_generate_wireframes(bool p_generate) { VSG::storage->set_debug_generate_wireframes(p_generate); } +void VisualServerRaster::call_set_use_vsync(bool p_enable) { + OS::get_singleton()->_set_use_vsync(p_enable); +} + VisualServerRaster::VisualServerRaster() { VSG::canvas = memnew(VisualServerCanvas); diff --git a/servers/visual/visual_server_raster.h b/servers/visual/visual_server_raster.h index a0e79e9d3e..716c1754e1 100644 --- a/servers/visual/visual_server_raster.h +++ b/servers/visual/visual_server_raster.h @@ -668,6 +668,8 @@ public: virtual bool has_os_feature(const String &p_feature) const; virtual void set_debug_generate_wireframes(bool p_generate); + virtual void call_set_use_vsync(bool p_enable); + VisualServerRaster(); ~VisualServerRaster(); diff --git a/servers/visual/visual_server_wrap_mt.cpp b/servers/visual/visual_server_wrap_mt.cpp index b86a0ae3f6..e55b7a9309 100644 --- a/servers/visual/visual_server_wrap_mt.cpp +++ b/servers/visual/visual_server_wrap_mt.cpp @@ -158,9 +158,19 @@ void VisualServerWrapMT::finish() { canvas_occluder_polygon_free_cached_ids(); } +void VisualServerWrapMT::set_use_vsync_callback(bool p_enable) { + + singleton_mt->call_set_use_vsync(p_enable); +} + +VisualServerWrapMT *VisualServerWrapMT::singleton_mt = NULL; + VisualServerWrapMT::VisualServerWrapMT(VisualServer *p_contained, bool p_create_thread) : command_queue(p_create_thread) { + singleton_mt = this; + OS::switch_vsync_function = set_use_vsync_callback; //as this goes to another thread, make sure it goes properly + visual_server = p_contained; create_thread = p_create_thread; thread = NULL; diff --git a/servers/visual/visual_server_wrap_mt.h b/servers/visual/visual_server_wrap_mt.h index cb6f67474e..0f24521f5d 100644 --- a/servers/visual/visual_server_wrap_mt.h +++ b/servers/visual/visual_server_wrap_mt.h @@ -64,6 +64,8 @@ class VisualServerWrapMT : public VisualServer { //#define DEBUG_SYNC + static VisualServerWrapMT *singleton_mt; + #ifdef DEBUG_SYNC #define SYNC_DEBUG print_line("sync on: " + String(__FUNCTION__)); #else @@ -584,6 +586,10 @@ public: virtual bool has_feature(Features p_feature) const { return visual_server->has_feature(p_feature); } virtual bool has_os_feature(const String &p_feature) const { return visual_server->has_os_feature(p_feature); } + FUNC1(call_set_use_vsync, bool) + + static void set_use_vsync_callback(bool p_enable); + VisualServerWrapMT(VisualServer *p_contained, bool p_create_thread); ~VisualServerWrapMT(); diff --git a/servers/visual_server.cpp b/servers/visual_server.cpp index 153cff2f22..42ecb82a46 100644 --- a/servers/visual_server.cpp +++ b/servers/visual_server.cpp @@ -1820,6 +1820,7 @@ void VisualServer::_bind_methods() { BIND_ENUM_CONSTANT(INSTANCE_LIGHT); BIND_ENUM_CONSTANT(INSTANCE_REFLECTION_PROBE); BIND_ENUM_CONSTANT(INSTANCE_GI_PROBE); + BIND_ENUM_CONSTANT(INSTANCE_LIGHTMAP_CAPTURE); BIND_ENUM_CONSTANT(INSTANCE_MAX); BIND_ENUM_CONSTANT(INSTANCE_GEOMETRY_MASK); @@ -1921,6 +1922,7 @@ VisualServer::VisualServer() { //ERR_FAIL_COND(singleton); singleton = this; + GLOBAL_DEF("rendering/vram_compression/import_s3tc", true); GLOBAL_DEF("rendering/vram_compression/import_etc", false); GLOBAL_DEF("rendering/vram_compression/import_etc2", true); diff --git a/servers/visual_server.h b/servers/visual_server.h index ad4d32b967..23354c3d37 100644 --- a/servers/visual_server.h +++ b/servers/visual_server.h @@ -751,7 +751,6 @@ public: INSTANCE_GI_PROBE, INSTANCE_LIGHTMAP_CAPTURE, INSTANCE_MAX, - /*INSTANCE_BAKED_LIGHT_SAMPLER,*/ INSTANCE_GEOMETRY_MASK = (1 << INSTANCE_MESH) | (1 << INSTANCE_MULTIMESH) | (1 << INSTANCE_IMMEDIATE) | (1 << INSTANCE_PARTICLES) }; @@ -981,6 +980,8 @@ public: virtual void set_debug_generate_wireframes(bool p_generate) = 0; + virtual void call_set_use_vsync(bool p_enable) = 0; + VisualServer(); virtual ~VisualServer(); }; diff --git a/thirdparty/README.md b/thirdparty/README.md index fbce76fcc7..62690e21c7 100644 --- a/thirdparty/README.md +++ b/thirdparty/README.md @@ -62,8 +62,8 @@ Use UI font if exists, because it has tight vertical metrics and good for UI. ### Hack Regular - Upstream: https://github.com/source-foundry/Hack -- Version: 2.020 -- License: Hack Open Font License v2.0 +- Version: 3.000 +- License: MIT + Bitstream Vera License ### DroidSans*.ttf @@ -272,7 +272,7 @@ Collection of single-file libraries used in Godot components. ### poshlib - Upstream: http://poshlib.hookatooka.com/poshlib/trac.cgi (username guest, password guest123) -- Version: 1.3.002 +- Version: 1.3.002 - License: MIT Files extracted from the upstream source: @@ -308,6 +308,10 @@ Files extracted from the upstream source: - Relevant sources from src/ - License.txt +Important: Some files have Godot-made changes, those +changes are marked with `// -- GODOT --` comments. + + ## nanosvg - Upstream: https://github.com/memononen/nanosvg @@ -361,6 +365,7 @@ Files extracted from upstream source: - celt/ and silk/ subfolders - COPYING + ## pcre2 - Upstream: http://www.pcre.org/ @@ -374,6 +379,7 @@ Files extracted from upstream source: - src/pcre2_jit_*.c and src/sljit/* - AUTHORS and COPYING + ## pvrtccompressor - Upstream: https://bitbucket.org/jthlim/pvrtccompressor @@ -385,12 +391,14 @@ Files extracted from upstream source: - all .cpp and .h files apart from `main.cpp` - LICENSE.TXT + ## recastnavigation - Upstream: https://github.com/recastnavigation/recastnavigation - version: git commit ef3ea40f - 2016-02-06 - License: zlib + ## rtaudio - Upstream: http://www.music.mcgill.ca/~gary/rtaudio/ @@ -412,6 +420,10 @@ Files extracted from upstream source: - all .cpp, .h and .inl files +Important: Some files have Godot-made changes. +They are marked with `// -- GODOT start --` and `// -- GODOT end --` +comments and a patch is provided in the squish/ folder. + ## tinyexr diff --git a/thirdparty/fonts/Hack_Regular.ttf b/thirdparty/fonts/Hack_Regular.ttf Binary files differindex a35ea2e4f4..f342700811 100644 --- a/thirdparty/fonts/Hack_Regular.ttf +++ b/thirdparty/fonts/Hack_Regular.ttf diff --git a/thirdparty/fonts/LICENSE_Hack.md b/thirdparty/fonts/LICENSE_Hack.md index e9fc8a1f87..ddd23a2b81 100644 --- a/thirdparty/fonts/LICENSE_Hack.md +++ b/thirdparty/fonts/LICENSE_Hack.md @@ -1,49 +1,30 @@ -## License +The work in the Hack project is Copyright 2017 Source Foundry Authors and licensed under the MIT License -Hack Copyright 2015, Christopher Simpkins with Reserved Font Name "Hack". +The work in the DejaVu project was committed to the public domain. Bitstream Vera Sans Mono Copyright 2003 Bitstream Inc. and licensed under the Bitstream Vera License with Reserved Font Names "Bitstream" and "Vera" -DejaVu modifications of the original Bitstream Vera Sans Mono typeface have been committed to the public domain. +### MIT License +Copyright (c) 2017 Source Foundry Authors +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: -This Font Software is licensed under the Hack Open Font License v2.0 and the Bitstream Vera License. - -These licenses are copied below. - - -### Hack Open Font License v2.0 - -(Version 1.0 - 06 September 2015) - -(Version 2.0 - 27 September 2015) - -Copyright 2015 by Christopher Simpkins. All Rights Reserved. - -DEFINITIONS - -"Author" refers to any designer, engineer, programmer, technical writer or other person who contributed to the Font Software. - -PERMISSION AND CONDITIONS - -Permission is hereby granted, free of charge, to any person obtaining a copy of the fonts accompanying this license ("Fonts") and associated source code, documentation, and binary files (the "Font Software"), to reproduce and distribute the modifications to the Bitstream Vera Font Software, including without limitation the rights to use, study, copy, merge, embed, modify, redistribute, and/or sell modified or unmodified copies of the Font Software, and to permit persons to whom the Font Software is furnished to do so, subject to the following conditions: - -(1) The above copyright notice and this permission notice shall be included in all modified and unmodified copies of the Font Software typefaces. These notices can be included either as stand-alone text files, human-readable headers or in the appropriate machine-readable metadata fields within text or binary files as long as those fields can be easily viewed by the user. - -(2) The Font Software may be modified, altered, or added to, and in particular the designs of glyphs or characters in the Fonts may be modified and additional glyphs or characters may be added to the Fonts, only if the fonts are renamed to names not containing the word "Hack". - -(3) Neither the Font Software nor any of its individual components, in original or modified versions, may be sold by itself. - -TERMINATION - -This license becomes null and void if any of the above conditions are not met. - -THE FONT SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO ANY WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT OF COPYRIGHT, PATENT, TRADEMARK, OR OTHER RIGHT. IN NO EVENT SHALL THE COPYRIGHT HOLDER BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, INCLUDING ANY GENERAL, SPECIAL, INDIRECT, INCIDENTAL, OR CONSEQUENTIAL DAMAGES, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF THE USE OR INABILITY TO USE THE FONT SOFTWARE OR FROM OTHER DEALINGS IN THE FONT SOFTWARE. - -Except as contained in this notice, the names of Christopher Simpkins and the Author(s) of the Font Software shall not be used to promote, endorse or advertise any modified version, except to acknowledge the contribution(s) of Christopher Simpkins and the Author(s) or with their explicit written permission. For further information, contact: chris at sourcefoundry dot org. - +The above copyright notice and this permission notice shall be included in all +copies or substantial portions of the Software. +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +SOFTWARE. ### BITSTREAM VERA LICENSE diff --git a/thirdparty/squish/Add-Decompress-Bc5-to-Squish.patch b/thirdparty/squish/Add-Decompress-Bc5-to-Squish.patch new file mode 100644 index 0000000000..1e06a8d318 --- /dev/null +++ b/thirdparty/squish/Add-Decompress-Bc5-to-Squish.patch @@ -0,0 +1,143 @@ +From 7b64cc4c8b0be0443741483bf65909f5140179c0 Mon Sep 17 00:00:00 2001 +From: Orkun <orkuntezerm@gmail.com> +Date: Sun, 19 Nov 2017 02:24:31 +0300 +Subject: [PATCH] Fix #12220: Add Decompress Bc5 to Squish + +This Commit fixes the corrupted file preview described in #12220. +Added DecompressColourBc5 function to squish. +--- + thirdparty/squish/colourblock.cpp | 85 +++++++++++++++++++++++++++++++++++++++ + thirdparty/squish/colourblock.h | 3 ++ + thirdparty/squish/squish.cpp | 8 +++- + 3 files changed, 95 insertions(+), 1 deletion(-) + +diff --git a/thirdparty/squish/colourblock.cpp b/thirdparty/squish/colourblock.cpp +index af8b98036..3de46382c 100644 +--- a/thirdparty/squish/colourblock.cpp ++++ b/thirdparty/squish/colourblock.cpp +@@ -211,4 +211,89 @@ void DecompressColour( u8* rgba, void const* block, bool isDxt1 ) + } + } + ++// -- Godot start -- ++void DecompressColourBc5( u8* rgba, void const* block) ++{ ++ // get the block bytes ++ u8 const* bytes = reinterpret_cast< u8 const* >( block ); ++ ++ // unpack the endpoints ++ u8 codes[16]; ++ int red_0 = bytes[0]; ++ int red_1 = bytes[1]; ++ ++ codes[0] = red_0; ++ codes[1] = red_1; ++ codes[6] = 0.0f; ++ codes[7] = 1.0f; ++ // generate the midpoints ++ if(red_0 > red_1) ++ { ++ for( int i = 2; i < 8; ++i ) ++ { ++ codes[i] = ((8-i)*red_0 + (i-1)*red_1)/7; ++ } ++ } ++ else ++ { ++ for( int i = 2; i < 6; ++i ) ++ { ++ codes[i] = ((6-i)*red_0 + (i-1)*red_1)/5; ++ } ++ } ++ ++ int green_0 = bytes[8]; ++ int green_1 = bytes[9]; ++ ++ codes[0 + 8] = green_0; ++ codes[1 + 8] = green_1; ++ codes[6 + 8] = 0.0f; ++ codes[7 + 8] = 1.0f; ++ // generate the midpoints ++ if(green_0 > green_1) ++ { ++ for( int i = 2; i < 8; ++i ) ++ { ++ codes[i + 8] = ((8-i)*green_0 + (i-1)*green_1)/7; ++ } ++ } ++ else ++ { ++ for( int i = 2; i < 6; ++i ) ++ { ++ codes[i + 8] = ((6-i)*green_0 + (i-1)*green_1)/5; ++ } ++ } ++ ++ u8 indices[32]; ++ for( int i = 0; i < 4; ++i ) ++ { ++ u8 packed = bytes[2 + i]; ++ u8* red_ind = indices + 4*i; ++ ++ red_ind[0] = packed & 0x3; ++ red_ind[1] = ( packed >> 2 ) & 0x3; ++ red_ind[2] = ( packed >> 4 ) & 0x3; ++ red_ind[3] = ( packed >> 6 ) & 0x3; ++ ++ packed = bytes[8 + i]; ++ u8* green_ind = indices + 4*i + 16; ++ green_ind[0] = packed & 0x3; ++ green_ind[1] = ( packed >> 2 ) & 0x3; ++ green_ind[2] = ( packed >> 4 ) & 0x3; ++ green_ind[3] = ( packed >> 6 ) & 0x3; ++ } ++ ++ // store out the colours ++ for( int i = 0; i < 16; ++i ) ++ { ++ rgba[4*i] = codes[indices[i]]; ++ rgba[4*i +1] = codes[indices[i + 16] + 8]; ++ rgba[4*i +2] = 0; ++ rgba[4*i +3] = 255; ++ } ++} ++// -- GODOT end -- ++ ++ + } // namespace squish +diff --git a/thirdparty/squish/colourblock.h b/thirdparty/squish/colourblock.h +index fee2cd7c5..3cb9b7e3b 100644 +--- a/thirdparty/squish/colourblock.h ++++ b/thirdparty/squish/colourblock.h +@@ -35,6 +35,9 @@ void WriteColourBlock3( Vec3::Arg start, Vec3::Arg end, u8 const* indices, void* + void WriteColourBlock4( Vec3::Arg start, Vec3::Arg end, u8 const* indices, void* block ); + + void DecompressColour( u8* rgba, void const* block, bool isDxt1 ); ++// -- GODOT start -- ++void DecompressColourBc5( u8* rgba, void const* block ); ++// -- GODOT end -- + + } // namespace squish + +diff --git a/thirdparty/squish/squish.cpp b/thirdparty/squish/squish.cpp +index 1d22a64ad..fd11a147d 100644 +--- a/thirdparty/squish/squish.cpp ++++ b/thirdparty/squish/squish.cpp +@@ -135,7 +135,13 @@ void Decompress( u8* rgba, void const* block, int flags ) + colourBlock = reinterpret_cast< u8 const* >( block ) + 8; + + // decompress colour +- DecompressColour( rgba, colourBlock, ( flags & kDxt1 ) != 0 ); ++ // -- GODOT start -- ++ //DecompressColour( rgba, colourBlock, ( flags & kDxt1 ) != 0 ); ++ if(( flags & ( kBc5 ) ) != 0) ++ DecompressColourBc5( rgba, colourBlock); ++ else ++ DecompressColour( rgba, colourBlock, ( flags & kDxt1 ) != 0 ); ++ // -- GODOT end -- + + // decompress alpha separately if necessary + if( ( flags & kDxt3 ) != 0 ) +-- +2.13.6 + diff --git a/thirdparty/squish/colourblock.cpp b/thirdparty/squish/colourblock.cpp index af8b980365..3de46382c0 100644 --- a/thirdparty/squish/colourblock.cpp +++ b/thirdparty/squish/colourblock.cpp @@ -211,4 +211,89 @@ void DecompressColour( u8* rgba, void const* block, bool isDxt1 ) } } +// -- Godot start -- +void DecompressColourBc5( u8* rgba, void const* block) +{ + // get the block bytes + u8 const* bytes = reinterpret_cast< u8 const* >( block ); + + // unpack the endpoints + u8 codes[16]; + int red_0 = bytes[0]; + int red_1 = bytes[1]; + + codes[0] = red_0; + codes[1] = red_1; + codes[6] = 0.0f; + codes[7] = 1.0f; + // generate the midpoints + if(red_0 > red_1) + { + for( int i = 2; i < 8; ++i ) + { + codes[i] = ((8-i)*red_0 + (i-1)*red_1)/7; + } + } + else + { + for( int i = 2; i < 6; ++i ) + { + codes[i] = ((6-i)*red_0 + (i-1)*red_1)/5; + } + } + + int green_0 = bytes[8]; + int green_1 = bytes[9]; + + codes[0 + 8] = green_0; + codes[1 + 8] = green_1; + codes[6 + 8] = 0.0f; + codes[7 + 8] = 1.0f; + // generate the midpoints + if(green_0 > green_1) + { + for( int i = 2; i < 8; ++i ) + { + codes[i + 8] = ((8-i)*green_0 + (i-1)*green_1)/7; + } + } + else + { + for( int i = 2; i < 6; ++i ) + { + codes[i + 8] = ((6-i)*green_0 + (i-1)*green_1)/5; + } + } + + u8 indices[32]; + for( int i = 0; i < 4; ++i ) + { + u8 packed = bytes[2 + i]; + u8* red_ind = indices + 4*i; + + red_ind[0] = packed & 0x3; + red_ind[1] = ( packed >> 2 ) & 0x3; + red_ind[2] = ( packed >> 4 ) & 0x3; + red_ind[3] = ( packed >> 6 ) & 0x3; + + packed = bytes[8 + i]; + u8* green_ind = indices + 4*i + 16; + green_ind[0] = packed & 0x3; + green_ind[1] = ( packed >> 2 ) & 0x3; + green_ind[2] = ( packed >> 4 ) & 0x3; + green_ind[3] = ( packed >> 6 ) & 0x3; + } + + // store out the colours + for( int i = 0; i < 16; ++i ) + { + rgba[4*i] = codes[indices[i]]; + rgba[4*i +1] = codes[indices[i + 16] + 8]; + rgba[4*i +2] = 0; + rgba[4*i +3] = 255; + } +} +// -- GODOT end -- + + } // namespace squish diff --git a/thirdparty/squish/colourblock.h b/thirdparty/squish/colourblock.h index fee2cd7c5d..3cb9b7e3b9 100644 --- a/thirdparty/squish/colourblock.h +++ b/thirdparty/squish/colourblock.h @@ -35,6 +35,9 @@ void WriteColourBlock3( Vec3::Arg start, Vec3::Arg end, u8 const* indices, void* void WriteColourBlock4( Vec3::Arg start, Vec3::Arg end, u8 const* indices, void* block ); void DecompressColour( u8* rgba, void const* block, bool isDxt1 ); +// -- GODOT start -- +void DecompressColourBc5( u8* rgba, void const* block ); +// -- GODOT end -- } // namespace squish diff --git a/thirdparty/squish/squish.cpp b/thirdparty/squish/squish.cpp index 1d22a64ad6..fd11a147de 100644 --- a/thirdparty/squish/squish.cpp +++ b/thirdparty/squish/squish.cpp @@ -135,7 +135,13 @@ void Decompress( u8* rgba, void const* block, int flags ) colourBlock = reinterpret_cast< u8 const* >( block ) + 8; // decompress colour - DecompressColour( rgba, colourBlock, ( flags & kDxt1 ) != 0 ); + // -- GODOT start -- + //DecompressColour( rgba, colourBlock, ( flags & kDxt1 ) != 0 ); + if(( flags & ( kBc5 ) ) != 0) + DecompressColourBc5( rgba, colourBlock); + else + DecompressColour( rgba, colourBlock, ( flags & kDxt1 ) != 0 ); + // -- GODOT end -- // decompress alpha separately if necessary if( ( flags & kDxt3 ) != 0 ) diff --git a/thirdparty/thekla_atlas/nvcore/Debug.cpp b/thirdparty/thekla_atlas/nvcore/Debug.cpp index 113c551de8..4980ffa916 100644 --- a/thirdparty/thekla_atlas/nvcore/Debug.cpp +++ b/thirdparty/thekla_atlas/nvcore/Debug.cpp @@ -14,6 +14,7 @@ # define VC_EXTRALEAN # include <windows.h> # include <direct.h> +// -- GODOT start - # include <crtdbg.h> # if _MSC_VER < 1300 # define DECLSPEC_DEPRECATED @@ -24,6 +25,7 @@ // VC7: ships with updated headers # include <dbghelp.h> # endif +// -- GODOT end - # pragma comment(lib,"dbghelp.lib") #endif @@ -107,8 +109,9 @@ namespace #endif - +// -- GODOT start - #if NV_OS_WIN32 || NV_OS_DURANGO +// -- GODOT end - // We should try to simplify the top level filter as much as possible. // http://www.nynaeve.net/?p=128 @@ -391,8 +394,10 @@ namespace #pragma warning(disable:4748) static NV_NOINLINE int backtrace(void * trace[], int maxcount) { CONTEXT ctx = { 0 }; +// -- GODOT start -- #if NV_CPU_X86 && !NV_CPU_X86_64 ctx.ContextFlags = CONTEXT_CONTROL; +#if NV_CC_MSVC _asm { call x x: pop eax @@ -401,6 +406,13 @@ namespace mov ctx.Esp, esp } #else + register long unsigned int ebp asm("ebp"); + ctx.Eip = (DWORD) __builtin_return_address(0); + ctx.Ebp = ebp; + ctx.Esp = (DWORD) __builtin_frame_address(0); +#endif +// -- GODOT end -- +#else RtlCaptureContext(&ctx); // Not implemented correctly in x86. #endif diff --git a/thirdparty/thekla_atlas/nvcore/DefsGnucWin32.h b/thirdparty/thekla_atlas/nvcore/DefsGnucWin32.h index 4f97b90f3a..e1c8d6e4f8 100644 --- a/thirdparty/thekla_atlas/nvcore/DefsGnucWin32.h +++ b/thirdparty/thekla_atlas/nvcore/DefsGnucWin32.h @@ -19,7 +19,9 @@ #endif #define NV_FASTCALL __attribute__((fastcall)) +// -- GODOT start - #define NV_FORCEINLINE __attribute__((always_inline)) inline +// -- GODOT end - #define NV_DEPRECATED __attribute__((deprecated)) #if __GNUC__ > 2 diff --git a/thirdparty/thekla_atlas/nvmath/ftoi.h b/thirdparty/thekla_atlas/nvmath/ftoi.h index bee15c0908..182c56d1c3 100644 --- a/thirdparty/thekla_atlas/nvmath/ftoi.h +++ b/thirdparty/thekla_atlas/nvmath/ftoi.h @@ -53,7 +53,10 @@ namespace nv return (val<0) ? ftoi_ceil_xs(val) : ftoi_floor_xs(val); } -#if NV_CPU_X86 || NV_CPU_X86_64 +// -- GODOT start -- +//#if NV_CPU_X86 || NV_CPU_X86_64 +#if NV_USE_SSE +// -- GODOT end -- NV_FORCEINLINE int ftoi_round_sse(float f) { return _mm_cvt_ss2si(_mm_set_ss(f)); diff --git a/thirdparty/thekla_atlas/nvmath/nvmath.h b/thirdparty/thekla_atlas/nvmath/nvmath.h index 695f452c1d..f2b69426e1 100644 --- a/thirdparty/thekla_atlas/nvmath/nvmath.h +++ b/thirdparty/thekla_atlas/nvmath/nvmath.h @@ -14,10 +14,12 @@ #include <float.h> // finite, isnan #endif -#if NV_CPU_X86 || NV_CPU_X86_64 - //#include <intrin.h> - #include <xmmintrin.h> -#endif +// -- GODOT start -- +//#if NV_CPU_X86 || NV_CPU_X86_64 +// //#include <intrin.h> +// #include <xmmintrin.h> +//#endif +// -- GODOT end -- @@ -65,6 +67,13 @@ #endif +// -- GODOT start -- +#if NV_USE_SSE + //#include <intrin.h> + #include <xmmintrin.h> +#endif +// -- GODOT end -- + #ifndef PI #define PI float(3.1415926535897932384626433833) |