diff options
137 files changed, 1688 insertions, 676 deletions
diff --git a/COPYRIGHT.txt b/COPYRIGHT.txt index 92e68060c6..13edd896ef 100644 --- a/COPYRIGHT.txt +++ b/COPYRIGHT.txt @@ -145,6 +145,11 @@ Comment: DroidSans font Copyright: 2008, The Android Open Source Project License: Apache-2.0 +Files: ./thirdparty/fonts/NotoSans*.ttf +Comment: Noto Sans font +Copyright: 2012, Google Inc. +License: OFL-1.1 + Files: ./thirdparty/fonts/source_code_pro.otf Comment: Source Code Pro font Copyright: 2010, 2012, Adobe Systems Incorporated diff --git a/core/hash_map.h b/core/hash_map.h index b22c6378b0..37391a4c83 100644 --- a/core/hash_map.h +++ b/core/hash_map.h @@ -102,17 +102,31 @@ public: } }; -private: - struct Entry { + struct Element { + private: + friend class HashMap; uint32_t hash; - Entry *next; + Element *next; + Element() { next = 0; } Pair pair; - Entry() { next = 0; } + public: + const TKey &key() const { + return pair.key; + } + + TData &value() { + return pair.data; + } + + const TData &value() const { + return pair.value(); + } }; - Entry **hash_table; +private: + Element **hash_table; uint8_t hash_table_power; uint32_t elements; @@ -120,7 +134,7 @@ private: ERR_FAIL_COND(hash_table); - hash_table = memnew_arr(Entry *, (1 << MIN_HASH_TABLE_POWER)); + hash_table = memnew_arr(Element *, (1 << MIN_HASH_TABLE_POWER)); hash_table_power = MIN_HASH_TABLE_POWER; elements = 0; @@ -168,7 +182,7 @@ private: if (new_hash_table_power == -1) return; - Entry **new_hash_table = memnew_arr(Entry *, (1 << new_hash_table_power)); + Element **new_hash_table = memnew_arr(Element *, (1 << new_hash_table_power)); if (!new_hash_table) { ERR_PRINT("Out of Memory"); @@ -184,7 +198,7 @@ private: while (hash_table[i]) { - Entry *se = hash_table[i]; + Element *se = hash_table[i]; hash_table[i] = se->next; int new_pos = se->hash & ((1 << new_hash_table_power) - 1); se->next = new_hash_table[new_pos]; @@ -199,12 +213,12 @@ private: } /* I want to have only one function.. */ - _FORCE_INLINE_ const Entry *get_entry(const TKey &p_key) const { + _FORCE_INLINE_ const Element *get_element(const TKey &p_key) const { uint32_t hash = Hasher::hash(p_key); uint32_t index = hash & ((1 << hash_table_power) - 1); - Entry *e = hash_table[index]; + Element *e = hash_table[index]; while (e) { @@ -221,10 +235,10 @@ private: return NULL; } - Entry *create_entry(const TKey &p_key) { + Element *create_element(const TKey &p_key) { - /* if entry doesn't exist, create it */ - Entry *e = memnew(Entry); + /* if element doesn't exist, create it */ + Element *e = memnew(Element); ERR_FAIL_COND_V(!e, NULL); /* out of memory */ uint32_t hash = Hasher::hash(p_key); uint32_t index = hash & ((1 << hash_table_power) - 1); @@ -248,7 +262,7 @@ private: if (!p_t.hash_table || p_t.hash_table_power == 0) return; /* not copying from empty table */ - hash_table = memnew_arr(Entry *, 1 << p_t.hash_table_power); + hash_table = memnew_arr(Element *, 1 << p_t.hash_table_power); hash_table_power = p_t.hash_table_power; elements = p_t.elements; @@ -256,11 +270,11 @@ private: hash_table[i] = NULL; - const Entry *e = p_t.hash_table[i]; + const Element *e = p_t.hash_table[i]; while (e) { - Entry *le = memnew(Entry); /* local entry */ + Element *le = memnew(Element); /* local element */ *le = *e; /* copy data */ @@ -274,30 +288,30 @@ private: } public: - void set(const TKey &p_key, const TData &p_data) { - - set(Pair(p_key, p_data)); + Element *set(const TKey &p_key, const TData &p_data) { + return set(Pair(p_key, p_data)); } - void set(const Pair &p_pair) { + Element *set(const Pair &p_pair) { - Entry *e = NULL; + Element *e = NULL; if (!hash_table) make_hash_table(); // if no table, make one else - e = const_cast<Entry *>(get_entry(p_pair.key)); + e = const_cast<Element *>(get_element(p_pair.key)); /* if we made it up to here, the pair doesn't exist, create and assign */ if (!e) { - e = create_entry(p_pair.key); + e = create_element(p_pair.key); if (!e) - return; + return NULL; check_hash_table(); // perform mantenience routine } e->pair.data = p_pair.data; + return e; } bool has(const TKey &p_key) const { @@ -335,7 +349,7 @@ public: if (!hash_table) return NULL; - Entry *e = const_cast<Entry *>(get_entry(p_key)); + Element *e = const_cast<Element *>(get_element(p_key)); if (e) return &e->pair.data; @@ -348,7 +362,7 @@ public: if (!hash_table) return NULL; - const Entry *e = const_cast<Entry *>(get_entry(p_key)); + const Element *e = const_cast<Element *>(get_element(p_key)); if (e) return &e->pair.data; @@ -370,7 +384,7 @@ public: uint32_t hash = p_custom_hash; uint32_t index = hash & ((1 << hash_table_power) - 1); - Entry *e = hash_table[index]; + Element *e = hash_table[index]; while (e) { @@ -396,7 +410,7 @@ public: uint32_t hash = p_custom_hash; uint32_t index = hash & ((1 << hash_table_power) - 1); - const Entry *e = hash_table[index]; + const Element *e = hash_table[index]; while (e) { @@ -425,8 +439,8 @@ public: uint32_t hash = Hasher::hash(p_key); uint32_t index = hash & ((1 << hash_table_power) - 1); - Entry *e = hash_table[index]; - Entry *p = NULL; + Element *e = hash_table[index]; + Element *p = NULL; while (e) { /* checking hash first avoids comparing key, which may take longer */ @@ -463,16 +477,16 @@ public: } inline TData &operator[](const TKey &p_key) { //assignment - Entry *e = NULL; + Element *e = NULL; if (!hash_table) make_hash_table(); // if no table, make one else - e = const_cast<Entry *>(get_entry(p_key)); + e = const_cast<Element *>(get_element(p_key)); /* if we made it up to here, the pair doesn't exist, create */ if (!e) { - e = create_entry(p_key); + e = create_element(p_key); CRASH_COND(!e); check_hash_table(); // perform mantenience routine } @@ -510,14 +524,14 @@ public: } else { /* get the next key */ - const Entry *e = get_entry(*p_key); + const Element *e = get_element(*p_key); ERR_FAIL_COND_V(!e, NULL); /* invalid key supplied */ if (e->next) { /* if there is a "next" in the list, return that */ return &e->next->pair.key; } else { - /* go to next entries */ + /* go to next elements */ uint32_t index = e->hash & ((1 << hash_table_power) - 1); index++; for (int i = index; i < (1 << hash_table_power); i++) { @@ -552,7 +566,7 @@ public: while (hash_table[i]) { - Entry *e = hash_table[i]; + Element *e = hash_table[i]; hash_table[i] = e->next; memdelete(e); } @@ -582,7 +596,7 @@ public: return; for (int i = 0; i < (1 << hash_table_power); i++) { - Entry *e = hash_table[i]; + Element *e = hash_table[i]; while (e) { *p_pairs = &e->pair; p_pairs++; @@ -596,7 +610,7 @@ public: return; for (int i = 0; i < (1 << hash_table_power); i++) { - Entry *e = hash_table[i]; + Element *e = hash_table[i]; while (e) { p_keys->push_back(e->pair.key); e = e->next; diff --git a/core/helper/math_fieldwise.cpp b/core/helper/math_fieldwise.cpp index 2ce2a70866..228611f8b3 100644 --- a/core/helper/math_fieldwise.cpp +++ b/core/helper/math_fieldwise.cpp @@ -1,5 +1,5 @@ /*************************************************************************/ -/* fieldwise.cpp */ +/* math_fieldwise.cpp */ /*************************************************************************/ /* This file is part of: */ /* GODOT ENGINE */ diff --git a/core/helper/math_fieldwise.h b/core/helper/math_fieldwise.h index 4671703f41..400df040a4 100644 --- a/core/helper/math_fieldwise.h +++ b/core/helper/math_fieldwise.h @@ -1,5 +1,5 @@ /*************************************************************************/ -/* fieldwise.h */ +/* math_fieldwise.h */ /*************************************************************************/ /* This file is part of: */ /* GODOT ENGINE */ diff --git a/core/io/resource_format_binary.cpp b/core/io/resource_format_binary.cpp index 965d11e414..f44492248e 100644 --- a/core/io/resource_format_binary.cpp +++ b/core/io/resource_format_binary.cpp @@ -1005,7 +1005,7 @@ ResourceInteractiveLoaderBinary::~ResourceInteractiveLoaderBinary() { memdelete(f); } -Ref<ResourceInteractiveLoader> ResourceFormatLoaderBinary::load_interactive(const String &p_path, Error *r_error) { +Ref<ResourceInteractiveLoader> ResourceFormatLoaderBinary::load_interactive(const String &p_path, const String &p_original_path, Error *r_error) { if (r_error) *r_error = ERR_FILE_CANT_OPEN; @@ -1019,7 +1019,8 @@ Ref<ResourceInteractiveLoader> ResourceFormatLoaderBinary::load_interactive(cons } Ref<ResourceInteractiveLoaderBinary> ria = memnew(ResourceInteractiveLoaderBinary); - ria->local_path = ProjectSettings::get_singleton()->localize_path(p_path); + String path = p_original_path != "" ? p_original_path : p_path; + ria->local_path = ProjectSettings::get_singleton()->localize_path(path); ria->res_path = ria->local_path; //ria->set_local_path( Globals::get_singleton()->localize_path(p_path) ); ria->open(f); diff --git a/core/io/resource_format_binary.h b/core/io/resource_format_binary.h index 1bd0d333c6..ab77c2c9d3 100644 --- a/core/io/resource_format_binary.h +++ b/core/io/resource_format_binary.h @@ -101,7 +101,7 @@ public: class ResourceFormatLoaderBinary : public ResourceFormatLoader { public: - virtual Ref<ResourceInteractiveLoader> load_interactive(const String &p_path, Error *r_error = NULL); + virtual Ref<ResourceInteractiveLoader> load_interactive(const String &p_path, const String &p_original_path = "", Error *r_error = NULL); virtual void get_recognized_extensions_for_type(const String &p_type, List<String> *p_extensions) const; virtual void get_recognized_extensions(List<String> *p_extensions) const; virtual bool handles_type(const String &p_type) const; diff --git a/core/io/resource_import.cpp b/core/io/resource_import.cpp index 69ff791a3a..be486a86a3 100644 --- a/core/io/resource_import.cpp +++ b/core/io/resource_import.cpp @@ -119,7 +119,7 @@ RES ResourceFormatImporter::load(const String &p_path, const String &p_original_ return RES(); } - RES res = ResourceLoader::load(pat.path, pat.type, false, r_error); + RES res = ResourceLoader::_load(pat.path, p_path, pat.type, false, r_error); #ifdef TOOLS_ENABLED if (res.is_valid()) { diff --git a/core/io/resource_loader.cpp b/core/io/resource_loader.cpp index 30ae9f5681..4f266df43e 100644 --- a/core/io/resource_loader.cpp +++ b/core/io/resource_loader.cpp @@ -109,10 +109,10 @@ public: ResourceInteractiveLoaderDefault() {} }; -Ref<ResourceInteractiveLoader> ResourceFormatLoader::load_interactive(const String &p_path, Error *r_error) { +Ref<ResourceInteractiveLoader> ResourceFormatLoader::load_interactive(const String &p_path, const String &p_original_path, Error *r_error) { //either this - Ref<Resource> res = load(p_path, p_path, r_error); + Ref<Resource> res = load(p_path, p_original_path, r_error); if (res.is_null()) return Ref<ResourceInteractiveLoader>(); @@ -126,7 +126,7 @@ RES ResourceFormatLoader::load(const String &p_path, const String &p_original_pa String path = p_path; //or this must be implemented - Ref<ResourceInteractiveLoader> ril = load_interactive(p_path, r_error); + Ref<ResourceInteractiveLoader> ril = load_interactive(p_path, p_original_path, r_error); if (!ril.is_valid()) return RES(); ril->set_local_path(p_original_path); @@ -157,6 +157,34 @@ void ResourceFormatLoader::get_dependencies(const String &p_path, List<String> * /////////////////////////////////// +RES ResourceLoader::_load(const String &p_path, const String &p_original_path, const String &p_type_hint, bool p_no_cache, Error *r_error) { + + bool found = false; + + // Try all loaders and pick the first match for the type hint + for (int i = 0; i < loader_count; i++) { + + if (!loader[i]->recognize_path(p_path, p_type_hint)) { + continue; + } + found = true; + RES res = loader[i]->load(p_path, p_original_path != String() ? p_original_path : p_path, r_error); + if (res.is_null()) { + continue; + } + + return res; + } + + if (found) { + ERR_EXPLAIN("Failed loading resource: " + p_path); + } else { + ERR_EXPLAIN("No loader found for resource: " + p_path); + } + ERR_FAIL_V(RES()); + return RES(); +} + RES ResourceLoader::load(const String &p_path, const String &p_type_hint, bool p_no_cache, Error *r_error) { if (r_error) @@ -183,45 +211,29 @@ RES ResourceLoader::load(const String &p_path, const String &p_type_hint, bool p if (OS::get_singleton()->is_stdout_verbose()) print_line("load resource: " + path); - bool found = false; - // Try all loaders and pick the first match for the type hint - for (int i = 0; i < loader_count; i++) { + RES res = _load(path, local_path, p_type_hint, p_no_cache, r_error); - if (!loader[i]->recognize_path(path, p_type_hint)) { - continue; - } - found = true; - RES res = loader[i]->load(path, path, r_error); - if (res.is_null()) { - continue; - } - if (!p_no_cache) - res->set_path(local_path); + if (res.is_null()) { + return RES(); + } + if (!p_no_cache) + res->set_path(local_path); - if (xl_remapped) - res->set_as_translation_remapped(true); + if (xl_remapped) + res->set_as_translation_remapped(true); #ifdef TOOLS_ENABLED - res->set_edited(false); - if (timestamp_on_load) { - uint64_t mt = FileAccess::get_modified_time(path); - //printf("mt %s: %lli\n",remapped_path.utf8().get_data(),mt); - res->set_last_modified_time(mt); - } -#endif - - return res; + res->set_edited(false); + if (timestamp_on_load) { + uint64_t mt = FileAccess::get_modified_time(path); + //printf("mt %s: %lli\n",remapped_path.utf8().get_data(),mt); + res->set_last_modified_time(mt); } +#endif - if (found) { - ERR_EXPLAIN("Failed loading resource: " + path); - } else { - ERR_EXPLAIN("No loader found for resource: " + path); - } - ERR_FAIL_V(RES()); - return RES(); + return res; } Ref<ResourceInteractiveLoader> ResourceLoader::load_interactive(const String &p_path, const String &p_type_hint, bool p_no_cache, Error *r_error) { @@ -262,7 +274,7 @@ Ref<ResourceInteractiveLoader> ResourceLoader::load_interactive(const String &p_ if (!loader[i]->recognize_path(path, p_type_hint)) continue; found = true; - Ref<ResourceInteractiveLoader> ril = loader[i]->load_interactive(path, r_error); + Ref<ResourceInteractiveLoader> ril = loader[i]->load_interactive(path, local_path, r_error); if (ril.is_null()) continue; if (!p_no_cache) diff --git a/core/io/resource_loader.h b/core/io/resource_loader.h index 91f0c939bf..a71a568569 100644 --- a/core/io/resource_loader.h +++ b/core/io/resource_loader.h @@ -57,7 +57,7 @@ public: class ResourceFormatLoader { public: - virtual Ref<ResourceInteractiveLoader> load_interactive(const String &p_path, Error *r_error = NULL); + virtual Ref<ResourceInteractiveLoader> load_interactive(const String &p_path, const String &p_original_path = "", Error *r_error = NULL); virtual RES load(const String &p_path, const String &p_original_path = "", Error *r_error = NULL); virtual void get_recognized_extensions(List<String> *p_extensions) const = 0; virtual void get_recognized_extensions_for_type(const String &p_type, List<String> *p_extensions) const; @@ -96,6 +96,10 @@ class ResourceLoader { static SelfList<Resource>::List remapped_list; + friend class ResourceFormatImporter; + //internal load function + static RES _load(const String &p_path, const String &p_original_path, const String &p_type_hint, bool p_no_cache, Error *r_error); + public: static Ref<ResourceInteractiveLoader> load_interactive(const String &p_path, const String &p_type_hint = "", bool p_no_cache = false, Error *r_error = NULL); static RES load(const String &p_path, const String &p_type_hint = "", bool p_no_cache = false, Error *r_error = NULL); diff --git a/core/math/a_star.h b/core/math/a_star.h index d2d2166719..75b860d0a4 100644 --- a/core/math/a_star.h +++ b/core/math/a_star.h @@ -1,5 +1,5 @@ /*************************************************************************/ -/* a_star.h */ +/* a_star.h */ /*************************************************************************/ /* This file is part of: */ /* GODOT ENGINE */ diff --git a/core/ordered_hash_map.h b/core/ordered_hash_map.h new file mode 100644 index 0000000000..3e619d2b2e --- /dev/null +++ b/core/ordered_hash_map.h @@ -0,0 +1,315 @@ +/*************************************************************************/ +/* ordered_hash_map.h */ +/*************************************************************************/ +/* This file is part of: */ +/* GODOT ENGINE */ +/* http://www.godotengine.org */ +/*************************************************************************/ +/* Copyright (c) 2007-2017 Juan Linietsky, Ariel Manzur. */ +/* Copyright (c) 2014-2017 Godot Engine contributors (cf. AUTHORS.md) */ +/* */ +/* 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: */ +/* */ +/* 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. */ +/*************************************************************************/ +#ifndef ORDERED_HASH_MAP_H +#define ORDERED_HASH_MAP_H + +#include "hash_map.h" +#include "list.h" +#include "pair.h" + +/** + * A hash map which allows to iterate elements in insertion order. + * Insertion, lookup, deletion have O(1) complexity. + * The API aims to be consistent with Map rather than HashMap, because the + * former is more frequently used and is more coherent with the rest of the + * codebase. + * Deletion during iteration is safe and will preserve the order. + */ +template <class K, class V, class Hasher = HashMapHasherDefault, class Comparator = HashMapComparatorDefault<K>, uint8_t MIN_HASH_TABLE_POWER = 3, uint8_t RELATIONSHIP = 8> +class OrderedHashMap { + typedef List<Pair<const K *, V> > InternalList; + typedef HashMap<K, typename InternalList::Element *, Hasher, Comparator, MIN_HASH_TABLE_POWER, RELATIONSHIP> InternalMap; + + InternalList list; + InternalMap map; + +public: + class Element { + friend class OrderedHashMap<K, V, Hasher, Comparator, MIN_HASH_TABLE_POWER, RELATIONSHIP>; + + typename InternalList::Element *list_element; + typename InternalList::Element *next_element; + typename InternalList::Element *prev_element; + + Element(typename InternalList::Element *p_element) { + list_element = p_element; + + if (list_element) { + next_element = list_element->next(); + prev_element = list_element->prev(); + } + } + + public: + _FORCE_INLINE_ Element() + : list_element(NULL), next_element(NULL), prev_element(NULL) { + } + + Element next() const { + return Element(next_element); + } + + Element prev() const { + return Element(prev_element); + } + + Element(const Element &other) + : list_element(other.list_element), + prev_element(other.prev_element), + next_element(other.next_element) { + } + + Element &operator=(const Element &other) { + list_element = other.list_element; + next_element = other.next_element; + prev_element = other.prev_element; + return *this; + } + + friend bool operator==(const Element &, const Element &); + friend bool operator!=(const Element &, const Element &); + + operator bool() const { + return (list_element != NULL); + } + + const K &key() const { + CRASH_COND(!list_element); + return *(list_element->get().first); + }; + + V &value() { + CRASH_COND(!list_element); + return list_element->get().second; + }; + + const V &value() const { + CRASH_COND(!list_element); + return list_element->get().second; + }; + + V &get() { + CRASH_COND(!list_element); + return list_element->get().second; + }; + + const V &get() const { + CRASH_COND(!list_element); + return list_element->get().second; + }; + }; + + class ConstElement { + friend class OrderedHashMap<K, V, Hasher, Comparator, MIN_HASH_TABLE_POWER, RELATIONSHIP>; + + const typename InternalList::Element *list_element; + + ConstElement(const typename InternalList::Element *p_element) + : list_element(p_element) { + } + + public: + _FORCE_INLINE_ ConstElement() + : list_element(NULL) { + } + + ConstElement(const ConstElement &other) + : list_element(other.list_element) { + } + + ConstElement &operator=(const ConstElement &other) { + list_element = other.list_element; + return *this; + } + + ConstElement next() const { + return ConstElement(list_element ? list_element->next() : NULL); + } + + ConstElement prev() const { + return ConstElement(list_element ? list_element->prev() : NULL); + } + + friend bool operator==(const ConstElement &, const ConstElement &); + friend bool operator!=(const ConstElement &, const ConstElement &); + + operator bool() const { + return (list_element != NULL); + } + + const K &key() const { + CRASH_COND(!list_element); + return *(list_element->get().first); + }; + + const V &value() const { + CRASH_COND(!list_element); + return list_element->get().second; + }; + + const V &get() const { + CRASH_COND(!list_element); + return list_element->get().second; + }; + }; + + ConstElement find(const K &p_key) const { + typename InternalList::Element **list_element = map.getptr(p_key); + if (list_element) { + return ConstElement(*list_element); + } + return ConstElement(NULL); + } + + Element find(const K &p_key) { + typename InternalList::Element **list_element = map.getptr(p_key); + if (list_element) { + return Element(*list_element); + } + return Element(NULL); + } + + Element insert(const K &p_key, const V &p_value) { + typename InternalList::Element **list_element = map.getptr(p_key); + if (list_element) { + (*list_element)->get().second = p_value; + return Element(*list_element); + } + typename InternalList::Element *new_element = list.push_back(Pair<const K *, V>(NULL, p_value)); + typename InternalMap::Element *e = map.set(p_key, new_element); + new_element->get().first = &e->key(); + + return Element(new_element); + } + + void erase(Element &p_element) { + map.erase(p_element.key()); + list.erase(p_element.list_element); + p_element.list_element = NULL; + } + + bool erase(const K &p_key) { + typename InternalList::Element **list_element = map.getptr(p_key); + if (list_element) { + list.erase(*list_element); + map.erase(p_key); + return true; + } + return false; + } + + inline bool has(const K &p_key) const { + return map.has(p_key); + } + + const V &operator[](const K &p_key) const { + ConstElement e = find(p_key); + CRASH_COND(!e); + return e.value(); + } + + V &operator[](const K &p_key) { + Element e = find(p_key); + if (!e) { + // consistent with Map behaviour + e = insert(p_key, V()); + } + return e.value(); + } + + inline Element front() { + return Element(list.front()); + } + + inline Element back() { + return Element(list.back()); + } + + inline ConstElement front() const { + return ConstElement(list.front()); + } + + inline ConstElement back() const { + return ConstElement(list.back()); + } + + inline bool empty() const { return list.empty(); } + inline int size() const { return list.size(); } + + void clear() { + map.clear(); + list.clear(); + } + +private: + void _copy_from(const OrderedHashMap &p_map) { + for (ConstElement E = p_map.front(); E; E = E.next()) { + insert(E.key(), E.value()); + } + } + +public: + void operator=(const OrderedHashMap &p_map) { + _copy_from(p_map); + } + + OrderedHashMap(const OrderedHashMap &p_map) { + _copy_from(p_map); + } + + _FORCE_INLINE_ OrderedHashMap() { + } +}; + +template <class K, class V, class Hasher, class Comparator, uint8_t MIN_HASH_TABLE_POWER, uint8_t RELATIONSHIP> +bool operator==(const typename OrderedHashMap<K, V, Hasher, Comparator, MIN_HASH_TABLE_POWER, RELATIONSHIP>::Element &first, + const typename OrderedHashMap<K, V, Hasher, Comparator, MIN_HASH_TABLE_POWER, RELATIONSHIP>::Element &second) { + return (first.list_element == second.list_element); +} + +template <class K, class V, class Hasher, class Comparator, uint8_t MIN_HASH_TABLE_POWER, uint8_t RELATIONSHIP> +bool operator!=(const typename OrderedHashMap<K, V, Hasher, Comparator, MIN_HASH_TABLE_POWER, RELATIONSHIP>::Element &first, + const typename OrderedHashMap<K, V, Hasher, Comparator, MIN_HASH_TABLE_POWER, RELATIONSHIP>::Element &second) { + return (first.list_element != second.list_element); +} + +template <class K, class V, class Hasher, class Comparator, uint8_t MIN_HASH_TABLE_POWER, uint8_t RELATIONSHIP> +bool operator==(const typename OrderedHashMap<K, V, Hasher, Comparator, MIN_HASH_TABLE_POWER, RELATIONSHIP>::ConstElement &first, + const typename OrderedHashMap<K, V, Hasher, Comparator, MIN_HASH_TABLE_POWER, RELATIONSHIP>::ConstElement &second) { + return (first.list_element == second.list_element); +} + +template <class K, class V, class Hasher, class Comparator, uint8_t MIN_HASH_TABLE_POWER, uint8_t RELATIONSHIP> +bool operator!=(const typename OrderedHashMap<K, V, Hasher, Comparator, MIN_HASH_TABLE_POWER, RELATIONSHIP>::ConstElement &first, + const typename OrderedHashMap<K, V, Hasher, Comparator, MIN_HASH_TABLE_POWER, RELATIONSHIP>::ConstElement &second) { + return (first.list_element != second.list_element); +} + +#endif // ORDERED_HASH_MAP_H
\ No newline at end of file diff --git a/core/pair.h b/core/pair.h index f780c79c81..535c3355b6 100644 --- a/core/pair.h +++ b/core/pair.h @@ -44,6 +44,16 @@ struct Pair { }; template <class F, class S> +bool operator==(const Pair<F, S> &pair, const Pair<F, S> &other) { + return (pair.first == other.first) && (pair.second == other.second); +} + +template <class F, class S> +bool operator!=(const Pair<F, S> &pair, const Pair<F, S> &other) { + return (pair.first != other.first) || (pair.second != other.second); +} + +template <class F, class S> struct PairSort { bool operator()(const Pair<F, S> &A, const Pair<F, S> &B) const { diff --git a/core/project_settings.cpp b/core/project_settings.cpp index ce1d7918db..a74917162b 100644 --- a/core/project_settings.cpp +++ b/core/project_settings.cpp @@ -1,5 +1,5 @@ /*************************************************************************/ -/* globals.cpp */ +/* project_settings.cpp */ /*************************************************************************/ /* This file is part of: */ /* GODOT ENGINE */ diff --git a/core/project_settings.h b/core/project_settings.h index 5c8907c74e..718ab2a011 100644 --- a/core/project_settings.h +++ b/core/project_settings.h @@ -1,5 +1,5 @@ /*************************************************************************/ -/* globals.h */ +/* project_settings.h */ /*************************************************************************/ /* This file is part of: */ /* GODOT ENGINE */ diff --git a/core/script_language.cpp b/core/script_language.cpp index f2be15897e..bde80a30bc 100644 --- a/core/script_language.cpp +++ b/core/script_language.cpp @@ -55,7 +55,6 @@ void Script::_bind_methods() { ClassDB::bind_method(D_METHOD("set_source_code", "source"), &Script::set_source_code); ClassDB::bind_method(D_METHOD("reload", "keep_state"), &Script::reload, DEFVAL(false)); - ClassDB::bind_method(D_METHOD("has_method", "method_name"), &Script::has_method); ClassDB::bind_method(D_METHOD("has_script_signal", "signal_name"), &Script::has_script_signal); ClassDB::bind_method(D_METHOD("is_tool"), &Script::is_tool); diff --git a/doc/base/classes.xml b/doc/base/classes.xml index 8af7385934..e0b1ea3870 100644 --- a/doc/base/classes.xml +++ b/doc/base/classes.xml @@ -25989,7 +25989,7 @@ <description> </description> <methods> - <method name="get_draw_center" qualifiers="const"> + <method name="is_draw_center_enabled" qualifiers="const"> <return type="bool"> </return> <description> @@ -26071,7 +26071,7 @@ </member> <member name="axis_stretch_vertical" type="int" setter="set_v_axis_stretch_mode" getter="get_v_axis_stretch_mode" brief=""> </member> - <member name="draw_center" type="bool" setter="set_draw_center" getter="get_draw_center" brief=""> + <member name="draw_center" type="bool" setter="set_draw_center" getter="is_draw_center_enabled" brief=""> </member> <member name="patch_margin_bottom" type="int" setter="set_patch_margin" getter="get_patch_margin" brief=""> </member> @@ -32449,7 +32449,7 @@ <description> </description> </method> - <method name="get_principal_inetria_axes" qualifiers="const"> + <method name="get_principal_inertia_axes" qualifiers="const"> <return type="Basis"> </return> <description> @@ -44515,7 +44515,7 @@ <description> </description> </method> - <method name="get_draw_center" qualifiers="const"> + <method name="is_draw_center_enabled" qualifiers="const"> <return type="bool"> </return> <description> @@ -44573,7 +44573,7 @@ </member> <member name="dark_color" type="Color" setter="set_dark_color" getter="get_dark_color" brief=""> </member> - <member name="draw_bg" type="bool" setter="set_draw_center" getter="get_draw_center" brief=""> + <member name="draw_bg" type="bool" setter="set_draw_center" getter="is_draw_center_enabled" brief=""> </member> <member name="light_color" type="Color" setter="set_light_color" getter="get_light_color" brief=""> </member> @@ -44589,7 +44589,7 @@ Texture Based 3x3 scale style. This stylebox performs a 3x3 scaling of a texture, where only the center cell is fully stretched. This allows for the easy creation of bordered styles. </description> <methods> - <method name="get_draw_center" qualifiers="const"> + <method name="is_draw_center_enabled" qualifiers="const"> <return type="bool"> </return> <description> @@ -44683,7 +44683,7 @@ </method> </methods> <members> - <member name="draw_center" type="bool" setter="set_draw_center" getter="get_draw_center" brief=""> + <member name="draw_center" type="bool" setter="set_draw_center" getter="is_draw_center_enabled" brief=""> </member> <member name="expand_margin_bottom" type="float" setter="set_expand_margin_size" getter="get_expand_margin_size" brief=""> </member> diff --git a/drivers/convex_decomp/b2d_decompose.cpp b/drivers/convex_decomp/b2d_decompose.cpp index 14ab4d1072..97d312983f 100644 --- a/drivers/convex_decomp/b2d_decompose.cpp +++ b/drivers/convex_decomp/b2d_decompose.cpp @@ -1,5 +1,5 @@ /*************************************************************************/ -/* b2d_decompose.cpp */ +/* b2d_decompose.cpp */ /*************************************************************************/ /* This file is part of: */ /* GODOT ENGINE */ diff --git a/drivers/gles3/rasterizer_scene_gles3.cpp b/drivers/gles3/rasterizer_scene_gles3.cpp index a492629dae..cbb05befb6 100644 --- a/drivers/gles3/rasterizer_scene_gles3.cpp +++ b/drivers/gles3/rasterizer_scene_gles3.cpp @@ -1,5 +1,5 @@ /*************************************************************************/ -/* rasterizer_storage_gles3.cpp */ +/* rasterizer_scene_gles3.cpp */ /*************************************************************************/ /* This file is part of: */ /* GODOT ENGINE */ @@ -1100,15 +1100,15 @@ bool RasterizerSceneGLES3::_setup_material(RasterizerStorageGLES3::Material *p_m state.current_line_width = p_material->line_width; } - if (state.current_depth_test != (!p_material->shader->spatial.ontop)) { - if (p_material->shader->spatial.ontop) { + if (state.current_depth_test != (!p_material->shader->spatial.no_depth_test)) { + if (p_material->shader->spatial.no_depth_test) { glDisable(GL_DEPTH_TEST); } else { glEnable(GL_DEPTH_TEST); } - state.current_depth_test = !p_material->shader->spatial.ontop; + state.current_depth_test = !p_material->shader->spatial.no_depth_test; } if (state.current_depth_draw != p_material->shader->spatial.depth_draw_mode) { @@ -2195,7 +2195,7 @@ void RasterizerSceneGLES3::_add_geometry(RasterizerStorageGLES3::Geometry *p_geo void RasterizerSceneGLES3::_add_geometry_with_material(RasterizerStorageGLES3::Geometry *p_geometry, InstanceBase *p_instance, RasterizerStorageGLES3::GeometryOwner *p_owner, RasterizerStorageGLES3::Material *p_material, bool p_shadow) { bool has_base_alpha = (p_material->shader->spatial.uses_alpha && !p_material->shader->spatial.uses_alpha_scissor) || p_material->shader->spatial.uses_screen_texture; - bool has_blend_alpha = p_material->shader->spatial.blend_mode != RasterizerStorageGLES3::Shader::Spatial::BLEND_MODE_MIX || p_material->shader->spatial.ontop; + bool has_blend_alpha = p_material->shader->spatial.blend_mode != RasterizerStorageGLES3::Shader::Spatial::BLEND_MODE_MIX; bool has_alpha = has_base_alpha || has_blend_alpha; bool shadow = false; @@ -2267,7 +2267,7 @@ void RasterizerSceneGLES3::_add_geometry_with_material(RasterizerStorageGLES3::G } e->sort_key |= uint64_t(e->material->index) << RenderList::SORT_KEY_MATERIAL_INDEX_SHIFT; - e->sort_key |= uint64_t(e->instance->depth_layer) << RenderList::SORT_KEY_DEPTH_LAYER_SHIFT; + e->sort_key |= uint64_t(e->instance->depth_layer) << RenderList::SORT_KEY_OPAQUE_DEPTH_LAYER_SHIFT; if (!has_blend_alpha && has_alpha && p_material->shader->spatial.depth_draw_mode == RasterizerStorageGLES3::Shader::Spatial::DEPTH_DRAW_ALPHA_PREPASS) { @@ -2283,6 +2283,8 @@ void RasterizerSceneGLES3::_add_geometry_with_material(RasterizerStorageGLES3::G if (e->instance->gi_probe_instances.size()) { e->sort_key |= SORT_KEY_GI_PROBES_FLAG; } + + e->sort_key |= uint64_t(p_material->render_priority + 128) << RenderList::SORT_KEY_PRIORITY_SHIFT; } /* @@ -4282,7 +4284,7 @@ void RasterizerSceneGLES3::render_scene(const Transform &p_cam_transform, const glEnable(GL_DEPTH_TEST); glDisable(GL_SCISSOR_TEST); - render_list.sort_by_reverse_depth(true); + render_list.sort_by_reverse_depth_and_priority(true); if (state.directional_light_count == 0) { directional_light = NULL; diff --git a/drivers/gles3/rasterizer_scene_gles3.h b/drivers/gles3/rasterizer_scene_gles3.h index 659408b455..d9c96b15b7 100644 --- a/drivers/gles3/rasterizer_scene_gles3.h +++ b/drivers/gles3/rasterizer_scene_gles3.h @@ -531,7 +531,7 @@ public: virtual void environment_set_fog(RID p_env, bool p_enable, float p_begin, float p_end, RID p_gradient_texture); virtual void environment_set_ssr(RID p_env, bool p_enable, int p_max_steps, float p_fade_in, float p_fade_out, float p_depth_tolerance, bool p_roughness); - virtual void environment_set_ssao(RID p_env, bool p_enable, float p_radius, float p_radius2, float p_intensity2, float p_intensity, float p_bias, float p_light_affect, const Color &p_color, bool p_blur); + virtual void environment_set_ssao(RID p_env, bool p_enable, float p_radius, float p_intensity, float p_radius2, float p_intensity2, float p_bias, float p_light_affect, const Color &p_color, bool p_blur); virtual void environment_set_tonemap(RID p_env, VS::EnvironmentToneMapper p_tone_mapper, float p_exposure, float p_white, bool p_auto_exposure, float p_min_luminance, float p_max_luminance, float p_auto_exp_speed, float p_auto_exp_scale); @@ -645,17 +645,25 @@ public: MAX_LIGHTS = 4096, MAX_REFLECTIONS = 1024, - SORT_KEY_DEPTH_LAYER_SHIFT = 60, + SORT_KEY_PRIORITY_SHIFT = 56, + SORT_KEY_PRIORITY_MASK = 0xFF, + //depth layer for opaque (56-52) + SORT_KEY_OPAQUE_DEPTH_LAYER_SHIFT = 52, + SORT_KEY_OPAQUE_DEPTH_LAYER_MASK = 0xF, //64 bits unsupported in MSVC -#define SORT_KEY_UNSHADED_FLAG (uint64_t(1) << 59) -#define SORT_KEY_NO_DIRECTIONAL_FLAG (uint64_t(1) << 58) -#define SORT_KEY_GI_PROBES_FLAG (uint64_t(1) << 57) -#define SORT_KEY_VERTEX_LIT_FLAG (uint64_t(1) << 56) - SORT_KEY_SHADING_SHIFT = 56, +#define SORT_KEY_UNSHADED_FLAG (uint64_t(1) << 51) +#define SORT_KEY_NO_DIRECTIONAL_FLAG (uint64_t(1) << 50) +#define SORT_KEY_GI_PROBES_FLAG (uint64_t(1) << 49) +#define SORT_KEY_VERTEX_LIT_FLAG (uint64_t(1) << 48) + SORT_KEY_SHADING_SHIFT = 48, SORT_KEY_SHADING_MASK = 15, - SORT_KEY_MATERIAL_INDEX_SHIFT = 40, - SORT_KEY_GEOMETRY_INDEX_SHIFT = 20, - SORT_KEY_GEOMETRY_TYPE_SHIFT = 15, + //48-32 material index + SORT_KEY_MATERIAL_INDEX_SHIFT = 32, + //32-12 geometry index + SORT_KEY_GEOMETRY_INDEX_SHIFT = 12, + //bits 12-8 geometry type + SORT_KEY_GEOMETRY_TYPE_SHIFT = 8, + //bits 0-7 for flags SORT_KEY_CULL_DISABLED_FLAG = 4, SORT_KEY_SKELETON_FLAG = 2, SORT_KEY_MIRROR_FLAG = 1 @@ -721,16 +729,22 @@ public: } } - struct SortByReverseDepth { + struct SortByReverseDepthAndPriority { _FORCE_INLINE_ bool operator()(const Element *A, const Element *B) const { - return A->instance->depth > B->instance->depth; + uint32_t layer_A = uint32_t(A->sort_key >> SORT_KEY_PRIORITY_SHIFT); + uint32_t layer_B = uint32_t(B->sort_key >> SORT_KEY_PRIORITY_SHIFT); + if (layer_A == layer_B) { + return A->instance->depth > B->instance->depth; + } else { + return layer_A < layer_B; + } } }; - void sort_by_reverse_depth(bool p_alpha) { //used for alpha + void sort_by_reverse_depth_and_priority(bool p_alpha) { //used for alpha - SortArray<Element *, SortByReverseDepth> sorter; + SortArray<Element *, SortByReverseDepthAndPriority> sorter; if (p_alpha) { sorter.sort(&elements[max_elements - alpha_element_count], alpha_element_count); } else { diff --git a/drivers/gles3/rasterizer_storage_gles3.cpp b/drivers/gles3/rasterizer_storage_gles3.cpp index 4cc6dcd5fb..91ba3aa702 100644 --- a/drivers/gles3/rasterizer_storage_gles3.cpp +++ b/drivers/gles3/rasterizer_storage_gles3.cpp @@ -1599,7 +1599,7 @@ void RasterizerStorageGLES3::_update_shader(Shader *p_shader) const { p_shader->spatial.uses_alpha_scissor = false; p_shader->spatial.uses_discard = false; p_shader->spatial.unshaded = false; - p_shader->spatial.ontop = false; + p_shader->spatial.no_depth_test = false; p_shader->spatial.uses_sss = false; p_shader->spatial.uses_vertex_lighting = false; p_shader->spatial.uses_screen_texture = false; @@ -1621,7 +1621,7 @@ void RasterizerStorageGLES3::_update_shader(Shader *p_shader) const { shaders.actions_scene.render_mode_values["cull_disabled"] = Pair<int *, int>(&p_shader->spatial.cull_mode, Shader::Spatial::CULL_MODE_DISABLED); shaders.actions_scene.render_mode_flags["unshaded"] = &p_shader->spatial.unshaded; - shaders.actions_scene.render_mode_flags["ontop"] = &p_shader->spatial.ontop; + shaders.actions_scene.render_mode_flags["depth_test_disable"] = &p_shader->spatial.no_depth_test; shaders.actions_scene.render_mode_flags["vertex_lighting"] = &p_shader->spatial.uses_vertex_lighting; @@ -1948,6 +1948,17 @@ void RasterizerStorageGLES3::material_remove_instance_owner(RID p_material, Rast } } +void RasterizerStorageGLES3::material_set_render_priority(RID p_material, int priority) { + + ERR_FAIL_COND(priority < VS::MATERIAL_RENDER_PRIORITY_MIN); + ERR_FAIL_COND(priority > VS::MATERIAL_RENDER_PRIORITY_MAX); + + Material *material = material_owner.get(p_material); + ERR_FAIL_COND(!material); + + material->render_priority = priority; +} + _FORCE_INLINE_ static void _fill_std140_variant_ubo_value(ShaderLanguage::DataType type, const Variant &value, uint8_t *data, bool p_linear_color) { switch (type) { case ShaderLanguage::TYPE_BOOL: { @@ -3963,7 +3974,7 @@ Color RasterizerStorageGLES3::multimesh_instance_get_color(RID p_multimesh, int ERR_FAIL_COND_V(multimesh->color_format == VS::MULTIMESH_COLOR_NONE, Color()); int stride = multimesh->color_floats + multimesh->xform_floats; - float *dataptr = &multimesh->data[stride * p_index + multimesh->color_floats]; + float *dataptr = &multimesh->data[stride * p_index + multimesh->xform_floats]; if (multimesh->color_format == VS::MULTIMESH_COLOR_8BIT) { union { @@ -3971,6 +3982,8 @@ Color RasterizerStorageGLES3::multimesh_instance_get_color(RID p_multimesh, int float colf; } cu; + cu.colf = dataptr[0]; + return Color::hex(BSWAP32(cu.colu)); } else if (multimesh->color_format == VS::MULTIMESH_COLOR_FLOAT) { diff --git a/drivers/gles3/rasterizer_storage_gles3.h b/drivers/gles3/rasterizer_storage_gles3.h index c74b127b23..f75b77aabe 100644 --- a/drivers/gles3/rasterizer_storage_gles3.h +++ b/drivers/gles3/rasterizer_storage_gles3.h @@ -444,7 +444,7 @@ public: bool uses_alpha; bool uses_alpha_scissor; bool unshaded; - bool ontop; + bool no_depth_test; bool uses_vertex; bool uses_discard; bool uses_sss; @@ -502,6 +502,7 @@ public: SelfList<Material> dirty_list; Vector<RID> textures; float line_width; + int render_priority; RID next_pass; @@ -523,6 +524,7 @@ public: ubo_id = 0; ubo_size = 0; last_pass = 0; + render_priority = 0; } }; @@ -550,6 +552,8 @@ public: virtual void material_add_instance_owner(RID p_material, RasterizerScene::InstanceBase *p_instance); virtual void material_remove_instance_owner(RID p_material, RasterizerScene::InstanceBase *p_instance); + virtual void material_set_render_priority(RID p_material, int priority); + void _update_material(Material *material); void update_dirty_materials(); diff --git a/drivers/wasapi/audio_driver_wasapi.cpp b/drivers/wasapi/audio_driver_wasapi.cpp index 6e01b5f524..5bea8cf20c 100644 --- a/drivers/wasapi/audio_driver_wasapi.cpp +++ b/drivers/wasapi/audio_driver_wasapi.cpp @@ -1,5 +1,5 @@ /*************************************************************************/ -/* audio_driver_wasapi.cpp */ +/* audio_driver_wasapi.cpp */ /*************************************************************************/ /* This file is part of: */ /* GODOT ENGINE */ diff --git a/drivers/wasapi/audio_driver_wasapi.h b/drivers/wasapi/audio_driver_wasapi.h index b91751f87e..c18b49e75e 100644 --- a/drivers/wasapi/audio_driver_wasapi.h +++ b/drivers/wasapi/audio_driver_wasapi.h @@ -1,5 +1,5 @@ /*************************************************************************/ -/* audio_driver_wasapi.h */ +/* audio_driver_wasapi.h */ /*************************************************************************/ /* This file is part of: */ /* GODOT ENGINE */ diff --git a/editor/code_editor.cpp b/editor/code_editor.cpp index e09145c05b..8c153d2745 100644 --- a/editor/code_editor.cpp +++ b/editor/code_editor.cpp @@ -1079,6 +1079,7 @@ void CodeTextEditor::update_editor_settings() { text_editor->set_scroll_pass_end_of_file(EditorSettings::get_singleton()->get("text_editor/cursor/scroll_past_end_of_file")); text_editor->set_indent_using_spaces(EditorSettings::get_singleton()->get("text_editor/indent/type")); text_editor->set_indent_size(EditorSettings::get_singleton()->get("text_editor/indent/size")); + text_editor->set_auto_indent(EditorSettings::get_singleton()->get("text_editor/indent/auto_indent")); text_editor->set_draw_tabs(EditorSettings::get_singleton()->get("text_editor/indent/draw_tabs")); text_editor->set_show_line_numbers(EditorSettings::get_singleton()->get("text_editor/line_numbers/show_line_numbers")); text_editor->set_line_numbers_zero_padded(EditorSettings::get_singleton()->get("text_editor/line_numbers/line_numbers_zero_padded")); diff --git a/editor/editor_export.cpp b/editor/editor_export.cpp index e761dce8ab..915fb7e5db 100644 --- a/editor/editor_export.cpp +++ b/editor/editor_export.cpp @@ -1,5 +1,5 @@ /*************************************************************************/ -/* editor_import_export.cpp */ +/* editor_export.cpp */ /*************************************************************************/ /* This file is part of: */ /* GODOT ENGINE */ diff --git a/editor/editor_export.h b/editor/editor_export.h index feff9678af..3b99c68c85 100644 --- a/editor/editor_export.h +++ b/editor/editor_export.h @@ -1,5 +1,5 @@ /*************************************************************************/ -/* editor_import_export.h */ +/* editor_export.h */ /*************************************************************************/ /* This file is part of: */ /* GODOT ENGINE */ diff --git a/editor/editor_file_system.cpp b/editor/editor_file_system.cpp index c175886d14..6e12a8fd02 100644 --- a/editor/editor_file_system.cpp +++ b/editor/editor_file_system.cpp @@ -1383,7 +1383,7 @@ void EditorFileSystem::_reimport_file(const String &p_file) { } } - if (load_default && ProjectSettings::get_singleton()->get("importer_defaults/" + importer->get_importer_name())) { + if (load_default && ProjectSettings::get_singleton()->has("importer_defaults/" + importer->get_importer_name())) { //use defaults if exist Dictionary d = ProjectSettings::get_singleton()->get("importer_defaults/" + importer->get_importer_name()); List<Variant> v; @@ -1509,6 +1509,8 @@ void EditorFileSystem::reimport_files(const Vector<String> &p_files) { if (!is_scanning()) { emit_signal("filesystem_changed"); } + + emit_signal("resources_reimported", p_files); } void EditorFileSystem::_bind_methods() { @@ -1524,6 +1526,7 @@ void EditorFileSystem::_bind_methods() { ADD_SIGNAL(MethodInfo("filesystem_changed")); ADD_SIGNAL(MethodInfo("sources_changed", PropertyInfo(Variant::BOOL, "exist"))); + ADD_SIGNAL(MethodInfo("resources_reimported", PropertyInfo(Variant::POOL_STRING_ARRAY, "resources"))); } void EditorFileSystem::_update_extensions() { diff --git a/editor/editor_fonts.cpp b/editor/editor_fonts.cpp index c4ac4cbca5..22a9c84d21 100644 --- a/editor/editor_fonts.cpp +++ b/editor/editor_fonts.cpp @@ -65,52 +65,52 @@ static Ref<BitmapFont> make_font(int p_height, int p_ascent, int p_valign, int p return font; } -#define MAKE_FALLBACKS(m_name) \ - m_name->add_fallback(DroidSansFallback); \ - m_name->add_fallback(DroidSansJapanese); \ - m_name->add_fallback(DroidSansArabic); \ - m_name->add_fallback(DroidSansHebrew); \ - m_name->add_fallback(DroidSansThai); - -#define MAKE_DROID_SANS(m_name, m_size) \ - Ref<DynamicFont> m_name; \ - m_name.instance(); \ - m_name->set_size(m_size); \ - m_name->set_font_data(DroidSans); \ +#define MAKE_FALLBACKS(m_name) \ + m_name->add_fallback(FontArabic); \ + m_name->add_fallback(FontHebrew); \ + m_name->add_fallback(FontThai); \ + m_name->add_fallback(FontJapanese); \ + m_name->add_fallback(FontFallback); + +#define MAKE_DEFAULT_FONT(m_name, m_size) \ + Ref<DynamicFont> m_name; \ + m_name.instance(); \ + m_name->set_size(m_size); \ + m_name->set_font_data(DefaultFont); \ MAKE_FALLBACKS(m_name); void editor_register_fonts(Ref<Theme> p_theme) { /* Droid Sans */ - Ref<DynamicFontData> DroidSans; - DroidSans.instance(); - DroidSans->set_font_ptr(_font_DroidSans, _font_DroidSans_size); - DroidSans->set_force_autohinter(true); //just looks better..i think? + Ref<DynamicFontData> DefaultFont; + DefaultFont.instance(); + DefaultFont->set_font_ptr(_font_NotoSansUI_Regular, _font_NotoSansUI_Regular_size); + DefaultFont->set_force_autohinter(true); //just looks better..i think? - Ref<DynamicFontData> DroidSansFallback; - DroidSansFallback.instance(); - DroidSansFallback->set_font_ptr(_font_DroidSansFallback, _font_DroidSansFallback_size); - DroidSansFallback->set_force_autohinter(true); //just looks better..i think? + Ref<DynamicFontData> FontFallback; + FontFallback.instance(); + FontFallback->set_font_ptr(_font_DroidSansFallback, _font_DroidSansFallback_size); + FontFallback->set_force_autohinter(true); //just looks better..i think? - Ref<DynamicFontData> DroidSansJapanese; - DroidSansJapanese.instance(); - DroidSansJapanese->set_font_ptr(_font_DroidSansJapanese, _font_DroidSansJapanese_size); - DroidSansJapanese->set_force_autohinter(true); //just looks better..i think? + Ref<DynamicFontData> FontJapanese; + FontJapanese.instance(); + FontJapanese->set_font_ptr(_font_DroidSansJapanese, _font_DroidSansJapanese_size); + FontJapanese->set_force_autohinter(true); //just looks better..i think? - Ref<DynamicFontData> DroidSansArabic; - DroidSansArabic.instance(); - DroidSansArabic->set_font_ptr(_font_DroidSansArabic, _font_DroidSansArabic_size); - DroidSansArabic->set_force_autohinter(true); //just looks better..i think? + Ref<DynamicFontData> FontArabic; + FontArabic.instance(); + FontArabic->set_font_ptr(_font_NotoNaskhArabicUI_Regular, _font_NotoNaskhArabicUI_Regular_size); + FontArabic->set_force_autohinter(true); //just looks better..i think? - Ref<DynamicFontData> DroidSansHebrew; - DroidSansHebrew.instance(); - DroidSansHebrew->set_font_ptr(_font_DroidSansHebrew, _font_DroidSansHebrew_size); - DroidSansHebrew->set_force_autohinter(true); //just looks better..i think? + Ref<DynamicFontData> FontHebrew; + FontHebrew.instance(); + FontHebrew->set_font_ptr(_font_NotoSansHebrew_Regular, _font_NotoSansHebrew_Regular_size); + FontHebrew->set_force_autohinter(true); //just looks better..i think? - Ref<DynamicFontData> DroidSansThai; - DroidSansThai.instance(); - DroidSansThai->set_font_ptr(_font_DroidSansThai, _font_DroidSansThai_size); - DroidSansThai->set_force_autohinter(true); //just looks better..i think? + Ref<DynamicFontData> FontThai; + FontThai.instance(); + FontThai->set_font_ptr(_font_NotoSansThaiUI_Regular, _font_NotoSansThaiUI_Regular_size); + FontThai->set_force_autohinter(true); //just looks better..i think? /* Source Code Pro */ @@ -119,7 +119,7 @@ void editor_register_fonts(Ref<Theme> p_theme) { dfmono->set_font_ptr(_font_source_code_pro, _font_source_code_pro_size); //dfd->set_force_autohinter(true); //just looks better..i think? - MAKE_DROID_SANS(df, int(EditorSettings::get_singleton()->get("interface/font_size")) * EDSCALE); + MAKE_DEFAULT_FONT(df, int(EditorSettings::get_singleton()->get("interface/font_size")) * EDSCALE); p_theme->set_default_theme_font(df); @@ -127,9 +127,9 @@ void editor_register_fonts(Ref<Theme> p_theme) { //Ref<BitmapFont> doc_title_font = make_font(_bi_font_doc_title_font_height,_bi_font_doc_title_font_ascent,0,_bi_font_doc_title_font_charcount,_bi_font_doc_title_font_characters,p_theme->get_icon("DocTitleFont","EditorIcons")); //Ref<BitmapFont> doc_code_font = make_font(_bi_font_doc_code_font_height,_bi_font_doc_code_font_ascent,0,_bi_font_doc_code_font_charcount,_bi_font_doc_code_font_characters,p_theme->get_icon("DocCodeFont","EditorIcons")); - MAKE_DROID_SANS(df_title, int(EDITOR_DEF("text_editor/help/help_title_font_size", 18)) * EDSCALE); + MAKE_DEFAULT_FONT(df_title, int(EDITOR_DEF("text_editor/help/help_title_font_size", 18)) * EDSCALE); - MAKE_DROID_SANS(df_doc, int(EDITOR_DEF("text_editor/help/help_font_size", 16)) * EDSCALE); + MAKE_DEFAULT_FONT(df_doc, int(EDITOR_DEF("text_editor/help/help_font_size", 16)) * EDSCALE); p_theme->set_font("doc", "EditorFonts", df_doc); p_theme->set_font("doc_title", "EditorFonts", df_title); diff --git a/editor/editor_node.cpp b/editor/editor_node.cpp index 15de8206aa..8575cd164f 100644 --- a/editor/editor_node.cpp +++ b/editor/editor_node.cpp @@ -382,20 +382,23 @@ void EditorNode::_fs_changed() { continue; if (E->get()->get_import_path() != String()) { - //imported resource +//this is an imported resource, will be reloaded if reimported via the _resources_reimported() callback +//imported resource +#if 0 uint64_t mt = FileAccess::get_modified_time(E->get()->get_import_path()); if (mt != E->get()->get_import_last_modified_time()) { print_line("success"); changed.push_back(E->get()); } +#endif + continue; + } - } else { - uint64_t mt = FileAccess::get_modified_time(E->get()->get_path()); + uint64_t mt = FileAccess::get_modified_time(E->get()->get_path()); - if (mt != E->get()->get_last_modified_time()) { - changed.push_back(E->get()); - } + if (mt != E->get()->get_last_modified_time()) { + changed.push_back(E->get()); } } @@ -410,6 +413,33 @@ void EditorNode::_fs_changed() { _mark_unsaved_scenes(); } +void EditorNode::_resources_reimported(const Vector<String> &p_resources) { + print_line("reimporting"); + List<String> scenes; //will load later + + for (int i = 0; i < p_resources.size(); i++) { + String file_type = ResourceLoader::get_resource_type(p_resources[i]); + if (file_type == "PackedScene") { + scenes.push_back(p_resources[i]); + //reload later if needed, first go with normal resources + continue; + } + + if (!ResourceCache::has(p_resources[i])) { + continue; //not loaded, no need to reload + } + //reload normally + Resource *resource = ResourceCache::get(p_resources[i]); + if (resource) { + resource->reload_from_file(); + } + } + + for (List<String>::Element *E = scenes.front(); E; E = E->next()) { + reload_scene(E->get()); + } +} + void EditorNode::_sources_changed(bool p_exist) { if (waiting_for_first_scan) { @@ -2857,6 +2887,7 @@ Error EditorNode::load_scene(const String &p_scene, bool p_ignore_broken_deps, b dependency_errors.clear(); + print_line("actually loading it"); Error err; Ref<PackedScene> sdata = ResourceLoader::load(lpath, "", true, &err); if (!sdata.is_valid()) { @@ -4179,30 +4210,25 @@ void EditorNode::_file_access_close_error_notify(const String &p_str) { void EditorNode::reload_scene(const String &p_path) { - //first of all, reload textures as they might have changed on disk + //first of all, reload internal textures, materials, meshes, etc. as they might have changed on disk + print_line("reloading: " + p_path); List<Ref<Resource> > cached; ResourceCache::get_cached_resources(&cached); List<Ref<Resource> > to_clear; //clear internal resources from previous scene from being used for (List<Ref<Resource> >::Element *E = cached.front(); E; E = E->next()) { - if (E->get()->get_path().begins_with(p_path + "::")) //subresources of existing scene + if (E->get()->get_path().find("::") != -1) { + print_line(E->get()->get_path()); + } + if (E->get()->get_path().begins_with(p_path + "::")) { //subresources of existing scene to_clear.push_back(E->get()); - - if (!cast_to<Texture>(E->get().ptr())) - continue; - if (!E->get()->get_path().is_resource_file() && !E->get()->get_path().is_abs_path()) - continue; - if (!FileAccess::exists(E->get()->get_path())) - continue; - uint64_t mt = FileAccess::get_modified_time(E->get()->get_path()); - if (mt != E->get()->get_last_modified_time()) { - E->get()->reload_from_file(); } } //so reload reloads everything, clear subresources of previous scene while (to_clear.front()) { + print_line("bye bye: " + to_clear.front()->get()->get_path()); to_clear.front()->get()->set_path(""); to_clear.pop_front(); } @@ -4234,7 +4260,8 @@ void EditorNode::reload_scene(const String &p_path) { //remove scene _remove_scene(scene_idx); //reload scene - load_scene(p_path); + + load_scene(p_path, true, false, true, true); //adjust index so tab is back a the previous position editor_data.move_edited_scene_to_index(scene_idx); get_undo_redo()->clear_history(); @@ -4426,6 +4453,8 @@ void EditorNode::_bind_methods() { ClassDB::bind_method(D_METHOD("_dim_timeout"), &EditorNode::_dim_timeout); ClassDB::bind_method(D_METHOD("_check_gui_base_size"), &EditorNode::_check_gui_base_size); + ClassDB::bind_method(D_METHOD("_resources_reimported"), &EditorNode::_resources_reimported); + ADD_SIGNAL(MethodInfo("play_pressed")); ADD_SIGNAL(MethodInfo("pause_pressed")); ADD_SIGNAL(MethodInfo("stop_pressed")); @@ -5454,6 +5483,7 @@ EditorNode::EditorNode() { EditorFileSystem::get_singleton()->connect("sources_changed", this, "_sources_changed"); EditorFileSystem::get_singleton()->connect("filesystem_changed", this, "_fs_changed"); + EditorFileSystem::get_singleton()->connect("resources_reimported", this, "_resources_reimported"); { List<StringName> tl; diff --git a/editor/editor_node.h b/editor/editor_node.h index 445ef4922e..c3ceee350a 100644 --- a/editor/editor_node.h +++ b/editor/editor_node.h @@ -422,6 +422,7 @@ private: void _prepare_history(); void _fs_changed(); + void _resources_reimported(const Vector<String> &p_resources); void _sources_changed(bool p_exist); void _node_renamed(); diff --git a/editor/editor_settings.cpp b/editor/editor_settings.cpp index 3bc85e8468..9c9eef848a 100644 --- a/editor/editor_settings.cpp +++ b/editor/editor_settings.cpp @@ -616,6 +616,7 @@ void EditorSettings::_load_defaults(Ref<ConfigFile> p_extra_config) { hints["text_editor/indent/type"] = PropertyInfo(Variant::INT, "text_editor/indent/type", PROPERTY_HINT_ENUM, "Tabs,Spaces"); set("text_editor/indent/size", 4); hints["text_editor/indent/size"] = PropertyInfo(Variant::INT, "text_editor/indent/size", PROPERTY_HINT_RANGE, "1, 64, 1"); // size of 0 crashes. + set("text_editor/indent/auto_indent", true); set("text_editor/indent/convert_indent_on_save", false); set("text_editor/indent/draw_tabs", true); diff --git a/editor/editor_themes.cpp b/editor/editor_themes.cpp index f09fe9d9ae..8943d5f0dc 100644 --- a/editor/editor_themes.cpp +++ b/editor/editor_themes.cpp @@ -284,7 +284,7 @@ Ref<Theme> create_editor_theme(const Ref<Theme> p_theme) { // Focus Ref<StyleBoxFlat> focus_sbt = make_flat_stylebox(contrast_color_1, 4, 4, 4, 4); - focus_sbt->set_filled(false); + focus_sbt->set_draw_center(false); focus_sbt->set_border_width_all(1 * EDSCALE); focus_sbt = change_border_color(focus_sbt, contrast_color_2); theme->set_stylebox("Focus", "EditorStyles", focus_sbt); @@ -301,7 +301,7 @@ Ref<Theme> create_editor_theme(const Ref<Theme> p_theme) { Ref<StyleBoxFlat> style_menu_hover_border = make_flat_stylebox(highlight_color, 4, 4, 4, 4); Ref<StyleBoxFlat> style_menu_hover_bg = make_flat_stylebox(dark_color_2, 4, 4, 4, 4); - style_menu_hover_border->set_filled(false); + style_menu_hover_border->set_draw_center(false); style_menu_hover_border->set_border_width(MARGIN_BOTTOM, border_width); style_menu_hover_border->set_border_color_all(highlight_color); style_menu_hover_border->set_expand_margin_size(MARGIN_BOTTOM, border_width); @@ -343,7 +343,7 @@ Ref<Theme> create_editor_theme(const Ref<Theme> p_theme) { theme->set_stylebox("Content", "EditorStyles", style_content_panel_vp); Ref<StyleBoxFlat> style_button_type = make_flat_stylebox(dark_color_1, 6, 4, 6, 4); - style_button_type->set_filled(true); + style_button_type->set_draw_center(true); style_button_type->set_border_width_all(border_width); style_button_type->set_border_color_all(contrast_color_2); @@ -454,7 +454,7 @@ Ref<Theme> create_editor_theme(const Ref<Theme> p_theme) { theme->set_stylebox("selected", "Tree", style_tree_selected); Ref<StyleBoxFlat> style_tree_cursor = make_flat_stylebox(HIGHLIGHT_COLOR_BG, 4, 4, 4, 4); - style_tree_cursor->set_filled(false); + style_tree_cursor->set_draw_center(false); style_tree_cursor->set_border_width_all(border_width); style_tree_cursor->set_border_color_all(contrast_color_1); @@ -481,7 +481,7 @@ Ref<Theme> create_editor_theme(const Ref<Theme> p_theme) { style_itemlist_bg->set_border_color_all(dark_color_3); Ref<StyleBoxFlat> style_itemlist_cursor = make_flat_stylebox(highlight_color, 0, 0, 0, 0); - style_itemlist_cursor->set_filled(false); + style_itemlist_cursor->set_draw_center(false); style_itemlist_cursor->set_border_width_all(border_width); style_itemlist_cursor->set_border_color_all(HIGHLIGHT_COLOR_BG); theme->set_stylebox("cursor", "ItemList", style_itemlist_cursor); @@ -495,7 +495,7 @@ Ref<Theme> create_editor_theme(const Ref<Theme> p_theme) { Ref<StyleBoxFlat> style_tab_fg = make_flat_stylebox(tab_color, 15, 5, 15, 5); Ref<StyleBoxFlat> style_tab_bg = make_flat_stylebox(tab_color, 15, 5, 15, 5); - style_tab_bg->set_filled(false); + style_tab_bg->set_draw_center(false); // Tabs & TabContainer theme->set_stylebox("tab_fg", "TabContainer", style_tab_fg); @@ -524,7 +524,7 @@ Ref<Theme> create_editor_theme(const Ref<Theme> p_theme) { Ref<StyleBoxFlat> style_tab_fg_debugger = make_flat_stylebox(dark_color_2, 10, 5, 10, 5); Ref<StyleBoxFlat> style_tab_bg_debugger = make_flat_stylebox(dark_color_2, 10, 5, 10, 5); - style_tab_bg_debugger->set_filled(false); + style_tab_bg_debugger->set_draw_center(false); theme->set_stylebox("DebuggerTabFG", "EditorStyles", style_tab_fg_debugger); theme->set_stylebox("DebuggerTabBG", "EditorStyles", style_tab_bg_debugger); diff --git a/editor/export_template_manager.h b/editor/export_template_manager.h index ce6d8024ae..c77f85688f 100644 --- a/editor/export_template_manager.h +++ b/editor/export_template_manager.h @@ -1,5 +1,5 @@ /*************************************************************************/ -/* export_template_manager.cpp */ +/* export_template_manager.h */ /*************************************************************************/ /* This file is part of: */ /* GODOT ENGINE */ diff --git a/editor/import/resource_importer_scene.cpp b/editor/import/resource_importer_scene.cpp index 7fa76713f3..594728d2e0 100644 --- a/editor/import/resource_importer_scene.cpp +++ b/editor/import/resource_importer_scene.cpp @@ -1167,7 +1167,8 @@ Error ResourceImporterScene::import(const String &p_source_file, const String &p memdelete(scene); - EditorNode::get_singleton()->reload_scene(p_source_file); + //this is not the time to reimport, wait until import process is done, import file is saved, etc. + //EditorNode::get_singleton()->reload_scene(p_source_file); return OK; } diff --git a/editor/import/resource_importer_texture.cpp b/editor/import/resource_importer_texture.cpp index b0b8faf2db..ade3550daa 100644 --- a/editor/import/resource_importer_texture.cpp +++ b/editor/import/resource_importer_texture.cpp @@ -357,7 +357,7 @@ Error ResourceImporterTexture::import(const String &p_source_file, const String bool force_rgbe = int(p_options["compress/hdr_mode"]) == 1; bool hdr_as_srgb = p_options["process/HDR_as_SRGB"]; int normal = p_options["compress/normal_map"]; - float scale = p_options["scale"]; + float scale = p_options["svg/scale"]; Ref<Image> image; image.instance(); diff --git a/editor/import_dock.cpp b/editor/import_dock.cpp index 6662fa9f21..112e3abcb5 100644 --- a/editor/import_dock.cpp +++ b/editor/import_dock.cpp @@ -28,6 +28,7 @@ /* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ /*************************************************************************/ #include "import_dock.h" +#include "editor_node.h" class ImportDockParameters : public Object { GDCLASS(ImportDockParameters, Object) @@ -264,16 +265,14 @@ void ImportDock::set_edit_multiple_paths(const Vector<String> &p_paths) { void ImportDock::_preset_selected(int p_idx) { - switch (p_idx) { - case ITEM_SET_AS_DEFAULT: { - List<ResourceImporter::ImportOption> options; - - params->importer->get_import_options(&options, p_idx); + int item_id = preset->get_popup()->get_item_id(p_idx); + switch (item_id) { + case ITEM_SET_AS_DEFAULT: { Dictionary d; - for (List<ResourceImporter::ImportOption>::Element *E = options.front(); E; E = E->next()) { - d[E->get().option.name] = E->get().default_value; + for (const List<PropertyInfo>::Element *E = params->properties.front(); E; E = E->next()) { + d[E->get().name] = params->values[E->get().name]; } ProjectSettings::get_singleton()->set("importer_defaults/" + params->importer->get_importer_name(), d); @@ -350,6 +349,15 @@ void ImportDock::_reimport() { EditorFileSystem::get_singleton()->emit_signal("filesystem_changed"); //it changed, so force emitting the signal } +void ImportDock::_notification(int p_what) { + switch (p_what) { + + case EditorSettings::NOTIFICATION_EDITOR_SETTINGS_CHANGED: { + + imported->add_style_override("normal", get_stylebox("normal", "LineEdit")); + } break; + } +} void ImportDock::_bind_methods() { ClassDB::bind_method(D_METHOD("_reimport"), &ImportDock::_reimport); @@ -365,8 +373,8 @@ void ImportDock::initialize_import_options() const { ImportDock::ImportDock() { - imported = memnew(LineEdit); - imported->set_editable(false); + imported = memnew(Label); + imported->add_style_override("normal", EditorNode::get_singleton()->get_gui_base()->get_stylebox("normal", "LineEdit")); add_child(imported); HBoxContainer *hb = memnew(HBoxContainer); add_margin_child(TTR("Import As:"), hb); diff --git a/editor/import_dock.h b/editor/import_dock.h index afb899d9c9..029c458320 100644 --- a/editor/import_dock.h +++ b/editor/import_dock.h @@ -41,7 +41,7 @@ class ImportDockParameters; class ImportDock : public VBoxContainer { GDCLASS(ImportDock, VBoxContainer) - LineEdit *imported; + Label *imported; OptionButton *import_as; MenuButton *preset; PropertyEditor *import_opts; @@ -65,6 +65,7 @@ class ImportDock : public VBoxContainer { protected: static void _bind_methods(); + void _notification(int p_what); public: void set_edit_path(const String &p_path); diff --git a/editor/plugins/gradient_editor_plugin.cpp b/editor/plugins/gradient_editor_plugin.cpp index abd2559d1f..51f00e5751 100644 --- a/editor/plugins/gradient_editor_plugin.cpp +++ b/editor/plugins/gradient_editor_plugin.cpp @@ -1,5 +1,5 @@ /*************************************************************************/ -/* color_ramp_editor_plugin.cpp */ +/* gradient_editor_plugin.cpp */ /*************************************************************************/ /* This file is part of: */ /* GODOT ENGINE */ diff --git a/editor/plugins/gradient_editor_plugin.h b/editor/plugins/gradient_editor_plugin.h index c169fa0947..ff7bf858c7 100644 --- a/editor/plugins/gradient_editor_plugin.h +++ b/editor/plugins/gradient_editor_plugin.h @@ -1,5 +1,5 @@ /*************************************************************************/ -/* color_ramp_editor_plugin.h */ +/* gradient_editor_plugin.h */ /*************************************************************************/ /* This file is part of: */ /* GODOT ENGINE */ diff --git a/editor/plugins/script_text_editor.cpp b/editor/plugins/script_text_editor.cpp index a8f1b00776..33890d890d 100644 --- a/editor/plugins/script_text_editor.cpp +++ b/editor/plugins/script_text_editor.cpp @@ -120,17 +120,29 @@ void ScriptTextEditor::_load_theme_settings() { //colorize core types Color basetype_color = EDITOR_DEF("text_editor/highlighting/base_type_color", Color(0.3, 0.3, 0.0)); + text_edit->add_keyword_color("String", basetype_color); text_edit->add_keyword_color("Vector2", basetype_color); + text_edit->add_keyword_color("Rect2", basetype_color); + text_edit->add_keyword_color("Transform2D", basetype_color); text_edit->add_keyword_color("Vector3", basetype_color); + text_edit->add_keyword_color("Rect3", basetype_color); + text_edit->add_keyword_color("Basis", basetype_color); text_edit->add_keyword_color("Plane", basetype_color); - text_edit->add_keyword_color("Quat", basetype_color); - text_edit->add_keyword_color("AABB", basetype_color); - text_edit->add_keyword_color("Matrix3", basetype_color); text_edit->add_keyword_color("Transform", basetype_color); + text_edit->add_keyword_color("Quat", basetype_color); text_edit->add_keyword_color("Color", basetype_color); - text_edit->add_keyword_color("Image", basetype_color); - text_edit->add_keyword_color("Rect2", basetype_color); + text_edit->add_keyword_color("Object", basetype_color); text_edit->add_keyword_color("NodePath", basetype_color); + text_edit->add_keyword_color("RID", basetype_color); + text_edit->add_keyword_color("Dictionary", basetype_color); + text_edit->add_keyword_color("Array", basetype_color); + text_edit->add_keyword_color("PoolByteArray", basetype_color); + text_edit->add_keyword_color("PoolIntArray", basetype_color); + text_edit->add_keyword_color("PoolRealArray", basetype_color); + text_edit->add_keyword_color("PoolStringArray", basetype_color); + text_edit->add_keyword_color("PoolVector2Array", basetype_color); + text_edit->add_keyword_color("PoolVector3Array", basetype_color); + text_edit->add_keyword_color("PoolColorArray", basetype_color); //colorize engine types Color type_color = EDITOR_DEF("text_editor/highlighting/engine_type_color", Color(0.0, 0.2, 0.4)); diff --git a/editor/plugins/shader_editor_plugin.cpp b/editor/plugins/shader_editor_plugin.cpp index 8672892b5a..13b0391a87 100644 --- a/editor/plugins/shader_editor_plugin.cpp +++ b/editor/plugins/shader_editor_plugin.cpp @@ -280,6 +280,7 @@ void ShaderEditor::_editor_settings_changed() { shader_editor->get_text_edit()->set_scroll_pass_end_of_file(EditorSettings::get_singleton()->get("text_editor/cursor/scroll_past_end_of_file")); shader_editor->get_text_edit()->set_indent_size(EditorSettings::get_singleton()->get("text_editor/indent/size")); shader_editor->get_text_edit()->set_indent_using_spaces(EditorSettings::get_singleton()->get("text_editor/indent/type")); + shader_editor->get_text_edit()->set_auto_indent(EditorSettings::get_singleton()->get("text_editor/indent/auto_indent")); shader_editor->get_text_edit()->set_draw_tabs(EditorSettings::get_singleton()->get("text_editor/indent/draw_tabs")); shader_editor->get_text_edit()->set_show_line_numbers(EditorSettings::get_singleton()->get("text_editor/line_numbers/show_line_numbers")); shader_editor->get_text_edit()->set_syntax_coloring(EditorSettings::get_singleton()->get("text_editor/highlighting/syntax_highlighting")); diff --git a/editor/plugins/spatial_editor_plugin.cpp b/editor/plugins/spatial_editor_plugin.cpp index bc5c700959..d2e60ef9ce 100644 --- a/editor/plugins/spatial_editor_plugin.cpp +++ b/editor/plugins/spatial_editor_plugin.cpp @@ -3505,7 +3505,7 @@ void SpatialEditor::_init_indicators() { gizmo_hl = Ref<SpatialMaterial>(memnew(SpatialMaterial)); gizmo_hl->set_flag(SpatialMaterial::FLAG_UNSHADED, true); - gizmo_hl->set_flag(SpatialMaterial::FLAG_ONTOP, true); + gizmo_hl->set_on_top_of_alpha(); gizmo_hl->set_feature(SpatialMaterial::FEATURE_TRANSPARENT, true); gizmo_hl->set_albedo(Color(1, 1, 1, gizmo_alph + 0.2f)); gizmo_hl->set_cull_mode(SpatialMaterial::CULL_DISABLED); @@ -3518,7 +3518,7 @@ void SpatialEditor::_init_indicators() { Ref<SpatialMaterial> mat = memnew(SpatialMaterial); mat->set_flag(SpatialMaterial::FLAG_UNSHADED, true); - mat->set_flag(SpatialMaterial::FLAG_ONTOP, true); + mat->set_on_top_of_alpha(); mat->set_feature(SpatialMaterial::FEATURE_TRANSPARENT, true); Color col; col[i] = 1.0; @@ -3613,7 +3613,7 @@ void SpatialEditor::_init_indicators() { Ref<SpatialMaterial> plane_mat = memnew(SpatialMaterial); plane_mat->set_flag(SpatialMaterial::FLAG_UNSHADED, true); - plane_mat->set_flag(SpatialMaterial::FLAG_ONTOP, true); + plane_mat->set_on_top_of_alpha(); plane_mat->set_feature(SpatialMaterial::FEATURE_TRANSPARENT, true); plane_mat->set_cull_mode(SpatialMaterial::CULL_DISABLED); Color col; diff --git a/editor/project_manager.cpp b/editor/project_manager.cpp index e042e9cc96..323a36154e 100644 --- a/editor/project_manager.cpp +++ b/editor/project_manager.cpp @@ -1226,7 +1226,7 @@ ProjectManager::ProjectManager() { String cp; cp.push_back(0xA9); cp.push_back(0); - OS::get_singleton()->set_window_title(_MKSTR(VERSION_NAME) + String(" - ") + TTR("Project Manager") + " - " + cp + " 2008-2017 Juan Linietsky, Ariel Manzur."); + OS::get_singleton()->set_window_title(_MKSTR(VERSION_NAME) + String(" - ") + TTR("Project Manager") + " - " + cp + " 2008-2017 Juan Linietsky, Ariel Manzur & Godot Contributors"); HBoxContainer *top_hb = memnew(HBoxContainer); vb->add_child(top_hb); diff --git a/editor/project_settings_editor.cpp b/editor/project_settings_editor.cpp index 94fce45733..9817ab176e 100644 --- a/editor/project_settings_editor.cpp +++ b/editor/project_settings_editor.cpp @@ -1,5 +1,5 @@ /*************************************************************************/ -/* project_settings.cpp */ +/* project_settings_editor.cpp */ /*************************************************************************/ /* This file is part of: */ /* GODOT ENGINE */ diff --git a/editor/project_settings_editor.h b/editor/project_settings_editor.h index e4e2345692..ceec089953 100644 --- a/editor/project_settings_editor.h +++ b/editor/project_settings_editor.h @@ -1,5 +1,5 @@ /*************************************************************************/ -/* project_settings.h */ +/* project_settings_editor.h */ /*************************************************************************/ /* This file is part of: */ /* GODOT ENGINE */ diff --git a/editor/script_create_dialog.cpp b/editor/script_create_dialog.cpp index d0e2e0c240..089c054b59 100644 --- a/editor/script_create_dialog.cpp +++ b/editor/script_create_dialog.cpp @@ -352,9 +352,16 @@ void ScriptCreateDialog::_path_changed(const String &p_path) { /* Does file already exist */ DirAccess *f = DirAccess::create(DirAccess::ACCESS_RESOURCES); - if (f->file_exists(p) && !(f->current_is_dir())) { + if (f->dir_exists(p)) { + is_new_script_created = false; + is_path_valid = false; + _msg_path_valid(false, TTR("Directory of the same name exists")); + } else if (f->file_exists(p)) { is_new_script_created = false; is_path_valid = true; + _msg_path_valid(true, TTR("File exists, will be reused")); + } else { + path_error_label->set_text(""); } memdelete(f); _update_dialog(); diff --git a/editor/spatial_editor_gizmos.cpp b/editor/spatial_editor_gizmos.cpp index c127b9a2f1..9c7ea506aa 100644 --- a/editor/spatial_editor_gizmos.cpp +++ b/editor/spatial_editor_gizmos.cpp @@ -580,7 +580,7 @@ Ref<SpatialMaterial> EditorSpatialGizmo::create_material(const String &p_name, c } if (p_on_top && is_selected()) { - line_material->set_flag(SpatialMaterial::FLAG_ONTOP, true); + line_material->set_on_top_of_alpha(); } line_material->set_albedo(color); @@ -624,7 +624,7 @@ Ref<SpatialMaterial> EditorSpatialGizmo::create_icon_material(const String &p_na icon->set_billboard_mode(SpatialMaterial::BILLBOARD_ENABLED); if (p_on_top && is_selected()) { - icon->set_flag(SpatialMaterial::FLAG_ONTOP, true); + icon->set_on_top_of_alpha(); } SpatialEditorGizmos::singleton->material_cache[name] = icon; @@ -3411,7 +3411,7 @@ SpatialEditorGizmos::SpatialEditorGizmos() { handle_material = Ref<SpatialMaterial>(memnew(SpatialMaterial)); handle_material->set_flag(SpatialMaterial::FLAG_UNSHADED, true); - handle_material->set_flag(SpatialMaterial::FLAG_ONTOP, true); + handle_material->set_on_top_of_alpha(); handle_material->set_albedo(Color(0.8, 0.8, 0.8)); handle_material_billboard = handle_material->duplicate(); handle_material_billboard->set_billboard_mode(SpatialMaterial::BILLBOARD_ENABLED); @@ -3426,11 +3426,11 @@ SpatialEditorGizmos::SpatialEditorGizmos() { handle2_material->set_feature(SpatialMaterial::FEATURE_TRANSPARENT, true); handle2_material->set_flag(SpatialMaterial::FLAG_ALBEDO_FROM_VERTEX_COLOR, true); handle2_material->set_flag(SpatialMaterial::FLAG_SRGB_VERTEX_COLOR, true); - handle2_material->set_flag(SpatialMaterial::FLAG_ONTOP, true); + handle2_material->set_on_top_of_alpha(); handle2_material_billboard = handle2_material->duplicate(); handle2_material_billboard->set_billboard_mode(SpatialMaterial::BILLBOARD_ENABLED); handle2_material_billboard->set_billboard_mode(SpatialMaterial::BILLBOARD_ENABLED); - handle2_material_billboard->set_flag(SpatialMaterial::FLAG_ONTOP, true); + handle2_material_billboard->set_on_top_of_alpha(); EDITOR_DEF("editors/3d_gizmos/gizmo_colors/light", Color(1, 1, 0.2)); EDITOR_DEF("editors/3d_gizmos/gizmo_colors/stream_player_3d", Color(0.4, 0.8, 1)); @@ -3490,7 +3490,7 @@ SpatialEditorGizmos::SpatialEditorGizmos() { skeleton_material = create_line_material(Color(0.6, 1.0, 0.3)); skeleton_material->set_cull_mode(SpatialMaterial::CULL_DISABLED); skeleton_material->set_flag(SpatialMaterial::FLAG_UNSHADED, true); - skeleton_material->set_flag(SpatialMaterial::FLAG_ONTOP, true); + skeleton_material->set_on_top_of_alpha(); skeleton_material->set_depth_draw_mode(SpatialMaterial::DEPTH_DRAW_DISABLED); //position 3D Shared mesh diff --git a/main/main.cpp b/main/main.cpp index c4cc30e602..7b2a890a8e 100644 --- a/main/main.cpp +++ b/main/main.cpp @@ -1112,10 +1112,20 @@ bool Main::start() { test = args[i + 1]; } else if (args[i] == "--export") { editor = true; //needs editor - _export_preset = args[i + 1]; + if (i + 1 < args.size()) { + _export_preset = args[i + 1]; + } else { + ERR_PRINT("Export preset name not specified"); + return false; + } } else if (args[i] == "--export-debug") { editor = true; //needs editor - _export_preset = args[i + 1]; + if (i + 1 < args.size()) { + _export_preset = args[i + 1]; + } else { + ERR_PRINT("Export preset name not specified"); + return false; + } export_debug = true; } else { // The parameter does not match anything known, don't skip the next argument diff --git a/main/tests/test_main.cpp b/main/tests/test_main.cpp index 794bdb757b..645db2826e 100644 --- a/main/tests/test_main.cpp +++ b/main/tests/test_main.cpp @@ -37,6 +37,7 @@ #include "test_image.h" #include "test_io.h" #include "test_math.h" +#include "test_ordered_hash_map.h" #include "test_physics.h" #include "test_physics_2d.h" #include "test_render.h" @@ -130,6 +131,11 @@ MainLoop *test_main(String p_test, const List<String> &p_args) { return TestImage::test(); } + if (p_test == "ordered_hash_map") { + + return TestOrderedHashMap::test(); + } + return NULL; } diff --git a/main/tests/test_ordered_hash_map.cpp b/main/tests/test_ordered_hash_map.cpp new file mode 100644 index 0000000000..89f4bf8593 --- /dev/null +++ b/main/tests/test_ordered_hash_map.cpp @@ -0,0 +1,171 @@ +/*************************************************************************/ +/* test_ordered_hash_map.cpp */ +/*************************************************************************/ +/* This file is part of: */ +/* GODOT ENGINE */ +/* http://www.godotengine.org */ +/*************************************************************************/ +/* Copyright (c) 2007-2017 Juan Linietsky, Ariel Manzur. */ +/* Copyright (c) 2014-2017 Godot Engine contributors (cf. AUTHORS.md) */ +/* */ +/* 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: */ +/* */ +/* 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. */ +/*************************************************************************/ + +#include "ordered_hash_map.h" +#include "os/os.h" +#include "pair.h" +#include "vector.h" + +namespace TestOrderedHashMap { + +bool test_insert() { + OrderedHashMap<int, int> map; + OrderedHashMap<int, int>::Element e = map.insert(42, 84); + + return e && e.key() == 42 && e.get() == 84 && e.value() == 84 && map[42] == 84 && map.has(42) && map.find(42); +} + +bool test_insert_overwrite() { + OrderedHashMap<int, int> map; + map.insert(42, 84); + map.insert(42, 1234); + + return map[42] == 1234; +} + +bool test_erase_via_element() { + OrderedHashMap<int, int> map; + OrderedHashMap<int, int>::Element e = map.insert(42, 84); + + map.erase(e); + return !e && !map.has(42) && !map.find(42); +} + +bool test_erase_via_key() { + OrderedHashMap<int, int> map; + map.insert(42, 84); + map.erase(42); + return !map.has(42) && !map.find(42); +} + +bool test_size() { + OrderedHashMap<int, int> map; + map.insert(42, 84); + map.insert(123, 84); + map.insert(123, 84); + map.insert(0, 84); + map.insert(123485, 84); + + return map.size() == 4; +} + +bool test_iteration() { + OrderedHashMap<int, int> map; + map.insert(42, 84); + map.insert(123, 12385); + map.insert(0, 12934); + map.insert(123485, 1238888); + map.insert(123, 111111); + + Vector<Pair<int, int> > expected; + expected.push_back(Pair<int, int>(42, 84)); + expected.push_back(Pair<int, int>(123, 111111)); + expected.push_back(Pair<int, int>(0, 12934)); + expected.push_back(Pair<int, int>(123485, 1238888)); + + int idx = 0; + for (OrderedHashMap<int, int>::Element E = map.front(); E; E = E.next()) { + if (expected[idx] != Pair<int, int>(E.key(), E.value())) { + return false; + } + ++idx; + } + return true; +} + +bool test_const_iteration(const OrderedHashMap<int, int> &map) { + Vector<Pair<int, int> > expected; + expected.push_back(Pair<int, int>(42, 84)); + expected.push_back(Pair<int, int>(123, 111111)); + expected.push_back(Pair<int, int>(0, 12934)); + expected.push_back(Pair<int, int>(123485, 1238888)); + + int idx = 0; + for (OrderedHashMap<int, int>::ConstElement E = map.front(); E; E = E.next()) { + if (expected[idx] != Pair<int, int>(E.key(), E.value())) { + return false; + } + ++idx; + } + return true; +} + +bool test_const_iteration() { + OrderedHashMap<int, int> map; + map.insert(42, 84); + map.insert(123, 12385); + map.insert(0, 12934); + map.insert(123485, 1238888); + map.insert(123, 111111); + + return test_const_iteration(map); +} + +typedef bool (*TestFunc)(void); + +TestFunc test_funcs[] = { + + test_insert, + test_insert_overwrite, + test_erase_via_element, + test_erase_via_key, + test_size, + test_iteration, + test_const_iteration, + 0 + +}; + +MainLoop *test() { + + int count = 0; + int passed = 0; + + while (true) { + if (!test_funcs[count]) + break; + bool pass = test_funcs[count](); + if (pass) + passed++; + OS::get_singleton()->print("\t%s\n", pass ? "PASS" : "FAILED"); + + count++; + } + + OS::get_singleton()->print("\n\n\n"); + OS::get_singleton()->print("*************\n"); + OS::get_singleton()->print("***TOTALS!***\n"); + OS::get_singleton()->print("*************\n"); + + OS::get_singleton()->print("Passed %i of %i tests\n", passed, count); + + return NULL; +} +} // namespace TestOrderedHashMap
\ No newline at end of file diff --git a/main/tests/test_ordered_hash_map.h b/main/tests/test_ordered_hash_map.h new file mode 100644 index 0000000000..0cde250f56 --- /dev/null +++ b/main/tests/test_ordered_hash_map.h @@ -0,0 +1,38 @@ +/*************************************************************************/ +/* test_ordered_hash_map.h */ +/*************************************************************************/ +/* This file is part of: */ +/* GODOT ENGINE */ +/* http://www.godotengine.org */ +/*************************************************************************/ +/* Copyright (c) 2007-2017 Juan Linietsky, Ariel Manzur. */ +/* Copyright (c) 2014-2017 Godot Engine contributors (cf. AUTHORS.md) */ +/* */ +/* 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: */ +/* */ +/* 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. */ +/*************************************************************************/ +#ifndef TEST_ORDERED_HASH_MAP_H +#define TEST_ORDERED_HASH_MAP_H + +namespace TestOrderedHashMap { + +MainLoop *test(); +} + +#endif diff --git a/modules/gdnative/gdnative.cpp b/modules/gdnative/gdnative.cpp index 7faf21c5a1..ded987557c 100644 --- a/modules/gdnative/gdnative.cpp +++ b/modules/gdnative/gdnative.cpp @@ -40,7 +40,7 @@ const String init_symbol = "godot_gdnative_init"; const String terminate_symbol = "godot_gdnative_terminate"; -String GDNativeLibrary::platform_names[NUM_PLATFORMS] = { +String GDNativeLibrary::platform_names[NUM_PLATFORMS + 1] = { "X11_32bit", "X11_64bit", "Windows_32bit", @@ -48,11 +48,15 @@ String GDNativeLibrary::platform_names[NUM_PLATFORMS] = { "OSX", "Android", - "iOS", - "WebAssembly" + "iOS_32bit", + "iOS_64bit", + + "WebAssembly", + + "" }; -String GDNativeLibrary::platform_lib_ext[NUM_PLATFORMS] = { +String GDNativeLibrary::platform_lib_ext[NUM_PLATFORMS + 1] = { "so", "so", "dll", @@ -60,21 +64,30 @@ String GDNativeLibrary::platform_lib_ext[NUM_PLATFORMS] = { "dylib", "so", + "dylib", + "dylib", + + "wasm", - "wasm" + "" }; -// TODO(karroffel): make this actually do the right thing. GDNativeLibrary::Platform GDNativeLibrary::current_platform = #if defined(X11_ENABLED) - X11_64BIT; + (sizeof(void *) == 8 ? X11_64BIT : X11_32BIT); #elif defined(WINDOWS_ENABLED) - WINDOWS_64BIT; + (sizeof(void *) == 8 ? WINDOWS_64BIT : WINDOWS_32BIT); #elif defined(OSX_ENABLED) OSX; +#elif defined(IPHONE_ENABLED) + (sizeof(void *) == 8 ? IOS_64BIT : IOS_32BIT); +#elif defined(ANDROID_ENABLED) + ANDROID; +#elif defined(JAVASCRIPT_ENABLED) + WASM; #else - X11_64BIT; // need a sensible default.. + NUM_PLATFORMS; #endif GDNativeLibrary::GDNativeLibrary() @@ -151,7 +164,10 @@ String GDNativeLibrary::get_library_path(StringName p_platform) const { } String GDNativeLibrary::get_active_library_path() const { - return library_paths[GDNativeLibrary::current_platform]; + if (GDNativeLibrary::current_platform != NUM_PLATFORMS) { + return library_paths[GDNativeLibrary::current_platform]; + } + return ""; } GDNative::GDNative() { diff --git a/modules/gdnative/gdnative.h b/modules/gdnative/gdnative.h index bec746a441..dc1c3507ec 100644 --- a/modules/gdnative/gdnative.h +++ b/modules/gdnative/gdnative.h @@ -48,11 +48,17 @@ class GDNativeLibrary : public Resource { // NOTE(karroffel): I heard OSX 32 bit is dead, so 64 only OSX, - // TODO(karroffel): all different android versions and archs + // Android .so files must be located in directories corresponding to Android ABI names: + // https://developer.android.com/ndk/guides/abis.html + // Android runtime will select the matching library depending on the device. + // The value here must simply point to the .so name, for example: + // "res://libmy_gdnative.so" or "libmy_gdnative.so", + // while in the project the actual paths can be "lib/android/armeabi-v7a/libmy_gdnative.so", + // "lib/android/arm64-v8a/libmy_gdnative.so". ANDROID, - // TODO(karroffe): all different iOS versions and archs - IOS, + IOS_32BIT, + IOS_64BIT, // TODO(karroffel): figure out how to deal with web stuff at all... WASM, @@ -64,10 +70,9 @@ class GDNativeLibrary : public Resource { }; - static String platform_names[NUM_PLATFORMS]; - static String platform_lib_ext[NUM_PLATFORMS]; + static String platform_names[NUM_PLATFORMS + 1]; + static String platform_lib_ext[NUM_PLATFORMS + 1]; - // TODO(karroffel): make this actually do something lol. static Platform current_platform; String library_paths[NUM_PLATFORMS]; diff --git a/modules/gdnative/godot/array.h b/modules/gdnative/godot/array.h index 434ce958c9..08f73c8785 100644 --- a/modules/gdnative/godot/array.h +++ b/modules/gdnative/godot/array.h @@ -37,7 +37,7 @@ extern "C" { #include <stdint.h> -#define GODOT_ARRAY_SIZE 8 +#define GODOT_ARRAY_SIZE sizeof(void *) #ifndef GODOT_CORE_API_GODOT_ARRAY_TYPE_DEFINED #define GODOT_CORE_API_GODOT_ARRAY_TYPE_DEFINED diff --git a/modules/gdnative/godot/dictionary.h b/modules/gdnative/godot/dictionary.h index bbe40f23c3..10d580af08 100644 --- a/modules/gdnative/godot/dictionary.h +++ b/modules/gdnative/godot/dictionary.h @@ -36,7 +36,7 @@ extern "C" { #include <stdint.h> -#define GODOT_DICTIONARY_SIZE 8 +#define GODOT_DICTIONARY_SIZE sizeof(void *) #ifndef GODOT_CORE_API_GODOT_DICTIONARY_TYPE_DEFINED #define GODOT_CORE_API_GODOT_DICTIONARY_TYPE_DEFINED diff --git a/modules/gdnative/godot/gdnative.h b/modules/gdnative/godot/gdnative.h index 8b289da1f5..c71a7ae1ef 100644 --- a/modules/gdnative/godot/gdnative.h +++ b/modules/gdnative/godot/gdnative.h @@ -56,7 +56,7 @@ extern "C" { #define GDAPI GDCALLINGCONV #endif #else -#define GDCALLINGCONV __attribute__((sysv_abi)) +#define GDCALLINGCONV __attribute__((sysv_abi, visibility("default"))) #define GDAPI GDCALLINGCONV #endif diff --git a/modules/gdnative/godot/node_path.h b/modules/gdnative/godot/node_path.h index 3e2a99e461..2f71ddd59d 100644 --- a/modules/gdnative/godot/node_path.h +++ b/modules/gdnative/godot/node_path.h @@ -36,7 +36,7 @@ extern "C" { #include <stdint.h> -#define GODOT_NODE_PATH_SIZE 8 +#define GODOT_NODE_PATH_SIZE sizeof(void *) #ifndef GODOT_CORE_API_GODOT_NODE_PATH_TYPE_DEFINED #define GODOT_CORE_API_GODOT_NODE_PATH_TYPE_DEFINED diff --git a/modules/gdnative/godot/pool_arrays.h b/modules/gdnative/godot/pool_arrays.h index ecd85ddfe8..1b51dca38c 100644 --- a/modules/gdnative/godot/pool_arrays.h +++ b/modules/gdnative/godot/pool_arrays.h @@ -38,7 +38,7 @@ extern "C" { /////// PoolByteArray -#define GODOT_POOL_BYTE_ARRAY_SIZE 8 +#define GODOT_POOL_BYTE_ARRAY_SIZE sizeof(void *) #ifndef GODOT_CORE_API_GODOT_POOL_BYTE_ARRAY_TYPE_DEFINED #define GODOT_CORE_API_GODOT_POOL_BYTE_ARRAY_TYPE_DEFINED @@ -49,7 +49,7 @@ typedef struct { /////// PoolIntArray -#define GODOT_POOL_INT_ARRAY_SIZE 8 +#define GODOT_POOL_INT_ARRAY_SIZE sizeof(void *) #ifndef GODOT_CORE_API_GODOT_POOL_INT_ARRAY_TYPE_DEFINED #define GODOT_CORE_API_GODOT_POOL_INT_ARRAY_TYPE_DEFINED @@ -60,7 +60,7 @@ typedef struct { /////// PoolRealArray -#define GODOT_POOL_REAL_ARRAY_SIZE 8 +#define GODOT_POOL_REAL_ARRAY_SIZE sizeof(void *) #ifndef GODOT_CORE_API_GODOT_POOL_REAL_ARRAY_TYPE_DEFINED #define GODOT_CORE_API_GODOT_POOL_REAL_ARRAY_TYPE_DEFINED @@ -71,7 +71,7 @@ typedef struct { /////// PoolStringArray -#define GODOT_POOL_STRING_ARRAY_SIZE 8 +#define GODOT_POOL_STRING_ARRAY_SIZE sizeof(void *) #ifndef GODOT_CORE_API_GODOT_POOL_STRING_ARRAY_TYPE_DEFINED #define GODOT_CORE_API_GODOT_POOL_STRING_ARRAY_TYPE_DEFINED @@ -82,7 +82,7 @@ typedef struct { /////// PoolVector2Array -#define GODOT_POOL_VECTOR2_ARRAY_SIZE 8 +#define GODOT_POOL_VECTOR2_ARRAY_SIZE sizeof(void *) #ifndef GODOT_CORE_API_GODOT_POOL_VECTOR2_ARRAY_TYPE_DEFINED #define GODOT_CORE_API_GODOT_POOL_VECTOR2_ARRAY_TYPE_DEFINED @@ -93,7 +93,7 @@ typedef struct { /////// PoolVector3Array -#define GODOT_POOL_VECTOR3_ARRAY_SIZE 8 +#define GODOT_POOL_VECTOR3_ARRAY_SIZE sizeof(void *) #ifndef GODOT_CORE_API_GODOT_POOL_VECTOR3_ARRAY_TYPE_DEFINED #define GODOT_CORE_API_GODOT_POOL_VECTOR3_ARRAY_TYPE_DEFINED @@ -104,7 +104,7 @@ typedef struct { /////// PoolColorArray -#define GODOT_POOL_COLOR_ARRAY_SIZE 8 +#define GODOT_POOL_COLOR_ARRAY_SIZE sizeof(void *) #ifndef GODOT_CORE_API_GODOT_POOL_COLOR_ARRAY_TYPE_DEFINED #define GODOT_CORE_API_GODOT_POOL_COLOR_ARRAY_TYPE_DEFINED diff --git a/modules/gdnative/godot/rid.h b/modules/gdnative/godot/rid.h index b685157cec..c56ff38735 100644 --- a/modules/gdnative/godot/rid.h +++ b/modules/gdnative/godot/rid.h @@ -36,7 +36,7 @@ extern "C" { #include <stdint.h> -#define GODOT_RID_SIZE 8 +#define GODOT_RID_SIZE sizeof(void *) #ifndef GODOT_CORE_API_GODOT_RID_TYPE_DEFINED #define GODOT_CORE_API_GODOT_RID_TYPE_DEFINED diff --git a/modules/gdnative/godot/string.cpp b/modules/gdnative/godot/string.cpp index 3790b6ea95..1282cf95e5 100644 --- a/modules/gdnative/godot/string.cpp +++ b/modules/gdnative/godot/string.cpp @@ -232,7 +232,7 @@ godot_int GDAPI godot_string_findn_from(const godot_string *p_self, godot_string return self->findn(*what, p_from); } -godot_int GDAPI find_last(const godot_string *p_self, godot_string p_what) { +godot_int GDAPI godot_string_find_last(const godot_string *p_self, godot_string p_what) { const String *self = (const String *)p_self; String *what = (String *)&p_what; diff --git a/modules/gdnative/godot/string.h b/modules/gdnative/godot/string.h index f41626faa1..128448e64e 100644 --- a/modules/gdnative/godot/string.h +++ b/modules/gdnative/godot/string.h @@ -37,7 +37,7 @@ extern "C" { #include <stdint.h> #include <wchar.h> -#define GODOT_STRING_SIZE 8 +#define GODOT_STRING_SIZE sizeof(void *) #ifndef GODOT_CORE_API_GODOT_STRING_TYPE_DEFINED #define GODOT_CORE_API_GODOT_STRING_TYPE_DEFINED @@ -82,7 +82,7 @@ godot_int GDAPI godot_string_findmk_from(const godot_string *p_self, const godot godot_int GDAPI godot_string_findmk_from_in_place(const godot_string *p_self, const godot_array *p_keys, godot_int p_from, godot_int *r_key); godot_int GDAPI godot_string_findn(const godot_string *p_self, godot_string p_what); godot_int GDAPI godot_string_findn_from(const godot_string *p_self, godot_string p_what, godot_int p_from); -godot_int GDAPI find_last(const godot_string *p_self, godot_string p_what); +godot_int GDAPI godot_string_find_last(const godot_string *p_self, godot_string p_what); godot_string GDAPI godot_string_format(const godot_string *p_self, const godot_variant *p_values); godot_string GDAPI godot_string_format_with_custom_placeholder(const godot_string *p_self, const godot_variant *p_values, const char *p_placeholder); godot_string GDAPI godot_string_hex_encode_buffer(const uint8_t *p_buffer, godot_int p_len); diff --git a/modules/gdnative/godot/variant.h b/modules/gdnative/godot/variant.h index fda24db8d4..849ba8bda6 100644 --- a/modules/gdnative/godot/variant.h +++ b/modules/gdnative/godot/variant.h @@ -36,7 +36,7 @@ extern "C" { #include <stdint.h> -#define GODOT_VARIANT_SIZE 24 +#define GODOT_VARIANT_SIZE (16 + sizeof(void *)) #ifndef GODOT_CORE_API_GODOT_VARIANT_TYPE_DEFINED #define GODOT_CORE_API_GODOT_VARIANT_TYPE_DEFINED diff --git a/modules/gridmap/grid_map_editor_plugin.cpp b/modules/gridmap/grid_map_editor_plugin.cpp index 6f0a13e07f..f6a76ad2a1 100644 --- a/modules/gridmap/grid_map_editor_plugin.cpp +++ b/modules/gridmap/grid_map_editor_plugin.cpp @@ -1159,14 +1159,14 @@ GridMapEditor::GridMapEditor(EditorNode *p_editor) { outer_mat.instance(); outer_mat->set_albedo(Color(0.7, 0.7, 1.0, 0.8)); - outer_mat->set_flag(SpatialMaterial::FLAG_ONTOP, true); + outer_mat->set_on_top_of_alpha(); outer_mat->set_flag(SpatialMaterial::FLAG_UNSHADED, true); outer_mat->set_line_width(3.0); outer_mat->set_feature(SpatialMaterial::FEATURE_TRANSPARENT, true); selection_floor_mat.instance(); selection_floor_mat->set_albedo(Color(0.80, 0.80, 1.0, 1)); - selection_floor_mat->set_flag(SpatialMaterial::FLAG_ONTOP, true); + selection_floor_mat->set_on_top_of_alpha(); selection_floor_mat->set_flag(SpatialMaterial::FLAG_UNSHADED, true); selection_floor_mat->set_line_width(3.0); //selection_floor_mat->set_feature(SpatialMaterial::FEATURE_TRANSPARENT, true); diff --git a/modules/hdr/image_loader_hdr.cpp b/modules/hdr/image_loader_hdr.cpp index d883b0f280..92d88207b3 100644 --- a/modules/hdr/image_loader_hdr.cpp +++ b/modules/hdr/image_loader_hdr.cpp @@ -1,5 +1,5 @@ /*************************************************************************/ -/* image_loader_jpegd.cpp */ +/* image_loader_hdr.cpp */ /*************************************************************************/ /* This file is part of: */ /* GODOT ENGINE */ diff --git a/modules/hdr/image_loader_hdr.h b/modules/hdr/image_loader_hdr.h index e6703dc142..569978d28d 100644 --- a/modules/hdr/image_loader_hdr.h +++ b/modules/hdr/image_loader_hdr.h @@ -1,5 +1,5 @@ /*************************************************************************/ -/* image_loader_jpegd.h */ +/* image_loader_hdr.h */ /*************************************************************************/ /* This file is part of: */ /* GODOT ENGINE */ diff --git a/modules/nativescript/godot_nativescript.h b/modules/nativescript/godot_nativescript.h index 1eaf459570..d1cbf221ec 100644 --- a/modules/nativescript/godot_nativescript.h +++ b/modules/nativescript/godot_nativescript.h @@ -1,5 +1,5 @@ /*************************************************************************/ -/* godot.h */ +/* godot_nativescript.h */ /*************************************************************************/ /* This file is part of: */ /* GODOT ENGINE */ @@ -58,7 +58,7 @@ extern "C" { #define GDAPI GDCALLINGCONV #endif #else -#define GDCALLINGCONV __attribute__((sysv_abi)) +#define GDCALLINGCONV __attribute__((sysv_abi, visibility("default"))) #define GDAPI GDCALLINGCONV #endif diff --git a/modules/nativescript/nativescript.cpp b/modules/nativescript/nativescript.cpp index 3799ce31f8..e141080687 100644 --- a/modules/nativescript/nativescript.cpp +++ b/modules/nativescript/nativescript.cpp @@ -994,6 +994,8 @@ void NativeScriptLanguage::init_library(const Ref<GDNativeLibrary> &lib) { #endif // See if this library was "registered" already. const String &lib_path = lib->get_active_library_path(); + ERR_EXPLAIN(lib->get_name() + " does not have a library for the current platform"); + ERR_FAIL_COND(lib_path.length() == 0); Map<String, Ref<GDNative> >::Element *E = library_gdnatives.find(lib_path); if (!E) { diff --git a/modules/regex/SCsub b/modules/regex/SCsub index 0fbdf97620..2dfc2739e9 100644 --- a/modules/regex/SCsub +++ b/modules/regex/SCsub @@ -8,8 +8,11 @@ env_regex.Append(CPPFLAGS=["-DPCRE2_CODE_UNIT_WIDTH=0"]) env_regex.add_source_files(env.modules_sources, "*.cpp") if (env['builtin_pcre2'] != 'no'): - thirdparty_dir = "#thirdparty/pcre2/src/" - thirdparty_flags = ["-DPCRE2_STATIC", "-DHAVE_CONFIG_H", "-DSUPPORT_JIT"] + jit_blacklist = ['javascript'] + thirdparty_dir = '#thirdparty/pcre2/src/' + thirdparty_flags = ['-DPCRE2_STATIC', '-DHAVE_CONFIG_H'] + if 'platform' in env and env['platform'] not in jit_blacklist: + thirdparty_flags.append('-DSUPPORT_JIT') thirdparty_sources = [ "pcre2_auto_possess.c", "pcre2_chartables.c", diff --git a/modules/tga/image_loader_tga.cpp b/modules/tga/image_loader_tga.cpp index 379c894550..84332ee2ff 100644 --- a/modules/tga/image_loader_tga.cpp +++ b/modules/tga/image_loader_tga.cpp @@ -1,5 +1,5 @@ /*************************************************************************/ -/* image_loader_jpegd.cpp */ +/* image_loader_tga.cpp */ /*************************************************************************/ /* This file is part of: */ /* GODOT ENGINE */ diff --git a/modules/tga/image_loader_tga.h b/modules/tga/image_loader_tga.h index 8689a1773b..7905ab37a7 100644 --- a/modules/tga/image_loader_tga.h +++ b/modules/tga/image_loader_tga.h @@ -1,5 +1,5 @@ /*************************************************************************/ -/* image_loader_jpegd.h */ +/* image_loader_tga.h */ /*************************************************************************/ /* This file is part of: */ /* GODOT ENGINE */ diff --git a/modules/tinyexr/image_loader_tinyexr.cpp b/modules/tinyexr/image_loader_tinyexr.cpp index 57826d69fb..49a4db237a 100644 --- a/modules/tinyexr/image_loader_tinyexr.cpp +++ b/modules/tinyexr/image_loader_tinyexr.cpp @@ -1,5 +1,5 @@ /*************************************************************************/ -/* image_loader_jpegd.cpp */ +/* image_loader_tinyexr.cpp */ /*************************************************************************/ /* This file is part of: */ /* GODOT ENGINE */ diff --git a/modules/tinyexr/image_loader_tinyexr.h b/modules/tinyexr/image_loader_tinyexr.h index adecba5d9d..53a81597af 100644 --- a/modules/tinyexr/image_loader_tinyexr.h +++ b/modules/tinyexr/image_loader_tinyexr.h @@ -1,5 +1,5 @@ /*************************************************************************/ -/* image_loader_jpegd.h */ +/* image_loader_tinyexr.h */ /*************************************************************************/ /* This file is part of: */ /* GODOT ENGINE */ diff --git a/modules/visual_script/visual_script_editor.cpp b/modules/visual_script/visual_script_editor.cpp index 05ceb7a38f..8386687c9f 100644 --- a/modules/visual_script/visual_script_editor.cpp +++ b/modules/visual_script/visual_script_editor.cpp @@ -1,5 +1,5 @@ /*************************************************************************/ -/* visual_script_editor.h */ +/* visual_script_editor.cpp */ /*************************************************************************/ /* This file is part of: */ /* GODOT ENGINE */ diff --git a/modules/visual_script/visual_script_nodes.h b/modules/visual_script/visual_script_nodes.h index 694fb96cfa..421409b265 100644 --- a/modules/visual_script/visual_script_nodes.h +++ b/modules/visual_script/visual_script_nodes.h @@ -1,5 +1,5 @@ /*************************************************************************/ -/* visual_script_nodes.h */ +/* visual_script_nodes.h */ /*************************************************************************/ /* This file is part of: */ /* GODOT ENGINE */ diff --git a/modules/webm/video_stream_webm.cpp b/modules/webm/video_stream_webm.cpp index 26344877de..0178ebab84 100644 --- a/modules/webm/video_stream_webm.cpp +++ b/modules/webm/video_stream_webm.cpp @@ -1,5 +1,5 @@ /*************************************************************************/ -/* av_stream_webm.cpp.cpp */ +/* video_stream_webm.cpp */ /*************************************************************************/ /* This file is part of: */ /* GODOT ENGINE */ diff --git a/modules/webm/video_stream_webm.h b/modules/webm/video_stream_webm.h index a48a6c6b9a..9a331849be 100644 --- a/modules/webm/video_stream_webm.h +++ b/modules/webm/video_stream_webm.h @@ -1,5 +1,5 @@ /*************************************************************************/ -/* av_stream_webm.cpp.cpp */ +/* video_stream_webm.h */ /*************************************************************************/ /* This file is part of: */ /* GODOT ENGINE */ diff --git a/platform/android/audio_driver_opensl.cpp b/platform/android/audio_driver_opensl.cpp index e774f5bb7d..9ebed84ace 100644 --- a/platform/android/audio_driver_opensl.cpp +++ b/platform/android/audio_driver_opensl.cpp @@ -1,5 +1,5 @@ /*************************************************************************/ -/* audio_driver_opensl.cpp */ +/* audio_driver_opensl.cpp */ /*************************************************************************/ /* This file is part of: */ /* GODOT ENGINE */ diff --git a/platform/android/detect.py b/platform/android/detect.py index 65442bf6f8..c1ac54c587 100644 --- a/platform/android/detect.py +++ b/platform/android/detect.py @@ -240,7 +240,7 @@ def configure(env): env.Append(CPPPATH=['#platform/android']) env.Append(CPPFLAGS=['-DANDROID_ENABLED', '-DUNIX_ENABLED', '-DNO_FCNTL', '-DMPC_FIXED_POINT']) - env.Append(LIBS=['OpenSLES', 'EGL', 'GLESv3', 'android', 'log', 'z']) + env.Append(LIBS=['OpenSLES', 'EGL', 'GLESv3', 'android', 'log', 'z', 'dl']) # TODO: Move that to opus module's config if("module_opus_enabled" in env and env["module_opus_enabled"] != "no"): diff --git a/platform/android/export/export.cpp b/platform/android/export/export.cpp index ef348d8685..3c5c0fda23 100644 --- a/platform/android/export/export.cpp +++ b/platform/android/export/export.cpp @@ -468,11 +468,36 @@ class EditorExportAndroid : public EditorExportPlatform { return zipfi; } - static Error save_apk_file(void *p_userdata, const String &p_path, const Vector<uint8_t> &p_data, int p_file, int p_total) { + static Set<String> get_abis() { + Set<String> abis; + abis.insert("armeabi"); + abis.insert("armeabi-v7a"); + abis.insert("arm64-v8a"); + abis.insert("x86"); + abis.insert("x86_64"); + abis.insert("mips"); + abis.insert("mips64"); + return abis; + } + static Error save_apk_file(void *p_userdata, const String &p_path, const Vector<uint8_t> &p_data, int p_file, int p_total) { APKExportData *ed = (APKExportData *)p_userdata; String dst_path = p_path; - dst_path = dst_path.replace_first("res://", "assets/"); + static Set<String> android_abis = get_abis(); + + if (dst_path.ends_with(".so")) { + String abi = dst_path.get_base_dir().get_file().strip_edges(); // parent dir name + if (android_abis.has(abi)) { + dst_path = "lib/" + abi + "/" + dst_path.get_file(); + } else { + String err = "Dynamic libraries must be located in the folder named after Android ABI they were compiled for. " + + p_path + " does not follow this convention."; + ERR_PRINT(err.utf8().get_data()); + return ERR_FILE_BAD_PATH; + } + } else { + dst_path = dst_path.replace_first("res://", "assets/"); + } zip_fileinfo zipfi = get_zip_fileinfo(); @@ -1393,15 +1418,15 @@ public: } } - if (file == "lib/x86/libgodot_android.so" && !export_x86) { + if (file == "lib/x86/*.so" && !export_x86) { skip = true; } - if (file.match("lib/armeabi*/libgodot_android.so") && !export_arm) { + if (file.match("lib/armeabi*/*.so") && !export_arm) { skip = true; } - if (file.match("lib/arm64*/libgodot_android.so") && !export_arm64) { + if (file.match("lib/arm64*/*.so") && !export_arm64) { skip = true; } diff --git a/platform/android/java/src/org/godotengine/godot/Godot.java b/platform/android/java/src/org/godotengine/godot/Godot.java index eab0387f32..53a90e4cfe 100644 --- a/platform/android/java/src/org/godotengine/godot/Godot.java +++ b/platform/android/java/src/org/godotengine/godot/Godot.java @@ -92,7 +92,7 @@ import android.os.SystemClock; public class Godot extends Activity implements SensorEventListener, IDownloaderClient -{ +{ static final int MAX_SINGLETONS = 64; private IStub mDownloaderClientStub; @@ -139,9 +139,9 @@ public class Godot extends Activity implements SensorEventListener, IDownloaderC com.godot.game.R.string.text_button_pause; mPauseButton.setText(stringResourceID); } - + static public class SingletonBase { - + protected void registerClass(String p_name, String[] p_methods) { GodotLib.singleton(p_name,this); @@ -210,6 +210,7 @@ public class Godot extends Activity implements SensorEventListener, IDownloaderC */ private String[] command_line; + private boolean use_apk_expansion; public GodotView mView; private boolean godot_initialized=false; @@ -264,27 +265,40 @@ public class Godot extends Activity implements SensorEventListener, IDownloaderC layout = new FrameLayout(this); layout.setLayoutParams(new LayoutParams(LayoutParams.FILL_PARENT,LayoutParams.FILL_PARENT)); setContentView(layout); - + // GodotEditText layout - GodotEditText edittext = new GodotEditText(this); + GodotEditText edittext = new GodotEditText(this); edittext.setLayoutParams(new ViewGroup.LayoutParams(LayoutParams.FILL_PARENT,LayoutParams.WRAP_CONTENT)); // ...add to FrameLayout layout.addView(edittext); - + mView = new GodotView(getApplication(),io,use_gl2,use_32_bits, this); layout.addView(mView,new LayoutParams(LayoutParams.FILL_PARENT,LayoutParams.FILL_PARENT)); - setKeepScreenOn(GodotLib.getGlobal("display/driver/keep_screen_on").equals("True")); - - edittext.setView(mView); - io.setEdit(edittext); - + edittext.setView(mView); + io.setEdit(edittext); + // Ad layout adLayout = new RelativeLayout(this); adLayout.setLayoutParams(new LayoutParams(LayoutParams.FILL_PARENT,LayoutParams.FILL_PARENT)); layout.addView(adLayout); - + + final String[] current_command_line = command_line; + final GodotView view = mView; + mView.queueEvent(new Runnable() { + @Override + public void run() { + GodotLib.setup(current_command_line); + runOnUiThread(new Runnable() { + @Override + public void run() { + view.setKeepScreenOn("True".equals(GodotLib.getGlobal("display/driver/keep_screen_on"))); + } + }); + } + }); + } - + public void setKeepScreenOn(final boolean p_enabled) { keep_screen_on = p_enabled; if (mView != null){ @@ -315,13 +329,13 @@ public class Godot extends Activity implements SensorEventListener, IDownloaderC } }); } - + private static Godot _self; - + public static Godot getInstance(){ return Godot._self; } - + private String[] getCommandLine() { InputStream is; @@ -402,7 +416,6 @@ public class Godot extends Activity implements SensorEventListener, IDownloaderC Log.d("GODOT"," " + command_line[w]); } }*/ - GodotLib.initialize(this,io.needsReloadHooks(),command_line,getAssets()); mSensorManager = (SensorManager) getSystemService(Context.SENSOR_SERVICE); mAccelerometer = mSensorManager.getDefaultSensor(Sensor.TYPE_ACCELEROMETER); mSensorManager.registerListener(this, mAccelerometer, SensorManager.SENSOR_DELAY_GAME); @@ -411,9 +424,12 @@ public class Godot extends Activity implements SensorEventListener, IDownloaderC mGyroscope = mSensorManager.getDefaultSensor(Sensor.TYPE_GYROSCOPE); mSensorManager.registerListener(this, mGyroscope, SensorManager.SENSOR_DELAY_GAME); + GodotLib.initialize(this, io.needsReloadHooks(), getAssets(), use_apk_expansion); + result_callback = null; mPaymentsManager = PaymentsManager.createManager(this).initService(); + godot_initialized=true; } @@ -426,7 +442,7 @@ public class Godot extends Activity implements SensorEventListener, IDownloaderC - @Override + @Override protected void onCreate(Bundle icicle) { Log.d("GODOT", "** GODOT ACTIVITY CREATED HERE ***\n"); @@ -437,12 +453,10 @@ public class Godot extends Activity implements SensorEventListener, IDownloaderC //window.addFlags(WindowManager.LayoutParams.FLAG_TURN_SCREEN_ON | WindowManager.LayoutParams.FLAG_KEEP_SCREEN_ON); window.addFlags(WindowManager.LayoutParams.FLAG_TURN_SCREEN_ON); - //check for apk expansion API if (true) { boolean md5mismatch = false; command_line = getCommandLine(); - boolean use_apk_expansion=false; String main_pack_md5=null; String main_pack_key=null; @@ -528,23 +542,23 @@ public class Godot extends Activity implements SensorEventListener, IDownloaderC if (!pack_valid) { Log.d("GODOT", "Pack Invalid, try re-downloading."); - + Intent notifierIntent = new Intent(this, this.getClass()); notifierIntent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK | Intent.FLAG_ACTIVITY_CLEAR_TOP); - + PendingIntent pendingIntent = PendingIntent.getActivity(this, 0, notifierIntent, PendingIntent.FLAG_UPDATE_CURRENT); - + int startResult; try { Log.d("GODOT", "INITIALIZING DOWNLOAD"); startResult = DownloaderClientMarshaller.startDownloadServiceIfRequired( - getApplicationContext(), - pendingIntent, + getApplicationContext(), + pendingIntent, GodotDownloaderService.class); Log.d("GODOT", "DOWNLOAD SERVICE FINISHED:" + startResult); - + if (startResult != DownloaderClientMarshaller.NO_DOWNLOAD_REQUIRED) { Log.d("GODOT", "DOWNLOAD REQUIRED"); // This is where you do set up to display the download @@ -563,7 +577,7 @@ public class Godot extends Activity implements SensorEventListener, IDownloaderC mCellMessage = findViewById(com.godot.game.R.id.approveCellular); mPauseButton = (Button) findViewById(com.godot.game.R.id.pauseButton); mWiFiSettingsButton = (Button) findViewById(com.godot.game.R.id.wifiSettingsButton); - + return; } else{ Log.d("GODOT", "NO DOWNLOAD REQUIRED"); @@ -582,7 +596,7 @@ public class Godot extends Activity implements SensorEventListener, IDownloaderC initializeGodot(); - + //instanceSingleton( new GodotFacebook(this) ); @@ -590,14 +604,14 @@ public class Godot extends Activity implements SensorEventListener, IDownloaderC @Override protected void onDestroy(){ - + if(mPaymentsManager != null ) mPaymentsManager.destroy(); for(int i=0;i<singleton_count;i++) { singletons[i].onMainDestroy(); } super.onDestroy(); } - + @Override protected void onPause() { super.onPause(); if (!godot_initialized){ @@ -607,8 +621,13 @@ public class Godot extends Activity implements SensorEventListener, IDownloaderC return; } mView.onPause(); + mView.queueEvent(new Runnable() { + @Override + public void run() { + GodotLib.focusout(); + } + }); mSensorManager.unregisterListener(this); - GodotLib.focusout(); for(int i=0;i<singleton_count;i++) { singletons[i].onMainPause(); @@ -625,10 +644,16 @@ public class Godot extends Activity implements SensorEventListener, IDownloaderC } mView.onResume(); + mView.queueEvent(new Runnable() { + @Override + public void run() { + GodotLib.focusin(); + } + }); mSensorManager.registerListener(this, mAccelerometer, SensorManager.SENSOR_DELAY_GAME); mSensorManager.registerListener(this, mMagnetometer, SensorManager.SENSOR_DELAY_GAME); mSensorManager.registerListener(this, mGyroscope, SensorManager.SENSOR_DELAY_GAME); - GodotLib.focusin(); + if(use_immersive && Build.VERSION.SDK_INT >= 19.0){ // check if the application runs on an android 4.4+ Window window = getWindow(); window.getDecorView().setSystemUiVisibility( @@ -644,8 +669,8 @@ public class Godot extends Activity implements SensorEventListener, IDownloaderC singletons[i].onMainResume(); } - - + + } @@ -670,32 +695,39 @@ public class Godot extends Activity implements SensorEventListener, IDownloaderC @Override public void onSensorChanged(SensorEvent event) { Display display = ((WindowManager) getSystemService(WINDOW_SERVICE)).getDefaultDisplay(); int displayRotation = display.getRotation(); - + float[] adjustedValues = new float[3]; final int axisSwap[][] = { - { 1, -1, 0, 1 }, // ROTATION_0 - {-1, -1, 1, 0 }, // ROTATION_90 - {-1, 1, 0, 1 }, // ROTATION_180 - { 1, 1, 1, 0 } }; // ROTATION_270 - - final int[] as = axisSwap[displayRotation]; - adjustedValues[0] = (float)as[0] * event.values[ as[2] ]; - adjustedValues[1] = (float)as[1] * event.values[ as[3] ]; + { 1, -1, 0, 1 }, // ROTATION_0 + {-1, -1, 1, 0 }, // ROTATION_90 + {-1, 1, 0, 1 }, // ROTATION_180 + { 1, 1, 1, 0 } }; // ROTATION_270 + + final int[] as = axisSwap[displayRotation]; + adjustedValues[0] = (float)as[0] * event.values[ as[2] ]; + adjustedValues[1] = (float)as[1] * event.values[ as[3] ]; adjustedValues[2] = event.values[2]; - - float x = adjustedValues[0]; - float y = adjustedValues[1]; - float z = adjustedValues[2]; - - int typeOfSensor = event.sensor.getType(); - if (typeOfSensor == event.sensor.TYPE_ACCELEROMETER) { - GodotLib.accelerometer(x,y,z); - } - if (typeOfSensor == event.sensor.TYPE_MAGNETIC_FIELD) { - GodotLib.magnetometer(x,y,z); - } - if (typeOfSensor == event.sensor.TYPE_GYROSCOPE) { - GodotLib.gyroscope(x,y,z); + + final float x = adjustedValues[0]; + final float y = adjustedValues[1]; + final float z = adjustedValues[2]; + + final int typeOfSensor = event.sensor.getType(); + if (mView != null) { + mView.queueEvent(new Runnable() { + @Override + public void run() { + if (typeOfSensor == Sensor.TYPE_ACCELEROMETER) { + GodotLib.accelerometer(x,y,z); + } + if (typeOfSensor == Sensor.TYPE_MAGNETIC_FIELD) { + GodotLib.magnetometer(x,y,z); + } + if (typeOfSensor == Sensor.TYPE_GYROSCOPE) { + GodotLib.gyroscope(x,y,z); + } + } + }); } } @@ -722,7 +754,14 @@ public class Godot extends Activity implements SensorEventListener, IDownloaderC @Override public void onBackPressed() { System.out.printf("** BACK REQUEST!\n"); - //GodotLib.back(); + if (mView != null) { + mView.queueEvent(new Runnable() { + @Override + public void run() { + GodotLib.back(); + } + }); + } } public void forceQuit() { @@ -733,7 +772,7 @@ public class Godot extends Activity implements SensorEventListener, IDownloaderC private boolean obbIsCorrupted(String f, String main_pack_md5){ - + try { InputStream fis = new FileInputStream(f); @@ -780,58 +819,64 @@ public class Godot extends Activity implements SensorEventListener, IDownloaderC } //@Override public boolean dispatchTouchEvent (MotionEvent event) { - public boolean gotTouchEvent(MotionEvent event) { + public boolean gotTouchEvent(final MotionEvent event) { super.onTouchEvent(event); - int evcount=event.getPointerCount(); + final int evcount=event.getPointerCount(); if (evcount==0) return true; - int[] arr = new int[event.getPointerCount()*3]; + if (mView != null) { + final int[] arr = new int[event.getPointerCount()*3]; - for(int i=0;i<event.getPointerCount();i++) { + for(int i=0;i<event.getPointerCount();i++) { - arr[i*3+0]=(int)event.getPointerId(i); - arr[i*3+1]=(int)event.getX(i); - arr[i*3+2]=(int)event.getY(i); - } + arr[i*3+0]=(int)event.getPointerId(i); + arr[i*3+1]=(int)event.getX(i); + arr[i*3+2]=(int)event.getY(i); + } - //System.out.printf("gaction: %d\n",event.getAction()); - switch(event.getAction()&MotionEvent.ACTION_MASK) { - - case MotionEvent.ACTION_DOWN: { - GodotLib.touch(0,0,evcount,arr); - //System.out.printf("action down at: %f,%f\n", event.getX(),event.getY()); - } break; - case MotionEvent.ACTION_MOVE: { - GodotLib.touch(1,0,evcount,arr); - /* - for(int i=0;i<event.getPointerCount();i++) { - System.out.printf("%d - moved to: %f,%f\n",i, event.getX(i),event.getY(i)); - } - */ - } break; - case MotionEvent.ACTION_POINTER_UP: { - final int indexPointUp = event.getActionIndex(); - final int pointer_idx = event.getPointerId(indexPointUp); - GodotLib.touch(4,pointer_idx,evcount,arr); - //System.out.printf("%d - s.up at: %f,%f\n",pointer_idx, event.getX(pointer_idx),event.getY(pointer_idx)); - } break; - case MotionEvent.ACTION_POINTER_DOWN: { - int pointer_idx = event.getActionIndex(); - GodotLib.touch(3,pointer_idx,evcount,arr); - //System.out.printf("%d - s.down at: %f,%f\n",pointer_idx, event.getX(pointer_idx),event.getY(pointer_idx)); - } break; - case MotionEvent.ACTION_CANCEL: - case MotionEvent.ACTION_UP: { - GodotLib.touch(2,0,evcount,arr); - /* - for(int i=0;i<event.getPointerCount();i++) { - System.out.printf("%d - up! %f,%f\n",i, event.getX(i),event.getY(i)); + //System.out.printf("gaction: %d\n",event.getAction()); + final int action = event.getAction() & MotionEvent.ACTION_MASK; + mView.queueEvent(new Runnable() { + @Override + public void run() { + switch(action) { + case MotionEvent.ACTION_DOWN: { + GodotLib.touch(0,0,evcount,arr); + //System.out.printf("action down at: %f,%f\n", event.getX(),event.getY()); + } break; + case MotionEvent.ACTION_MOVE: { + GodotLib.touch(1,0,evcount,arr); + /* + for(int i=0;i<event.getPointerCount();i++) { + System.out.printf("%d - moved to: %f,%f\n",i, event.getX(i),event.getY(i)); + } + */ + } break; + case MotionEvent.ACTION_POINTER_UP: { + final int indexPointUp = event.getActionIndex(); + final int pointer_idx = event.getPointerId(indexPointUp); + GodotLib.touch(4,pointer_idx,evcount,arr); + //System.out.printf("%d - s.up at: %f,%f\n",pointer_idx, event.getX(pointer_idx),event.getY(pointer_idx)); + } break; + case MotionEvent.ACTION_POINTER_DOWN: { + int pointer_idx = event.getActionIndex(); + GodotLib.touch(3,pointer_idx,evcount,arr); + //System.out.printf("%d - s.down at: %f,%f\n",pointer_idx, event.getX(pointer_idx),event.getY(pointer_idx)); + } break; + case MotionEvent.ACTION_CANCEL: + case MotionEvent.ACTION_UP: { + GodotLib.touch(2,0,evcount,arr); + /* + for(int i=0;i<event.getPointerCount();i++) { + System.out.printf("%d - up! %f,%f\n",i, event.getX(i),event.getY(i)); + } + */ + } break; + } } - */ - } break; - + }); } return true; } @@ -864,7 +909,7 @@ public class Godot extends Activity implements SensorEventListener, IDownloaderC private void queueEvent(Runnable runnable) { // TODO Auto-generated method stub - + } public PaymentsManager getPaymentsManager() { @@ -988,7 +1033,7 @@ public class Godot extends Activity implements SensorEventListener, IDownloaderC mProgressFraction.setText(Helpers.getDownloadProgressString (progress.mOverallProgress, progress.mOverallTotal)); - + } - + } diff --git a/platform/android/java/src/org/godotengine/godot/GodotLib.java b/platform/android/java/src/org/godotengine/godot/GodotLib.java index b487c17f53..47a690140f 100644 --- a/platform/android/java/src/org/godotengine/godot/GodotLib.java +++ b/platform/android/java/src/org/godotengine/godot/GodotLib.java @@ -37,7 +37,7 @@ public class GodotLib { public static GodotIO io; static { - System.loadLibrary("godot_android"); + System.loadLibrary("godot_android"); } /** @@ -45,7 +45,8 @@ public class GodotLib { * @param height the current view height */ - public static native void initialize(Godot p_instance,boolean need_reload_hook,String[] p_cmdline,Object p_asset_manager); + public static native void initialize(Godot p_instance,boolean need_reload_hook,Object p_asset_manager, boolean use_apk_expansion); + public static native void setup(String[] p_cmdline); public static native void resize(int width, int height,boolean reload); public static native void newcontext(boolean p_32_bits); public static native void back(); diff --git a/platform/android/java/src/org/godotengine/godot/GodotPaymentV3.java b/platform/android/java/src/org/godotengine/godot/GodotPaymentV3.java index a16c67523e..8fe79fdfc7 100644 --- a/platform/android/java/src/org/godotengine/godot/GodotPaymentV3.java +++ b/platform/android/java/src/org/godotengine/godot/GodotPaymentV3.java @@ -89,7 +89,7 @@ public class GodotPaymentV3 extends Godot.SingletonBase { } public void callbackSuccess(String ticket, String signature, String sku) { - GodotLib.callobject(purchaseCallbackId, "purchase_success", new Object[]{ticket, signature, sku}); + GodotLib.calldeferred(purchaseCallbackId, "purchase_success", new Object[]{ticket, signature, sku}); } public void callbackSuccessProductMassConsumed(String ticket, String signature, String sku) { diff --git a/platform/android/java/src/org/godotengine/godot/GodotView.java b/platform/android/java/src/org/godotengine/godot/GodotView.java index 19fcf8e687..3c2ad7cc59 100644 --- a/platform/android/java/src/org/godotengine/godot/GodotView.java +++ b/platform/android/java/src/org/godotengine/godot/GodotView.java @@ -208,8 +208,9 @@ public class GodotView extends GLSurfaceView implements InputDeviceListener { @Override public void onInputDeviceAdded(int deviceId) { joystick joy = new joystick(); joy.device_id = deviceId; - int id = joy_devices.size(); + final int id = joy_devices.size(); InputDevice device = mInputManager.getInputDevice(deviceId); + final String name = device.getName(); joy.name = device.getName(); joy.axes = new ArrayList<InputDevice.MotionRange>(); joy.hats = new ArrayList<InputDevice.MotionRange>(); @@ -224,19 +225,29 @@ public class GodotView extends GLSurfaceView implements InputDeviceListener { } } joy_devices.add(joy); - GodotLib.joyconnectionchanged(id, true, joy.name); + queueEvent(new Runnable() { + @Override + public void run() { + GodotLib.joyconnectionchanged(id, true, name); + } + }); } @Override public void onInputDeviceRemoved(int deviceId) { - int id = find_joy_device(deviceId); + final int id = find_joy_device(deviceId); joy_devices.remove(id); - GodotLib.joyconnectionchanged(id, false, ""); + queueEvent(new Runnable() { + @Override + public void run() { + GodotLib.joyconnectionchanged(id, false, ""); + } + }); } @Override public void onInputDeviceChanged(int deviceId) { } - @Override public boolean onKeyUp(int keyCode, KeyEvent event) { + @Override public boolean onKeyUp(final int keyCode, KeyEvent event) { if (keyCode == KeyEvent.KEYCODE_BACK) { return true; @@ -249,22 +260,38 @@ public class GodotView extends GLSurfaceView implements InputDeviceListener { int source = event.getSource(); if ((source & InputDevice.SOURCE_JOYSTICK) != 0 || (source & InputDevice.SOURCE_DPAD) != 0 || (source & InputDevice.SOURCE_GAMEPAD) != 0) { - int button = get_godot_button(keyCode); - int device = find_joy_device(event.getDeviceId()); + final int button = get_godot_button(keyCode); + final int device = find_joy_device(event.getDeviceId()); - GodotLib.joybutton(device, button, false); + queueEvent(new Runnable() { + @Override + public void run() { + GodotLib.joybutton(device, button, false); + } + }); return true; } else { - - GodotLib.key(keyCode, event.getUnicodeChar(0), false); + final int chr = event.getUnicodeChar(0); + queueEvent(new Runnable() { + @Override + public void run() { + GodotLib.key(keyCode, chr, false); + } + }); }; return super.onKeyUp(keyCode, event); }; - @Override public boolean onKeyDown(int keyCode, KeyEvent event) { + @Override public boolean onKeyDown(final int keyCode, KeyEvent event) { if (keyCode == KeyEvent.KEYCODE_BACK) { - GodotLib.back(); + queueEvent(new Runnable() { + @Override + public void run() { + GodotLib.back(); + } + }); + // press 'back' button should not terminate program //normal handle 'back' event in game logic return true; @@ -281,16 +308,26 @@ public class GodotView extends GLSurfaceView implements InputDeviceListener { if (event.getRepeatCount() > 0) // ignore key echo return true; - int button = get_godot_button(keyCode); - int device = find_joy_device(event.getDeviceId()); + final int button = get_godot_button(keyCode); + final int device = find_joy_device(event.getDeviceId()); //Log.e(TAG, String.format("joy button down! button %x, %d, device %d", keyCode, button, device)); - - GodotLib.joybutton(device, button, true); + queueEvent(new Runnable() { + @Override + public void run() { + GodotLib.joybutton(device, button, true); + } + }); return true; } else { - GodotLib.key(keyCode, event.getUnicodeChar(0), true); + final int chr = event.getUnicodeChar(0); + queueEvent(new Runnable() { + @Override + public void run() { + GodotLib.key(keyCode, chr, true); + } + }); }; return super.onKeyDown(keyCode, event); } @@ -299,21 +336,32 @@ public class GodotView extends GLSurfaceView implements InputDeviceListener { if ((event.getSource() & InputDevice.SOURCE_JOYSTICK) == InputDevice.SOURCE_JOYSTICK && event.getAction() == MotionEvent.ACTION_MOVE) { - int device_id = find_joy_device(event.getDeviceId()); + final int device_id = find_joy_device(event.getDeviceId()); joystick joy = joy_devices.get(device_id); for (int i = 0; i < joy.axes.size(); i++) { InputDevice.MotionRange range = joy.axes.get(i); - float value = (event.getAxisValue(range.getAxis()) - range.getMin() ) / range.getRange() * 2.0f - 1.0f; + final float value = (event.getAxisValue(range.getAxis()) - range.getMin() ) / range.getRange() * 2.0f - 1.0f; //Log.e(TAG, String.format("axis event: %d, value %f", i, value)); - GodotLib.joyaxis(device_id, i, value); + final int idx = i; + queueEvent(new Runnable() { + @Override + public void run() { + GodotLib.joyaxis(device_id, idx, value); + } + }); } for (int i = 0; i < joy.hats.size(); i+=2) { - int hatX = Math.round(event.getAxisValue(joy.hats.get(i).getAxis())); - int hatY = Math.round(event.getAxisValue(joy.hats.get(i+1).getAxis())); + final int hatX = Math.round(event.getAxisValue(joy.hats.get(i).getAxis())); + final int hatY = Math.round(event.getAxisValue(joy.hats.get(i+1).getAxis())); //Log.e(TAG, String.format("HAT EVENT %d, %d", hatX, hatY)); - GodotLib.joyhat(device_id, hatX, hatY); + queueEvent(new Runnable() { + @Override + public void run() { + GodotLib.joyhat(device_id, hatX, hatY); + } + }); } return true; }; diff --git a/platform/android/java/src/org/godotengine/godot/input/GodotTextInputWrapper.java b/platform/android/java/src/org/godotengine/godot/input/GodotTextInputWrapper.java index c2d03e4ecc..04669a3b0c 100644 --- a/platform/android/java/src/org/godotengine/godot/input/GodotTextInputWrapper.java +++ b/platform/android/java/src/org/godotengine/godot/input/GodotTextInputWrapper.java @@ -89,8 +89,13 @@ public class GodotTextInputWrapper implements TextWatcher, OnEditorActionListene //Log.d(TAG, "beforeTextChanged(" + pCharSequence + ")start: " + start + ",count: " + count + ",after: " + after); for (int i=0;i<count;i++){ - GodotLib.key(KeyEvent.KEYCODE_DEL, 0, true); - GodotLib.key(KeyEvent.KEYCODE_DEL, 0, false); + mView.queueEvent(new Runnable() { + @Override + public void run() { + GodotLib.key(KeyEvent.KEYCODE_DEL, 0, true); + GodotLib.key(KeyEvent.KEYCODE_DEL, 0, false); + } + }); } } @@ -99,9 +104,14 @@ public class GodotTextInputWrapper implements TextWatcher, OnEditorActionListene //Log.d(TAG, "onTextChanged(" + pCharSequence + ")start: " + start + ",count: " + count + ",before: " + before); for (int i=start;i<start+count;i++){ - int ch = pCharSequence.charAt(i); - GodotLib.key(0, ch, true); - GodotLib.key(0, ch, false); + final int ch = pCharSequence.charAt(i); + mView.queueEvent(new Runnable() { + @Override + public void run() { + GodotLib.key(0, ch, true); + GodotLib.key(0, ch, false); + } + }); } } @@ -111,8 +121,14 @@ public class GodotTextInputWrapper implements TextWatcher, OnEditorActionListene if (this.mEdit == pTextView && this.isFullScreenEdit()) { // user press the action button, delete all old text and insert new text for (int i = this.mOriginText.length(); i > 0; i--) { - GodotLib.key(KeyEvent.KEYCODE_DEL, 0, true); - GodotLib.key(KeyEvent.KEYCODE_DEL, 0, false); + mView.queueEvent(new Runnable() { + @Override + public void run() { + GodotLib.key(KeyEvent.KEYCODE_DEL, 0, true); + GodotLib.key(KeyEvent.KEYCODE_DEL, 0, false); + } + }); + /* if (BuildConfig.DEBUG) { Log.d(TAG, "deleteBackward"); @@ -131,9 +147,14 @@ public class GodotTextInputWrapper implements TextWatcher, OnEditorActionListene } for(int i = 0; i < text.length(); i++) { - int ch = text.codePointAt(i); - GodotLib.key(0, ch, true); - GodotLib.key(0, ch, false); + final int ch = text.codePointAt(i); + mView.queueEvent(new Runnable() { + @Override + public void run() { + GodotLib.key(0, ch, true); + GodotLib.key(0, ch, false); + } + }); } /* if (BuildConfig.DEBUG) { @@ -141,7 +162,7 @@ public class GodotTextInputWrapper implements TextWatcher, OnEditorActionListene } */ } - + if (pActionID == EditorInfo.IME_ACTION_DONE) { this.mView.requestFocus(); } diff --git a/platform/android/java_glue.cpp b/platform/android/java_glue.cpp index 06abe9d751..509d1bf123 100644 --- a/platform/android/java_glue.cpp +++ b/platform/android/java_glue.cpp @@ -613,8 +613,6 @@ static List<JAndroidPointerEvent> pointer_events; static List<Ref<InputEvent> > key_events; static List<OS_Android::JoypadEvent> joy_events; static bool initialized = false; -static Mutex *input_mutex = NULL; -static Mutex *suspend_mutex = NULL; static int step = 0; static bool resized = false; static bool resized_reload = false; @@ -756,7 +754,7 @@ static void _alert(const String &p_message, const String &p_title) { env->CallVoidMethod(_godot_instance, _alertDialog, jStrMessage, jStrTitle); } -JNIEXPORT void JNICALL Java_org_godotengine_godot_GodotLib_initialize(JNIEnv *env, jobject obj, jobject activity, jboolean p_need_reload_hook, jobjectArray p_cmdline, jobject p_asset_manager) { +JNIEXPORT void JNICALL Java_org_godotengine_godot_GodotLib_initialize(JNIEnv *env, jobject obj, jobject activity, jboolean p_need_reload_hook, jobject p_asset_manager, jboolean p_use_apk_expansion) { __android_log_print(ANDROID_LOG_INFO, "godot", "**INIT EVENT! - %p\n", env); @@ -826,36 +824,7 @@ JNIEXPORT void JNICALL Java_org_godotengine_godot_GodotLib_initialize(JNIEnv *en AudioDriverAndroid::setup(gob); } - const char **cmdline = NULL; - int cmdlen = 0; - bool use_apk_expansion = false; - if (p_cmdline) { - cmdlen = env->GetArrayLength(p_cmdline); - if (cmdlen) { - cmdline = (const char **)malloc((env->GetArrayLength(p_cmdline) + 1) * sizeof(const char *)); - cmdline[cmdlen] = NULL; - - for (int i = 0; i < cmdlen; i++) { - - jstring string = (jstring)env->GetObjectArrayElement(p_cmdline, i); - const char *rawString = env->GetStringUTFChars(string, 0); - if (!rawString) { - __android_log_print(ANDROID_LOG_INFO, "godot", "cmdline arg %i is null\n", i); - } else { - //__android_log_print(ANDROID_LOG_INFO,"godot","cmdline arg %i is: %s\n",i,rawString); - - if (strcmp(rawString, "--main_pack") == 0) - use_apk_expansion = true; - } - - cmdline[i] = rawString; - } - } - } - - __android_log_print(ANDROID_LOG_INFO, "godot", "CMDLINE LEN %i - APK EXPANSION %I\n", cmdlen, int(use_apk_expansion)); - - os_android = new OS_Android(_gfx_init_func, env, _open_uri, _get_data_dir, _get_locale, _get_model, _get_screen_dpi, _show_vk, _hide_vk, _set_screen_orient, _get_unique_id, _get_system_dir, _play_video, _is_video_playing, _pause_video, _stop_video, _set_keep_screen_on, _alert, use_apk_expansion); + os_android = new OS_Android(_gfx_init_func, env, _open_uri, _get_data_dir, _get_locale, _get_model, _get_screen_dpi, _show_vk, _hide_vk, _set_screen_orient, _get_unique_id, _get_system_dir, _play_video, _is_video_playing, _pause_video, _stop_video, _set_keep_screen_on, _alert, p_use_apk_expansion); os_android->set_need_reload_hooks(p_need_reload_hook); char wd[500]; @@ -864,62 +833,10 @@ JNIEXPORT void JNICALL Java_org_godotengine_godot_GodotLib_initialize(JNIEnv *en __android_log_print(ANDROID_LOG_INFO, "godot", "test construction %i\n", tst.a); __android_log_print(ANDROID_LOG_INFO, "godot", "running from dir %s\n", wd); - __android_log_print(ANDROID_LOG_INFO, "godot", "**SETUP"); - - Error err = Main::setup("apk", cmdlen, (char **)cmdline, false); - - if (err != OK) { - __android_log_print(ANDROID_LOG_INFO, "godot", "*****UNABLE TO SETUP"); - - return; //should exit instead and print the error - } - - __android_log_print(ANDROID_LOG_INFO, "godot", "*****SETUP OK"); - //video driver is determined here, because once initialized, it can't be changed - String vd = ProjectSettings::get_singleton()->get("display/driver"); + // String vd = ProjectSettings::get_singleton()->get("display/driver"); env->CallVoidMethod(_godot_instance, _on_video_init, (jboolean) true); - - __android_log_print(ANDROID_LOG_INFO, "godot", "**START"); - - input_mutex = Mutex::create(); - suspend_mutex = Mutex::create(); -} - -JNIEXPORT void JNICALL Java_org_godotengine_godot_GodotLib_resize(JNIEnv *env, jobject obj, jint width, jint height, jboolean reload) { - - __android_log_print(ANDROID_LOG_INFO, "godot", "^_^_^_^_^ resize %lld, %i, %i\n", Thread::get_caller_id(), width, height); - if (os_android) - os_android->set_display_size(Size2(width, height)); - - /*input_mutex->lock(); - resized=true; - if (reload) - resized_reload=true; - new_size=Size2(width,height); - input_mutex->unlock();*/ -} - -JNIEXPORT void JNICALL Java_org_godotengine_godot_GodotLib_newcontext(JNIEnv *env, jobject obj, bool p_32_bits) { - - __android_log_print(ANDROID_LOG_INFO, "godot", "^_^_^_^_^ newcontext %lld\n", Thread::get_caller_id()); - - if (os_android) { - os_android->set_context_is_16_bits(!p_32_bits); - } - - if (os_android && step > 0) { - - os_android->reload_gfx(); - } -} - -JNIEXPORT void JNICALL Java_org_godotengine_godot_GodotLib_back(JNIEnv *env, jobject obj) { - - input_mutex->lock(); - go_back_request = true; - input_mutex->unlock(); } static void _initialize_java_modules() { @@ -985,36 +902,106 @@ static void _initialize_java_modules() { } } -JNIEXPORT void JNICALL Java_org_godotengine_godot_GodotLib_step(JNIEnv *env, jobject obj) { - +JNIEXPORT void JNICALL Java_org_godotengine_godot_GodotLib_setup(JNIEnv *env, jobject obj, jobjectArray p_cmdline) { ThreadAndroid::setup_thread(); - //__android_log_print(ANDROID_LOG_INFO,"godot","**STEP EVENT! - %p-%i\n",env,Thread::get_caller_id()); + __android_log_print(ANDROID_LOG_INFO, "godot", "**SETUP"); - suspend_mutex->lock(); - input_mutex->lock(); - //first time step happens, initialize - if (step == 0) { - // ugly hack to initialize the rest of the engine - // because of the way android forces you to do everything with threads + const char **cmdline = NULL; + int cmdlen = 0; + bool use_apk_expansion = false; + if (p_cmdline) { + cmdlen = env->GetArrayLength(p_cmdline); + if (cmdlen) { + cmdline = (const char **)malloc((env->GetArrayLength(p_cmdline) + 1) * sizeof(const char *)); + cmdline[cmdlen] = NULL; + + for (int i = 0; i < cmdlen; i++) { + + jstring string = (jstring)env->GetObjectArrayElement(p_cmdline, i); + const char *rawString = env->GetStringUTFChars(string, 0); + if (!rawString) { + __android_log_print(ANDROID_LOG_INFO, "godot", "cmdline arg %i is null\n", i); + } else { + //__android_log_print(ANDROID_LOG_INFO,"godot","cmdline arg %i is: %s\n",i,rawString); - java_class_wrapper = memnew(JavaClassWrapper(_godot_instance)); - ProjectSettings::get_singleton()->add_singleton(ProjectSettings::Singleton("JavaClassWrapper", java_class_wrapper)); - _initialize_java_modules(); + if (strcmp(rawString, "-main_pack") == 0) + use_apk_expansion = true; + } + + cmdline[i] = rawString; + } + } + } + __android_log_print(ANDROID_LOG_INFO, "godot", "CMDLINE LEN %i - APK EXPANSION %i\n", cmdlen, int(use_apk_expansion)); + +#if 0 + char *args[]={"-test","render",NULL}; + __android_log_print(ANDROID_LOG_INFO,"godot","pre asdasd setup..."); + Error err = Main::setup("apk",2,args,false); +#else + Error err = Main::setup("apk", cmdlen, (char **)cmdline, false); +#endif + if (cmdline) { + free(cmdline); + } + + if (err != OK) { + __android_log_print(ANDROID_LOG_INFO, "godot", "*****UNABLE TO SETUP"); + return; //should exit instead and print the error + } + __android_log_print(ANDROID_LOG_INFO, "godot", "*****SETUP OK"); + + java_class_wrapper = memnew(JavaClassWrapper(_godot_instance)); + ProjectSettings::get_singleton()->add_singleton(ProjectSettings::Singleton("JavaClassWrapper", java_class_wrapper)); + _initialize_java_modules(); +} + +JNIEXPORT void JNICALL Java_org_godotengine_godot_GodotLib_resize(JNIEnv *env, jobject obj, jint width, jint height, jboolean reload) { + + __android_log_print(ANDROID_LOG_INFO, "godot", "^_^_^_^_^ resize %lld, %i, %i\n", Thread::get_caller_id(), width, height); + if (os_android) + os_android->set_display_size(Size2(width, height)); + + /*input_mutex->lock(); + resized=true; + if (reload) + resized_reload=true; + new_size=Size2(width,height); + input_mutex->unlock();*/ +} + +JNIEXPORT void JNICALL Java_org_godotengine_godot_GodotLib_newcontext(JNIEnv *env, jobject obj, bool p_32_bits) { + + __android_log_print(ANDROID_LOG_INFO, "godot", "^_^_^_^_^ newcontext %lld\n", Thread::get_caller_id()); + + if (os_android) { + os_android->set_context_is_16_bits(!p_32_bits); + } + + if (os_android && step > 0) { + + os_android->reload_gfx(); + } +} + +JNIEXPORT void JNICALL Java_org_godotengine_godot_GodotLib_back(JNIEnv *env, jobject obj) { + go_back_request = true; +} + +JNIEXPORT void JNICALL Java_org_godotengine_godot_GodotLib_step(JNIEnv *env, jobject obj) { + if (step == 0) { + __android_log_print(ANDROID_LOG_INFO, "godot", "**FIRST_STEP"); // Since Godot is initialized on the UI thread, _main_thread_id was set to that thread's id, // but for Godot purposes, the main thread is the one running the game loop Main::setup2(Thread::get_caller_id()); ++step; - suspend_mutex->unlock(); - input_mutex->unlock(); return; - }; + } + if (step == 1) { if (!Main::start()) { - - input_mutex->unlock(); - suspend_mutex->lock(); return; //should exit instead and print the error } @@ -1022,6 +1009,8 @@ JNIEXPORT void JNICALL Java_org_godotengine_godot_GodotLib_step(JNIEnv *env, job ++step; } + //__android_log_print(ANDROID_LOG_INFO,"godot","**STEP EVENT! - %p-%i\n",env,Thread::get_caller_id()); + while (pointer_events.size()) { JAndroidPointerEvent jpe = pointer_events.front()->get(); @@ -1052,8 +1041,6 @@ JNIEXPORT void JNICALL Java_org_godotengine_godot_GodotLib_step(JNIEnv *env, job go_back_request = false; } - input_mutex->unlock(); - os_android->process_accelerometer(accelerometer); os_android->process_magnetometer(magnetometer); @@ -1067,8 +1054,6 @@ JNIEXPORT void JNICALL Java_org_godotengine_godot_GodotLib_step(JNIEnv *env, job env->CallVoidMethod(_godot_instance, _finish); __android_log_print(ANDROID_LOG_INFO, "godot", "**FINISH REQUEST!!! - %p-%i\n", env, Thread::get_caller_id()); } - - suspend_mutex->unlock(); } JNIEXPORT void JNICALL Java_org_godotengine_godot_GodotLib_touch(JNIEnv *env, jobject obj, jint ev, jint pointer, jint count, jintArray positions) { @@ -1091,11 +1076,7 @@ JNIEXPORT void JNICALL Java_org_godotengine_godot_GodotLib_touch(JNIEnv *env, jo jpe.points = points; jpe.what = ev; - input_mutex->lock(); - pointer_events.push_back(jpe); - - input_mutex->unlock(); /* if (os_android) os_android->process_touch(ev,pointer,points); @@ -1365,9 +1346,7 @@ JNIEXPORT void JNICALL Java_org_godotengine_godot_GodotLib_joybutton(JNIEnv *env jevent.index = p_button; jevent.pressed = p_pressed; - input_mutex->lock(); joy_events.push_back(jevent); - input_mutex->unlock(); } JNIEXPORT void JNICALL Java_org_godotengine_godot_GodotLib_joyaxis(JNIEnv *env, jobject obj, jint p_device, jint p_axis, jfloat p_value) { @@ -1378,9 +1357,7 @@ JNIEXPORT void JNICALL Java_org_godotengine_godot_GodotLib_joyaxis(JNIEnv *env, jevent.index = p_axis; jevent.value = p_value; - input_mutex->lock(); joy_events.push_back(jevent); - input_mutex->unlock(); } JNIEXPORT void JNICALL Java_org_godotengine_godot_GodotLib_joyhat(JNIEnv *env, jobject obj, jint p_device, jint p_hat_x, jint p_hat_y) { @@ -1401,9 +1378,7 @@ JNIEXPORT void JNICALL Java_org_godotengine_godot_GodotLib_joyhat(JNIEnv *env, j hat |= InputDefault::HAT_MASK_DOWN; } jevent.hat = hat; - input_mutex->lock(); joy_events.push_back(jevent); - input_mutex->unlock(); } JNIEXPORT void JNICALL Java_org_godotengine_godot_GodotLib_joyconnectionchanged(JNIEnv *env, jobject obj, jint p_device, jboolean p_connected, jstring p_name) { @@ -1437,54 +1412,31 @@ JNIEXPORT void JNICALL Java_org_godotengine_godot_GodotLib_key(JNIEnv *env, jobj go_back_request = true; } - input_mutex->lock(); key_events.push_back(ievent); - input_mutex->unlock(); } JNIEXPORT void JNICALL Java_org_godotengine_godot_GodotLib_accelerometer(JNIEnv *env, jobject obj, jfloat x, jfloat y, jfloat z) { - - input_mutex->lock(); accelerometer = Vector3(x, y, z); - input_mutex->unlock(); } JNIEXPORT void JNICALL Java_org_godotengine_godot_GodotLib_magnetometer(JNIEnv *env, jobject obj, jfloat x, jfloat y, jfloat z) { - - input_mutex->lock(); magnetometer = Vector3(x, y, z); - input_mutex->unlock(); } JNIEXPORT void JNICALL Java_org_godotengine_godot_GodotLib_gyroscope(JNIEnv *env, jobject obj, jfloat x, jfloat y, jfloat z) { - - input_mutex->lock(); gyroscope = Vector3(x, y, z); - input_mutex->unlock(); } JNIEXPORT void JNICALL Java_org_godotengine_godot_GodotLib_focusin(JNIEnv *env, jobject obj) { - if (!suspend_mutex) - return; - suspend_mutex->lock(); - if (os_android && step > 0) os_android->main_loop_focusin(); - - suspend_mutex->unlock(); } JNIEXPORT void JNICALL Java_org_godotengine_godot_GodotLib_focusout(JNIEnv *env, jobject obj) { - if (!suspend_mutex) - return; - suspend_mutex->lock(); - if (os_android && step > 0) os_android->main_loop_focusout(); - - suspend_mutex->unlock(); } JNIEXPORT void JNICALL Java_org_godotengine_godot_GodotLib_audio(JNIEnv *env, jobject obj) { diff --git a/platform/android/java_glue.h b/platform/android/java_glue.h index 64970040f8..ec8ae9a0a6 100644 --- a/platform/android/java_glue.h +++ b/platform/android/java_glue.h @@ -36,7 +36,8 @@ #include <jni.h> extern "C" { -JNIEXPORT void JNICALL Java_org_godotengine_godot_GodotLib_initialize(JNIEnv *env, jobject obj, jobject activity, jboolean p_need_reload_hook, jobjectArray p_cmdline, jobject p_asset_manager); +JNIEXPORT void JNICALL Java_org_godotengine_godot_GodotLib_initialize(JNIEnv *env, jobject obj, jobject activity, jboolean p_need_reload_hook, jobject p_asset_manager, jboolean p_use_apk_expansion); +JNIEXPORT void JNICALL Java_org_godotengine_godot_GodotLib_setup(JNIEnv *env, jobject obj, jobjectArray p_cmdline); JNIEXPORT void JNICALL Java_org_godotengine_godot_GodotLib_resize(JNIEnv *env, jobject obj, jint width, jint height, jboolean reload); JNIEXPORT void JNICALL Java_org_godotengine_godot_GodotLib_newcontext(JNIEnv *env, jobject obj, bool p_32_bits); JNIEXPORT void JNICALL Java_org_godotengine_godot_GodotLib_step(JNIEnv *env, jobject obj); diff --git a/platform/iphone/icloud.h b/platform/iphone/icloud.h index 7ab3e04bb8..6944ee6749 100644 --- a/platform/iphone/icloud.h +++ b/platform/iphone/icloud.h @@ -1,5 +1,5 @@ /*************************************************************************/ -/* icloud.h */ +/* icloud.h */ /*************************************************************************/ /* This file is part of: */ /* GODOT ENGINE */ diff --git a/platform/iphone/icloud.mm b/platform/iphone/icloud.mm index 84458ed79f..097018f296 100644 --- a/platform/iphone/icloud.mm +++ b/platform/iphone/icloud.mm @@ -1,5 +1,5 @@ /*************************************************************************/ -/* icloud.mm */ +/* icloud.mm */ /*************************************************************************/ /* This file is part of: */ /* GODOT ENGINE */ diff --git a/platform/osx/joypad_osx.h b/platform/osx/joypad_osx.h index e271f4b947..4bdef8eb83 100644 --- a/platform/osx/joypad_osx.h +++ b/platform/osx/joypad_osx.h @@ -1,5 +1,5 @@ /*************************************************************************/ -/* joypad_osx.h */ +/* joypad_osx.h */ /*************************************************************************/ /* This file is part of: */ /* GODOT ENGINE */ diff --git a/platform/osx/power_osx.cpp b/platform/osx/power_osx.cpp index 24591e48b1..5f3938cb91 100644 --- a/platform/osx/power_osx.cpp +++ b/platform/osx/power_osx.cpp @@ -1,5 +1,5 @@ /*************************************************************************/ -/* power_osx.cpp */ +/* power_osx.cpp */ /*************************************************************************/ /* This file is part of: */ /* GODOT ENGINE */ diff --git a/platform/windows/joypad.cpp b/platform/windows/joypad.cpp index cde72c98c9..00cfa812de 100644 --- a/platform/windows/joypad.cpp +++ b/platform/windows/joypad.cpp @@ -1,5 +1,5 @@ /*************************************************************************/ -/* joypad.cpp */ +/* joypad.cpp */ /*************************************************************************/ /* This file is part of: */ /* GODOT ENGINE */ diff --git a/platform/windows/joypad.h b/platform/windows/joypad.h index 059c577bb6..a76caf6fac 100644 --- a/platform/windows/joypad.h +++ b/platform/windows/joypad.h @@ -1,5 +1,5 @@ /*************************************************************************/ -/* joypad.h */ +/* joypad.h */ /*************************************************************************/ /* This file is part of: */ /* GODOT ENGINE */ diff --git a/scene/3d/collision_shape.cpp b/scene/3d/collision_shape.cpp index 4d4ed30d03..5f1151f8e9 100644 --- a/scene/3d/collision_shape.cpp +++ b/scene/3d/collision_shape.cpp @@ -1,5 +1,5 @@ /*************************************************************************/ -/* body_shape.cpp */ +/* collision_shape.cpp */ /*************************************************************************/ /* This file is part of: */ /* GODOT ENGINE */ diff --git a/scene/3d/collision_shape.h b/scene/3d/collision_shape.h index 6d849f42af..94621177cb 100644 --- a/scene/3d/collision_shape.h +++ b/scene/3d/collision_shape.h @@ -1,5 +1,5 @@ /*************************************************************************/ -/* body_shape.h */ +/* collision_shape.h */ /*************************************************************************/ /* This file is part of: */ /* GODOT ENGINE */ diff --git a/scene/3d/immediate_geometry.h b/scene/3d/immediate_geometry.h index b2bcb5af1a..6db825bf54 100644 --- a/scene/3d/immediate_geometry.h +++ b/scene/3d/immediate_geometry.h @@ -1,5 +1,5 @@ /*************************************************************************/ -/* immediate_geometry.h */ +/* immediate_geometry.h */ /*************************************************************************/ /* This file is part of: */ /* GODOT ENGINE */ diff --git a/scene/3d/physics_body.cpp b/scene/3d/physics_body.cpp index a0a393e8ed..9590394211 100644 --- a/scene/3d/physics_body.cpp +++ b/scene/3d/physics_body.cpp @@ -918,7 +918,7 @@ Dictionary KinematicBody::_move(const Vector3 &p_motion) { if (move(p_motion, col)) { Dictionary d; d["position"] = col.collision; - d["normal"] = col.collision; + d["normal"] = col.normal; d["local_shape"] = col.local_shape; d["travel"] = col.travel; d["remainder"] = col.remainder; @@ -929,6 +929,7 @@ Dictionary KinematicBody::_move(const Vector3 &p_motion) { d["collider"] = Variant(); } + d["collider_velocity"] = col.collider_vel; d["collider_shape_index"] = col.collider_shape; d["collider_metadata"] = col.collider_metadata; diff --git a/scene/3d/remote_transform.cpp b/scene/3d/remote_transform.cpp index 3d402fa5af..8faf985b11 100644 --- a/scene/3d/remote_transform.cpp +++ b/scene/3d/remote_transform.cpp @@ -1,6 +1,5 @@ - /*************************************************************************/ -/* remote_transform.cpp */ +/* remote_transform.cpp */ /*************************************************************************/ /* This file is part of: */ /* GODOT ENGINE */ diff --git a/scene/animation/animation_tree_player.cpp b/scene/animation/animation_tree_player.cpp index e2330eb0d4..5be7949e93 100644 --- a/scene/animation/animation_tree_player.cpp +++ b/scene/animation/animation_tree_player.cpp @@ -1002,7 +1002,7 @@ void AnimationTreePlayer::animation_node_set_master_animation(const StringName & _update_sources(); } -void AnimationTreePlayer::animation_node_set_filter_path(const StringName &p_node, const NodePath &p_track_path, bool p_filter) { +void AnimationTreePlayer::animation_node_set_filter_path(const StringName &p_node, const NodePath &p_track_path, bool p_track_path) { GET_NODE(NODE_ANIMATION, AnimationNode); diff --git a/scene/animation/animation_tree_player.h b/scene/animation/animation_tree_player.h index 71d7277118..609430340b 100644 --- a/scene/animation/animation_tree_player.h +++ b/scene/animation/animation_tree_player.h @@ -347,7 +347,7 @@ public: void animation_node_set_master_animation(const StringName &p_node, const String &p_master_animation); String animation_node_get_master_animation(const StringName &p_node) const; - void animation_node_set_filter_path(const StringName &p_node, const NodePath &p_filter, bool p_enable); + void animation_node_set_filter_path(const StringName &p_node, const NodePath &p_track_path, bool p_filter); void animation_node_set_get_filtered_paths(const StringName &p_node, List<NodePath> *r_paths) const; bool animation_node_is_path_filtered(const StringName &p_node, const NodePath &p_path) const; diff --git a/scene/gui/check_box.h b/scene/gui/check_box.h index 4a1adb5f2f..4da06be8d1 100644 --- a/scene/gui/check_box.h +++ b/scene/gui/check_box.h @@ -1,5 +1,5 @@ /*************************************************************************/ -/* check_box.h */ +/* check_box.h */ /*************************************************************************/ /* This file is part of: */ /* GODOT ENGINE */ diff --git a/scene/gui/label.cpp b/scene/gui/label.cpp index 5fe3dd0129..5ed5463f65 100644 --- a/scene/gui/label.cpp +++ b/scene/gui/label.cpp @@ -85,7 +85,7 @@ void Label::_notification(int p_what) { Size2 string_size; Size2 size = get_size(); - + Ref<StyleBox> style = get_stylebox("normal"); Ref<Font> font = get_font("font"); Color font_color = get_color("font_color"); Color font_color_shadow = get_color("font_color_shadow"); @@ -93,6 +93,8 @@ void Label::_notification(int p_what) { Point2 shadow_ofs(get_constant("shadow_offset_x"), get_constant("shadow_offset_y")); int line_spacing = get_constant("line_spacing"); + style->draw(ci, Rect2(Point2(0, 0), get_size())); + VisualServer::get_singleton()->canvas_item_set_distance_field_mode(get_canvas_item(), font.is_valid() && font->is_distance_field_hint()); int font_h = font->get_height() + line_spacing; @@ -193,21 +195,20 @@ void Label::_notification(int p_what) { case ALIGN_FILL: case ALIGN_LEFT: { - x_ofs = 0; + x_ofs = style->get_offset().x; } break; case ALIGN_CENTER: { x_ofs = int(size.width - (taken + spaces * space_w)) / 2; - } break; case ALIGN_RIGHT: { - x_ofs = int(size.width - (taken + spaces * space_w)); - + x_ofs = int(size.width - style->get_margin(MARGIN_RIGHT) - (taken + spaces * space_w)); } break; } - int y_ofs = (line - lines_skipped) * font_h + font->get_ascent(); + int y_ofs = style->get_offset().y; + y_ofs += (line - lines_skipped) * font_h + font->get_ascent(); y_ofs += vbegin + line * vsep; while (from != to) { @@ -288,8 +289,10 @@ void Label::_notification(int p_what) { Size2 Label::get_minimum_size() const { + Size2 min_style = get_stylebox("normal")->get_minimum_size(); + if (autowrap) - return Size2(1, clip ? 1 : minsize.height); + return Size2(1, clip ? 1 : minsize.height) + min_style; else { // don't want to mutable everything @@ -299,7 +302,7 @@ Size2 Label::get_minimum_size() const { Size2 ms = minsize; if (clip) ms.width = 1; - return ms; + return ms + min_style; } } @@ -350,7 +353,7 @@ int Label::get_visible_line_count() const { int line_spacing = get_constant("line_spacing"); int font_h = get_font("font")->get_height() + line_spacing; - int lines_visible = (get_size().y + line_spacing) / font_h; + int lines_visible = (get_size().height - get_stylebox("normal")->get_minimum_size().height + line_spacing) / font_h; if (lines_visible > line_count) lines_visible = line_count; @@ -370,7 +373,8 @@ void Label::regenerate_word_cache() { memdelete(current); } - int width = autowrap ? get_size().width : get_longest_line_width(); + Ref<StyleBox> style = get_stylebox("normal"); + int width = autowrap ? (get_size().width - style->get_minimum_size().width) : get_longest_line_width(); Ref<Font> font = get_font("font"); int current_word_size = 0; diff --git a/scene/gui/patch_9_rect.cpp b/scene/gui/patch_9_rect.cpp index 6b2deeb209..92c34dd3f9 100644 --- a/scene/gui/patch_9_rect.cpp +++ b/scene/gui/patch_9_rect.cpp @@ -61,7 +61,7 @@ void NinePatchRect::_bind_methods() { ClassDB::bind_method(D_METHOD("set_region_rect", "rect"), &NinePatchRect::set_region_rect); ClassDB::bind_method(D_METHOD("get_region_rect"), &NinePatchRect::get_region_rect); ClassDB::bind_method(D_METHOD("set_draw_center", "draw_center"), &NinePatchRect::set_draw_center); - ClassDB::bind_method(D_METHOD("get_draw_center"), &NinePatchRect::get_draw_center); + ClassDB::bind_method(D_METHOD("is_draw_center_enabled"), &NinePatchRect::is_draw_center_enabled); ClassDB::bind_method(D_METHOD("set_h_axis_stretch_mode", "mode"), &NinePatchRect::set_h_axis_stretch_mode); ClassDB::bind_method(D_METHOD("get_h_axis_stretch_mode"), &NinePatchRect::get_h_axis_stretch_mode); ClassDB::bind_method(D_METHOD("set_v_axis_stretch_mode", "mode"), &NinePatchRect::set_v_axis_stretch_mode); @@ -70,7 +70,7 @@ void NinePatchRect::_bind_methods() { ADD_SIGNAL(MethodInfo("texture_changed")); ADD_PROPERTYNZ(PropertyInfo(Variant::OBJECT, "texture", PROPERTY_HINT_RESOURCE_TYPE, "Texture"), "set_texture", "get_texture"); - ADD_PROPERTYNO(PropertyInfo(Variant::BOOL, "draw_center"), "set_draw_center", "get_draw_center"); + ADD_PROPERTYNO(PropertyInfo(Variant::BOOL, "draw_center"), "set_draw_center", "is_draw_center_enabled"); ADD_PROPERTYNZ(PropertyInfo(Variant::RECT2, "region_rect"), "set_region_rect", "get_region_rect"); ADD_GROUP("Patch Margin", "patch_margin_"); @@ -151,13 +151,13 @@ Rect2 NinePatchRect::get_region_rect() const { return region_rect; } -void NinePatchRect::set_draw_center(bool p_draw) { +void NinePatchRect::set_draw_center(bool p_enabled) { - draw_center = p_draw; + draw_center = p_enabled; update(); } -bool NinePatchRect::get_draw_center() const { +bool NinePatchRect::is_draw_center_enabled() const { return draw_center; } diff --git a/scene/gui/patch_9_rect.h b/scene/gui/patch_9_rect.h index 4cf93e4c05..808b7a1f5d 100644 --- a/scene/gui/patch_9_rect.h +++ b/scene/gui/patch_9_rect.h @@ -67,8 +67,8 @@ public: void set_region_rect(const Rect2 &p_region_rect); Rect2 get_region_rect() const; - void set_draw_center(bool p_draw); - bool get_draw_center() const; + void set_draw_center(bool p_enabled); + bool is_draw_center_enabled() const; void set_h_axis_stretch_mode(AxisStretchMode p_mode); AxisStretchMode get_h_axis_stretch_mode() const; diff --git a/scene/gui/text_edit.cpp b/scene/gui/text_edit.cpp index 7a9daea73e..7b93393851 100644 --- a/scene/gui/text_edit.cpp +++ b/scene/gui/text_edit.cpp @@ -2113,15 +2113,15 @@ void TextEdit::_gui_input(const Ref<InputEvent> &p_gui_input) { //keep indentation int space_count = 0; - for (int i = 0; i < text[cursor.line].length(); i++) { - if (text[cursor.line][i] == '\t' && cursor.column > 0) { + for (int i = 0; i < cursor.column; i++) { + if (text[cursor.line][i] == '\t') { if (indent_using_spaces) { ins += space_indent; } else { ins += "\t"; } space_count = 0; - } else if (text[cursor.line][i] == ' ' && cursor.column > 0) { + } else if (text[cursor.line][i] == ' ') { space_count++; if (space_count == indent_size) { diff --git a/scene/main/scene_tree.cpp b/scene/main/scene_tree.cpp index 65aeb23609..a71b491bae 100644 --- a/scene/main/scene_tree.cpp +++ b/scene/main/scene_tree.cpp @@ -1,5 +1,5 @@ /*************************************************************************/ -/* scene_main_loop.cpp */ +/* scene_tree.cpp */ /*************************************************************************/ /* This file is part of: */ /* GODOT ENGINE */ @@ -542,6 +542,10 @@ bool SceneTree::idle(float p_time) { if (env_path != String()) { fallback = ResourceLoader::load(env_path); + if (fallback.is_null()) { + //could not load fallback, set as empty + ProjectSettings::get_singleton()->set("rendering/environment/default_environment", ""); + } } else { fallback.unref(); } diff --git a/scene/main/scene_tree.h b/scene/main/scene_tree.h index 594b806cef..c116bec4fc 100644 --- a/scene/main/scene_tree.h +++ b/scene/main/scene_tree.h @@ -1,5 +1,5 @@ /*************************************************************************/ -/* scene_main_loop.h */ +/* scene_tree.h */ /*************************************************************************/ /* This file is part of: */ /* GODOT ENGINE */ diff --git a/scene/main/viewport.cpp b/scene/main/viewport.cpp index 02da926e50..36dbd14b40 100644 --- a/scene/main/viewport.cpp +++ b/scene/main/viewport.cpp @@ -1202,15 +1202,15 @@ bool Viewport::get_vflip() const { return vflip; } -void Viewport::set_clear_on_new_frame(bool p_enable) { +void Viewport::set_clear_mode(ClearMode p_mode) { - clear_on_new_frame = p_enable; - //VisualServer::get_singleton()->viewport_set_clear_on_new_frame(viewport,p_enable); + clear_mode = p_mode; + VS::get_singleton()->viewport_set_clear_mode(viewport, VS::ViewportClearMode(p_mode)); } -bool Viewport::get_clear_on_new_frame() const { +Viewport::ClearMode Viewport::get_clear_mode() const { - return clear_on_new_frame; + return clear_mode; } void Viewport::set_shadow_atlas_size(int p_size) { @@ -1246,12 +1246,6 @@ Viewport::ShadowAtlasQuadrantSubdiv Viewport::get_shadow_atlas_quadrant_subdiv(i return shadow_atlas_quadrant_subdiv[p_quadrant]; } -void Viewport::clear() { - - //clear=true; - //VisualServer::get_singleton()->viewport_clear(viewport); -} - Transform2D Viewport::_get_input_pre_xform() const { Transform2D pre_xf; @@ -2625,10 +2619,9 @@ void Viewport::_bind_methods() { ClassDB::bind_method(D_METHOD("set_vflip", "enable"), &Viewport::set_vflip); ClassDB::bind_method(D_METHOD("get_vflip"), &Viewport::get_vflip); - ClassDB::bind_method(D_METHOD("set_clear_on_new_frame", "enable"), &Viewport::set_clear_on_new_frame); - ClassDB::bind_method(D_METHOD("get_clear_on_new_frame"), &Viewport::get_clear_on_new_frame); + ClassDB::bind_method(D_METHOD("set_clear_mode", "mode"), &Viewport::set_clear_mode); + ClassDB::bind_method(D_METHOD("get_clear_mode"), &Viewport::get_clear_mode); - ClassDB::bind_method(D_METHOD("clear"), &Viewport::clear); ClassDB::bind_method(D_METHOD("set_update_mode", "mode"), &Viewport::set_update_mode); ClassDB::bind_method(D_METHOD("get_update_mode"), &Viewport::get_update_mode); @@ -2705,7 +2698,7 @@ void Viewport::_bind_methods() { ADD_PROPERTY(PropertyInfo(Variant::INT, "debug_draw", PROPERTY_HINT_ENUM, "Disabled,Unshaded,Overdraw,Wireframe"), "set_debug_draw", "get_debug_draw"); ADD_GROUP("Render Target", "render_target_"); ADD_PROPERTY(PropertyInfo(Variant::BOOL, "render_target_v_flip"), "set_vflip", "get_vflip"); - ADD_PROPERTY(PropertyInfo(Variant::BOOL, "render_target_clear_on_new_frame"), "set_clear_on_new_frame", "get_clear_on_new_frame"); + ADD_PROPERTY(PropertyInfo(Variant::BOOL, "render_target_clear_mode", PROPERTY_HINT_ENUM, "Always,Never,NextFrame"), "set_clear_mode", "get_clear_mode"); ADD_PROPERTY(PropertyInfo(Variant::INT, "render_target_update_mode", PROPERTY_HINT_ENUM, "Disabled,Once,When Visible,Always"), "set_update_mode", "get_update_mode"); ADD_GROUP("Audio Listener", "audio_listener_"); ADD_PROPERTY(PropertyInfo(Variant::BOOL, "audio_listener_enable_2d"), "set_as_audio_listener_2d", "is_audio_listener_2d"); @@ -2784,7 +2777,7 @@ Viewport::Viewport() { gen_mipmaps = false; vflip = false; - clear_on_new_frame = true; + //clear=true; update_mode = UPDATE_WHEN_VISIBLE; @@ -2828,6 +2821,7 @@ Viewport::Viewport() { usage = USAGE_3D; debug_draw = DEBUG_DRAW_DISABLED; + clear_mode = CLEAR_MODE_ALWAYS; } Viewport::~Viewport() { diff --git a/scene/main/viewport.h b/scene/main/viewport.h index f527fa4f5b..ce2bc991f5 100644 --- a/scene/main/viewport.h +++ b/scene/main/viewport.h @@ -140,6 +140,13 @@ public: DEBUG_DRAW_WIREFRAME, }; + enum ClearMode { + + CLEAR_MODE_ALWAYS, + CLEAR_MODE_NEVER, + CLEAR_MODE_ONLY_NEXT_FRAME + }; + private: friend class ViewportTexture; @@ -182,7 +189,7 @@ private: bool transparent_bg; bool vflip; - bool clear_on_new_frame; + ClearMode clear_mode; bool filter; bool gen_mipmaps; @@ -395,9 +402,8 @@ public: void set_vflip(bool p_enable); bool get_vflip() const; - void set_clear_on_new_frame(bool p_enable); - bool get_clear_on_new_frame() const; - void clear(); + void set_clear_mode(ClearMode p_mode); + ClearMode get_clear_mode() const; void set_update_mode(UpdateMode p_mode); UpdateMode get_update_mode() const; @@ -466,6 +472,7 @@ VARIANT_ENUM_CAST(Viewport::ShadowAtlasQuadrantSubdiv); VARIANT_ENUM_CAST(Viewport::MSAA); VARIANT_ENUM_CAST(Viewport::Usage); VARIANT_ENUM_CAST(Viewport::DebugDraw); +VARIANT_ENUM_CAST(Viewport::ClearMode); VARIANT_ENUM_CAST(Viewport::RenderInfo); #endif diff --git a/scene/resources/default_theme/default_theme.cpp b/scene/resources/default_theme/default_theme.cpp index 08de33175a..4ff635edeb 100644 --- a/scene/resources/default_theme/default_theme.cpp +++ b/scene/resources/default_theme/default_theme.cpp @@ -408,6 +408,7 @@ void fill_default_theme(Ref<Theme> &theme, const Ref<Font> &default_font, const // Label + theme->set_stylebox("normal", "Label", memnew(StyleBoxEmpty)); theme->set_font("font", "Label", default_font); theme->set_color("font_color", "Label", Color(1, 1, 1)); @@ -525,7 +526,7 @@ void fill_default_theme(Ref<Theme> &theme, const Ref<Font> &default_font, const theme->set_stylebox("slider", "VSlider", make_stylebox(vslider_bg_png, 4, 4, 4, 4)); theme->set_stylebox("grabber_highlight", "VSlider", make_stylebox(vslider_grabber_hl_png, 6, 6, 6, 6)); theme->set_stylebox("grabber_disabled", "VSlider", make_stylebox(vslider_grabber_disabled_png, 6, 6, 6, 6)); - theme->set_stylebox("focus", "HSlider", focus); + theme->set_stylebox("focus", "VSlider", focus); theme->set_icon("grabber", "VSlider", make_icon(vslider_grabber_png)); theme->set_icon("grabber_highlight", "VSlider", make_icon(vslider_grabber_hl_png)); diff --git a/scene/resources/default_theme/default_theme.h b/scene/resources/default_theme/default_theme.h index 9032b71775..f2a4b2616d 100644 --- a/scene/resources/default_theme/default_theme.h +++ b/scene/resources/default_theme/default_theme.h @@ -1,5 +1,5 @@ /*************************************************************************/ -/* default_theme.cpp */ +/* default_theme.h */ /*************************************************************************/ /* This file is part of: */ /* GODOT ENGINE */ diff --git a/scene/resources/material.cpp b/scene/resources/material.cpp index 77563121df..63b7fe4a86 100644 --- a/scene/resources/material.cpp +++ b/scene/resources/material.cpp @@ -48,6 +48,19 @@ Ref<Material> Material::get_next_pass() const { return next_pass; } +void Material::set_render_priority(int p_priority) { + + ERR_FAIL_COND(p_priority < RENDER_PRIORITY_MIN); + ERR_FAIL_COND(p_priority > RENDER_PRIORITY_MAX); + render_priority = p_priority; + VS::get_singleton()->material_set_render_priority(material, p_priority); +} + +int Material::get_render_priority() const { + + return render_priority; +} + RID Material::get_rid() const { return material; @@ -58,12 +71,20 @@ void Material::_bind_methods() { ClassDB::bind_method(D_METHOD("set_next_pass", "next_pass"), &Material::set_next_pass); ClassDB::bind_method(D_METHOD("get_next_pass"), &Material::get_next_pass); + ClassDB::bind_method(D_METHOD("set_render_priority", "priority"), &Material::set_render_priority); + ClassDB::bind_method(D_METHOD("get_render_priority"), &Material::get_render_priority); + + ADD_PROPERTY(PropertyInfo(Variant::OBJECT, "render_priority", PROPERTY_HINT_RANGE, itos(RENDER_PRIORITY_MIN) + "," + itos(RENDER_PRIORITY_MAX) + ",1"), "set_render_priority", "get_render_priority"); ADD_PROPERTY(PropertyInfo(Variant::OBJECT, "next_pass", PROPERTY_HINT_RESOURCE_TYPE, "Material"), "set_next_pass", "get_next_pass"); + + BIND_CONSTANT(RENDER_PRIORITY_MAX); + BIND_CONSTANT(RENDER_PRIORITY_MIN); } Material::Material() { material = VisualServer::get_singleton()->material_create(); + render_priority = 0; } Material::~Material() { @@ -227,8 +248,8 @@ void SpatialMaterial::init_shaders() { shader_names->uv1_blend_sharpness = "uv1_blend_sharpness"; shader_names->uv2_blend_sharpness = "uv2_blend_sharpness"; - shader_names->particle_h_frames = "particle_h_frames"; - shader_names->particle_v_frames = "particle_v_frames"; + shader_names->particles_anim_h_frames = "particles_anim_h_frames"; + shader_names->particles_anim_v_frames = "particles_anim_v_frames"; shader_names->particles_anim_loop = "particles_anim_loop"; shader_names->depth_min_layers = "depth_min_layers"; shader_names->depth_max_layers = "depth_max_layers"; @@ -347,8 +368,8 @@ void SpatialMaterial::_update_shader() { if (flags[FLAG_UNSHADED]) { code += ",unshaded"; } - if (flags[FLAG_ONTOP]) { - code += ",ontop"; + if (flags[FLAG_DISABLE_DEPTH_TEST]) { + code += ",depth_test_disable"; } if (flags[FLAG_USE_VERTEX_LIGHTING]) { code += ",vertex_lighting"; @@ -503,8 +524,8 @@ void SpatialMaterial::_update_shader() { code += "\tint particle_total_frames = particles_anim_h_frames * particles_anim_v_frames;\n"; code += "\tint particle_frame = int(INSTANCE_CUSTOM.y * float(particle_total_frames));\n"; code += "\tif (particles_anim_loop) particle_frame=clamp(particle_frame,0,particle_total_frames-1); else particle_frame=abs(particle_frame)%particle_total_frames;\n"; - //code += "\tUV /= vec2(float(particles_anim_h_frames),float(particles_anim_v_frames));\n"; - //code += "\tUV+= UV * vec2(float(particle_frame % particles_anim_h_frames),float(particle_frame / particles_anim_v_frames));\n"; + code += "\tUV /= vec2(float(particles_anim_h_frames),float(particles_anim_v_frames));\n"; + code += "\tUV += vec2(float(particle_frame % particles_anim_h_frames) / float(particles_anim_h_frames),float(particle_frame / particles_anim_h_frames) / float(particles_anim_v_frames));\n"; //handle rotation // code += "\tmat4 rotation = mat4(" } break; @@ -530,7 +551,7 @@ void SpatialMaterial::_update_shader() { } if (detail_uv == DETAIL_UV_2 && !flags[FLAG_UV2_USE_TRIPLANAR]) { - code += "\tUV2=UV2*uv2_scale+uv2_offset;\n"; + code += "\tUV2=UV2*uv2_scale.xy+uv2_offset.xy;\n"; } if (flags[FLAG_UV1_USE_TRIPLANAR] || flags[FLAG_UV2_USE_TRIPLANAR]) { //generate tangent and binormal in world space @@ -1281,7 +1302,7 @@ SpatialMaterial::BillboardMode SpatialMaterial::get_billboard_mode() const { void SpatialMaterial::set_particles_anim_h_frames(int p_frames) { particles_anim_h_frames = p_frames; - VS::get_singleton()->material_set_param(_get_material(), shader_names->particle_h_frames, p_frames); + VS::get_singleton()->material_set_param(_get_material(), shader_names->particles_anim_h_frames, p_frames); } int SpatialMaterial::get_particles_anim_h_frames() const { @@ -1291,7 +1312,7 @@ int SpatialMaterial::get_particles_anim_h_frames() const { void SpatialMaterial::set_particles_anim_v_frames(int p_frames) { particles_anim_v_frames = p_frames; - VS::get_singleton()->material_set_param(_get_material(), shader_names->particle_v_frames, p_frames); + VS::get_singleton()->material_set_param(_get_material(), shader_names->particles_anim_v_frames, p_frames); } int SpatialMaterial::get_particles_anim_v_frames() const { @@ -1459,6 +1480,12 @@ RID SpatialMaterial::get_material_rid_for_2d(bool p_shaded, bool p_transparent, return materials_for_2d[version]->get_rid(); } +void SpatialMaterial::set_on_top_of_alpha() { + set_feature(FEATURE_TRANSPARENT, true); + set_render_priority(RENDER_PRIORITY_MAX); + set_flag(FLAG_DISABLE_DEPTH_TEST, true); +} + void SpatialMaterial::_bind_methods() { ClassDB::bind_method(D_METHOD("set_albedo", "albedo"), &SpatialMaterial::set_albedo); @@ -1606,7 +1633,7 @@ void SpatialMaterial::_bind_methods() { ADD_PROPERTYI(PropertyInfo(Variant::BOOL, "flags_transparent"), "set_feature", "get_feature", FEATURE_TRANSPARENT); ADD_PROPERTYI(PropertyInfo(Variant::BOOL, "flags_unshaded"), "set_flag", "get_flag", FLAG_UNSHADED); ADD_PROPERTYI(PropertyInfo(Variant::BOOL, "flags_vertex_lighting"), "set_flag", "get_flag", FLAG_USE_VERTEX_LIGHTING); - ADD_PROPERTYI(PropertyInfo(Variant::BOOL, "flags_on_top"), "set_flag", "get_flag", FLAG_ONTOP); + ADD_PROPERTYI(PropertyInfo(Variant::BOOL, "flags_no_depth_test"), "set_flag", "get_flag", FLAG_DISABLE_DEPTH_TEST); ADD_PROPERTYI(PropertyInfo(Variant::BOOL, "flags_use_point_size"), "set_flag", "get_flag", FLAG_USE_POINT_SIZE); ADD_PROPERTYI(PropertyInfo(Variant::BOOL, "flags_fixed_size"), "set_flag", "get_flag", FLAG_FIXED_SIZE); ADD_GROUP("Vertex Color", "vertex_color"); @@ -1768,7 +1795,7 @@ void SpatialMaterial::_bind_methods() { BIND_ENUM_CONSTANT(FLAG_UNSHADED); BIND_ENUM_CONSTANT(FLAG_USE_VERTEX_LIGHTING); - BIND_ENUM_CONSTANT(FLAG_ONTOP); + BIND_ENUM_CONSTANT(FLAG_DISABLE_DEPTH_TEST); BIND_ENUM_CONSTANT(FLAG_ALBEDO_FROM_VERTEX_COLOR); BIND_ENUM_CONSTANT(FLAG_SRGB_VERTEX_COLOR); BIND_ENUM_CONSTANT(FLAG_USE_POINT_SIZE); diff --git a/scene/resources/material.h b/scene/resources/material.h index b82e8d8cbd..4977e5dd70 100644 --- a/scene/resources/material.h +++ b/scene/resources/material.h @@ -48,15 +48,23 @@ class Material : public Resource { RID material; Ref<Material> next_pass; + int render_priority; protected: _FORCE_INLINE_ RID _get_material() const { return material; } static void _bind_methods(); public: + enum { + RENDER_PRIORITY_MAX = VS::MATERIAL_RENDER_PRIORITY_MAX, + RENDER_PRIORITY_MIN = VS::MATERIAL_RENDER_PRIORITY_MIN, + }; void set_next_pass(const Ref<Material> &p_pass); Ref<Material> get_next_pass() const; + void set_render_priority(int p_priority); + int get_render_priority() const; + virtual RID get_rid() const; Material(); virtual ~Material(); @@ -156,7 +164,7 @@ public: enum Flags { FLAG_UNSHADED, FLAG_USE_VERTEX_LIGHTING, - FLAG_ONTOP, + FLAG_DISABLE_DEPTH_TEST, FLAG_ALBEDO_FROM_VERTEX_COLOR, FLAG_SRGB_VERTEX_COLOR, FLAG_USE_POINT_SIZE, @@ -283,8 +291,8 @@ private: StringName uv1_offset; StringName uv2_scale; StringName uv2_offset; - StringName particle_h_frames; - StringName particle_v_frames; + StringName particles_anim_h_frames; + StringName particles_anim_v_frames; StringName particles_anim_loop; StringName depth_min_layers; StringName depth_max_layers; @@ -511,6 +519,8 @@ public: void set_alpha_scissor_threshold(float p_treshold); float get_alpha_scissor_threshold() const; + void set_on_top_of_alpha(); + void set_metallic_texture_channel(TextureChannel p_channel); TextureChannel get_metallic_texture_channel() const; void set_roughness_texture_channel(TextureChannel p_channel); diff --git a/scene/resources/scene_format_text.cpp b/scene/resources/scene_format_text.cpp index fea5c11dec..14e2ef83f8 100644 --- a/scene/resources/scene_format_text.cpp +++ b/scene/resources/scene_format_text.cpp @@ -891,7 +891,7 @@ String ResourceInteractiveLoaderText::recognize(FileAccess *p_f) { ///////////////////// -Ref<ResourceInteractiveLoader> ResourceFormatLoaderText::load_interactive(const String &p_path, Error *r_error) { +Ref<ResourceInteractiveLoader> ResourceFormatLoaderText::load_interactive(const String &p_path, const String &p_original_path, Error *r_error) { if (r_error) *r_error = ERR_CANT_OPEN; @@ -905,7 +905,8 @@ Ref<ResourceInteractiveLoader> ResourceFormatLoaderText::load_interactive(const } Ref<ResourceInteractiveLoaderText> ria = memnew(ResourceInteractiveLoaderText); - ria->local_path = ProjectSettings::get_singleton()->localize_path(p_path); + String path = p_original_path != "" ? p_original_path : p_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); diff --git a/scene/resources/scene_format_text.h b/scene/resources/scene_format_text.h index 193bcf7112..a72a62037c 100644 --- a/scene/resources/scene_format_text.h +++ b/scene/resources/scene_format_text.h @@ -108,7 +108,7 @@ public: class ResourceFormatLoaderText : public ResourceFormatLoader { public: - virtual Ref<ResourceInteractiveLoader> load_interactive(const String &p_path, Error *r_error = NULL); + virtual Ref<ResourceInteractiveLoader> load_interactive(const String &p_path, const String &p_original_path = "", Error *r_error = NULL); virtual void get_recognized_extensions_for_type(const String &p_type, List<String> *p_extensions) const; virtual void get_recognized_extensions(List<String> *p_extensions) const; virtual bool handles_type(const String &p_type) const; diff --git a/scene/resources/style_box.cpp b/scene/resources/style_box.cpp index f646e3667d..b8a0a7864e 100644 --- a/scene/resources/style_box.cpp +++ b/scene/resources/style_box.cpp @@ -165,13 +165,13 @@ void StyleBoxTexture::draw(RID p_canvas_item, const Rect2 &p_rect) const { VisualServer::get_singleton()->canvas_item_add_nine_patch(p_canvas_item, rect, src_rect, texture->get_rid(), Vector2(margin[MARGIN_LEFT], margin[MARGIN_TOP]), Vector2(margin[MARGIN_RIGHT], margin[MARGIN_BOTTOM]), VS::NinePatchAxisMode(axis_h), VS::NinePatchAxisMode(axis_v), draw_center, modulate, normal_rid); } -void StyleBoxTexture::set_draw_center(bool p_draw) { +void StyleBoxTexture::set_draw_center(bool p_enabled) { - draw_center = p_draw; + draw_center = p_enabled; emit_changed(); } -bool StyleBoxTexture::get_draw_center() const { +bool StyleBoxTexture::is_draw_center_enabled() const { return draw_center; } @@ -281,7 +281,7 @@ void StyleBoxTexture::_bind_methods() { ClassDB::bind_method(D_METHOD("get_region_rect"), &StyleBoxTexture::get_region_rect); ClassDB::bind_method(D_METHOD("set_draw_center", "enable"), &StyleBoxTexture::set_draw_center); - ClassDB::bind_method(D_METHOD("get_draw_center"), &StyleBoxTexture::get_draw_center); + ClassDB::bind_method(D_METHOD("is_draw_center_enabled"), &StyleBoxTexture::is_draw_center_enabled); ClassDB::bind_method(D_METHOD("set_modulate", "color"), &StyleBoxTexture::set_modulate); ClassDB::bind_method(D_METHOD("get_modulate"), &StyleBoxTexture::get_modulate); @@ -312,7 +312,7 @@ void StyleBoxTexture::_bind_methods() { ADD_PROPERTYNZ(PropertyInfo(Variant::INT, "axis_stretch_vertical", PROPERTY_HINT_ENUM, "Stretch,Tile,Tile Fit"), "set_v_axis_stretch_mode", "get_v_axis_stretch_mode"); ADD_GROUP("Modulate", "modulate_"); ADD_PROPERTY(PropertyInfo(Variant::COLOR, "modulate_color"), "set_modulate", "get_modulate"); - ADD_PROPERTY(PropertyInfo(Variant::BOOL, "draw_center"), "set_draw_center", "get_draw_center"); + ADD_PROPERTY(PropertyInfo(Variant::BOOL, "draw_center"), "set_draw_center", "is_draw_center_enabled"); BIND_ENUM_CONSTANT(AXIS_STRETCH_MODE_STRETCH); BIND_ENUM_CONSTANT(AXIS_STRETCH_MODE_TILE); @@ -460,14 +460,14 @@ float StyleBoxFlat::get_expand_margin_size(Margin p_expand_margin) const { return expand_margin[p_expand_margin]; } -void StyleBoxFlat::set_filled(bool p_filled) { +void StyleBoxFlat::set_draw_center(bool p_enabled) { - filled = p_filled; + draw_center = p_enabled; emit_changed(); } -bool StyleBoxFlat::is_filled() const { +bool StyleBoxFlat::is_draw_center_enabled() const { - return filled; + return draw_center; } void StyleBoxFlat::set_shadow_color(const Color &p_color) { @@ -691,7 +691,7 @@ void StyleBoxFlat::draw(RID p_canvas_item, const Rect2 &p_rect) const { style_rect, adapted_border, inner_color, border_color.read().ptr(), corner_detail); //DRAW INFILL - if (filled) { + if (draw_center) { int temp_vert_offset = verts.size(); int no_border[4] = { 0, 0, 0, 0 }; draw_ring(verts, indices, colors, style_rect, adapted_corner, @@ -724,7 +724,7 @@ void StyleBoxFlat::draw(RID p_canvas_item, const Rect2 &p_rect) const { int aa_border_width[4] = { aa_size, aa_size, aa_size, aa_size }; - if (filled) { + if (draw_center) { if (!blend_border) { //INFILL AA draw_ring(verts, indices, colors, style_rect, adapted_corner, @@ -776,8 +776,8 @@ void StyleBoxFlat::_bind_methods() { ClassDB::bind_method(D_METHOD("set_expand_margin_individual", "size_left", "size_top", "size_right", "size_bottom"), &StyleBoxFlat::set_expand_margin_size_individual); ClassDB::bind_method(D_METHOD("get_expand_margin", "margin"), &StyleBoxFlat::get_expand_margin_size); - ClassDB::bind_method(D_METHOD("set_filled", "filled"), &StyleBoxFlat::set_filled); - ClassDB::bind_method(D_METHOD("is_filled"), &StyleBoxFlat::is_filled); + ClassDB::bind_method(D_METHOD("set_draw_center", "draw_center"), &StyleBoxFlat::set_draw_center); + ClassDB::bind_method(D_METHOD("is_draw_center_enabled"), &StyleBoxFlat::is_draw_center_enabled); ClassDB::bind_method(D_METHOD("set_shadow_color", "color"), &StyleBoxFlat::set_shadow_color); ClassDB::bind_method(D_METHOD("get_shadow_color"), &StyleBoxFlat::get_shadow_color); @@ -796,7 +796,7 @@ void StyleBoxFlat::_bind_methods() { ADD_PROPERTY(PropertyInfo(Variant::COLOR, "bg_color"), "set_bg_color", "get_bg_color"); - ADD_PROPERTY(PropertyInfo(Variant::BOOL, "filled"), "set_filled", "is_filled"); + ADD_PROPERTY(PropertyInfo(Variant::BOOL, "draw_center"), "set_draw_center", "is_draw_center_enabled"); ADD_GROUP("Border Width", "border_width_"); ADD_PROPERTYI(PropertyInfo(Variant::INT, "border_width_left", PROPERTY_HINT_RANGE, "0,1024,1"), "set_border_width", "get_border_width", MARGIN_LEFT); @@ -843,7 +843,7 @@ StyleBoxFlat::StyleBoxFlat() { border_color.append(Color(0.8, 0.8, 0.8)); blend_border = false; - filled = true; + draw_center = true; anti_aliased = true; shadow_size = 0; diff --git a/scene/resources/style_box.h b/scene/resources/style_box.h index db41333b7e..3d085f7166 100644 --- a/scene/resources/style_box.h +++ b/scene/resources/style_box.h @@ -117,8 +117,8 @@ public: void set_normal_map(RES p_normal_map); RES get_normal_map() const; - void set_draw_center(bool p_draw); - bool get_draw_center() const; + void set_draw_center(bool p_enabled); + bool is_draw_center_enabled() const; virtual Size2 get_center_size() const; void set_h_axis_stretch_mode(AxisStretchMode p_mode); @@ -150,7 +150,7 @@ class StyleBoxFlat : public StyleBox { int expand_margin[4]; int corner_radius[4]; - bool filled; + bool draw_center; bool blend_border; bool anti_aliased; @@ -202,9 +202,9 @@ public: void set_expand_margin_size_individual(float p_left, float p_top, float p_right, float p_bottom); float get_expand_margin_size(Margin p_expand_margin) const; - //FILLED - void set_filled(bool p_draw); - bool is_filled() const; + //DRAW CENTER + void set_draw_center(bool p_enabled); + bool is_draw_center_enabled() const; //SHADOW void set_shadow_color(const Color &p_color); diff --git a/servers/physics_2d/physics_2d_server_sw.cpp b/servers/physics_2d/physics_2d_server_sw.cpp index 006c5fd7b5..e9e7122af3 100644 --- a/servers/physics_2d/physics_2d_server_sw.cpp +++ b/servers/physics_2d/physics_2d_server_sw.cpp @@ -130,9 +130,12 @@ void Physics2DServerSW::_shape_col_cbk(const Vector2 &p_point_A, const Vector2 & if (cbk->valid_dir != Vector2()) { if (p_point_A.distance_squared_to(p_point_B) > cbk->valid_depth * cbk->valid_depth) { + cbk->invalid_by_dir++; return; } if (cbk->valid_dir.dot((p_point_A - p_point_B).normalized()) < 0.7071) { + cbk->invalid_by_dir++; + ; /* print_line("A: "+p_point_A); print_line("B: "+p_point_B); print_line("discard too angled "+rtos(cbk->valid_dir.dot((p_point_A-p_point_B)))); diff --git a/servers/physics_2d/physics_2d_server_sw.h b/servers/physics_2d/physics_2d_server_sw.h index 7d3c589fa9..dd310d7a93 100644 --- a/servers/physics_2d/physics_2d_server_sw.h +++ b/servers/physics_2d/physics_2d_server_sw.h @@ -74,6 +74,7 @@ public: real_t valid_depth; int max; int amount; + int invalid_by_dir; Vector2 *ptr; }; diff --git a/servers/physics_2d/space_2d_sw.cpp b/servers/physics_2d/space_2d_sw.cpp index 9b2e586993..779f0d54ac 100644 --- a/servers/physics_2d/space_2d_sw.cpp +++ b/servers/physics_2d/space_2d_sw.cpp @@ -30,8 +30,8 @@ #include "space_2d_sw.h" #include "collision_solver_2d_sw.h" +#include "pair.h" #include "physics_2d_server_sw.h" - _FORCE_INLINE_ static bool _match_object_type_query(CollisionObject2DSW *p_object, uint32_t p_collision_layer, uint32_t p_type_mask) { if ((p_object->get_collision_layer() & p_collision_layer) == 0) @@ -517,6 +517,10 @@ bool Space2DSW::test_body_motion(Body2DSW *p_body, const Transform2D &p_from, co body_aabb = p_from.xform(p_body->get_inv_transform().xform(body_aabb)); body_aabb = body_aabb.grow(p_margin); + static const int max_excluded_shape_pairs = 32; + Pair<Shape2DSW *, Shape2DSW *> excluded_shape_pairs[max_excluded_shape_pairs]; + int excluded_shape_pair_count = 0; + Transform2D body_transform = p_from; { @@ -532,6 +536,8 @@ bool Space2DSW::test_body_motion(Body2DSW *p_body, const Transform2D &p_from, co cbk.max = max_results; cbk.amount = 0; cbk.ptr = sr; + cbk.invalid_by_dir = 0; + excluded_shape_pair_count = 0; //last step is the one valid Physics2DServerSW::CollCbkData *cbkptr = &cbk; CollisionSolver2DSW::CallbackResult cbkres = Physics2DServerSW::_shape_col_cbk; @@ -555,14 +561,25 @@ bool Space2DSW::test_body_motion(Body2DSW *p_body, const Transform2D &p_from, co cbk.valid_dir = body_shape_xform.get_axis(1).normalized(); cbk.valid_depth = p_margin; //only valid depth is the collision margin + cbk.invalid_by_dir = 0; + } else { cbk.valid_dir = Vector2(); cbk.valid_depth = 0; + cbk.invalid_by_dir = 0; } - if (CollisionSolver2DSW::solve(body_shape, body_shape_xform, Vector2(), col_obj->get_shape(shape_idx), col_obj->get_transform() * col_obj->get_shape_transform(shape_idx), Vector2(), cbkres, cbkptr, NULL, p_margin)) { + Shape2DSW *against_shape = col_obj->get_shape(shape_idx); + if (CollisionSolver2DSW::solve(body_shape, body_shape_xform, Vector2(), against_shape, col_obj->get_transform() * col_obj->get_shape_transform(shape_idx), Vector2(), cbkres, cbkptr, NULL, p_margin)) { collided = cbk.amount > 0; } + + if (!collided && cbk.invalid_by_dir > 0) { + //this shape must be excluded + if (excluded_shape_pair_count < max_excluded_shape_pairs) { + excluded_shape_pairs[excluded_shape_pair_count++] = Pair<Shape2DSW *, Shape2DSW *>(body_shape, against_shape); + } + } } } @@ -622,15 +639,31 @@ bool Space2DSW::test_body_motion(Body2DSW *p_body, const Transform2D &p_from, co const CollisionObject2DSW *col_obj = intersection_query_results[i]; int shape_idx = intersection_query_subindex_results[i]; + Shape2DSW *against_shape = col_obj->get_shape(shape_idx); + + bool excluded = false; + + for (int k = 0; k < excluded_shape_pair_count; k++) { + + if (excluded_shape_pairs[k].first == body_shape && excluded_shape_pairs[k].second == against_shape) { + excluded = true; + break; + } + } + + if (excluded) { + + continue; + } Transform2D col_obj_xform = col_obj->get_transform() * col_obj->get_shape_transform(shape_idx); //test initial overlap, does it collide if going all the way? - if (!CollisionSolver2DSW::solve(body_shape, body_shape_xform, p_motion, col_obj->get_shape(shape_idx), col_obj_xform, Vector2(), NULL, NULL, NULL, 0)) { + if (!CollisionSolver2DSW::solve(body_shape, body_shape_xform, p_motion, against_shape, col_obj_xform, Vector2(), NULL, NULL, NULL, 0)) { continue; } //test initial overlap - if (CollisionSolver2DSW::solve(body_shape, body_shape_xform, Vector2(), col_obj->get_shape(shape_idx), col_obj_xform, Vector2(), NULL, NULL, NULL, 0)) { + if (CollisionSolver2DSW::solve(body_shape, body_shape_xform, Vector2(), against_shape, col_obj_xform, Vector2(), NULL, NULL, NULL, 0)) { if (col_obj->is_shape_set_as_one_way_collision(j)) { continue; @@ -650,7 +683,7 @@ bool Space2DSW::test_body_motion(Body2DSW *p_body, const Transform2D &p_from, co real_t ofs = (low + hi) * 0.5; Vector2 sep = mnormal; //important optimization for this to work fast enough - bool collided = CollisionSolver2DSW::solve(body_shape, body_shape_xform, p_motion * ofs, col_obj->get_shape(shape_idx), col_obj_xform, Vector2(), NULL, NULL, &sep, 0); + bool collided = CollisionSolver2DSW::solve(body_shape, body_shape_xform, p_motion * ofs, against_shape, col_obj_xform, Vector2(), NULL, NULL, &sep, 0); if (collided) { @@ -669,7 +702,7 @@ bool Space2DSW::test_body_motion(Body2DSW *p_body, const Transform2D &p_from, co cbk.amount = 0; cbk.ptr = cd; cbk.valid_dir = body_shape_xform.get_axis(1).normalized(); - ; + cbk.valid_depth = 10e20; Vector2 sep = mnormal; //important optimization for this to work fast enough @@ -738,6 +771,19 @@ bool Space2DSW::test_body_motion(Body2DSW *p_body, const Transform2D &p_from, co const CollisionObject2DSW *col_obj = intersection_query_results[i]; int shape_idx = intersection_query_subindex_results[i]; + Shape2DSW *against_shape = col_obj->get_shape(shape_idx); + + bool excluded = false; + for (int k = 0; k < excluded_shape_pair_count; k++) { + + if (excluded_shape_pairs[k].first == body_shape && excluded_shape_pairs[k].second == against_shape) { + excluded = true; + break; + } + } + if (excluded) + continue; + if (col_obj->is_shape_set_as_one_way_collision(shape_idx)) { rcd.valid_dir = body_shape_xform.get_axis(1).normalized(); @@ -749,7 +795,7 @@ bool Space2DSW::test_body_motion(Body2DSW *p_body, const Transform2D &p_from, co rcd.object = col_obj; rcd.shape = shape_idx; - bool sc = CollisionSolver2DSW::solve(body_shape, body_shape_xform, Vector2(), col_obj->get_shape(shape_idx), col_obj->get_transform() * col_obj->get_shape_transform(shape_idx), Vector2(), _rest_cbk_result, &rcd, NULL, p_margin); + bool sc = CollisionSolver2DSW::solve(body_shape, body_shape_xform, Vector2(), against_shape, col_obj->get_transform() * col_obj->get_shape_transform(shape_idx), Vector2(), _rest_cbk_result, &rcd, NULL, p_margin); if (!sc) continue; } diff --git a/servers/physics_server.cpp b/servers/physics_server.cpp index 5097e0a5d2..d4e37be882 100644 --- a/servers/physics_server.cpp +++ b/servers/physics_server.cpp @@ -75,7 +75,7 @@ void PhysicsDirectBodyState::_bind_methods() { ClassDB::bind_method(D_METHOD("get_total_angular_damp"), &PhysicsDirectBodyState::get_total_angular_damp); ClassDB::bind_method(D_METHOD("get_center_of_mass"), &PhysicsDirectBodyState::get_center_of_mass); - ClassDB::bind_method(D_METHOD("get_principal_inetria_axes"), &PhysicsDirectBodyState::get_principal_inertia_axes); + ClassDB::bind_method(D_METHOD("get_principal_inertia_axes"), &PhysicsDirectBodyState::get_principal_inertia_axes); ClassDB::bind_method(D_METHOD("get_inverse_mass"), &PhysicsDirectBodyState::get_inverse_mass); ClassDB::bind_method(D_METHOD("get_inverse_inertia"), &PhysicsDirectBodyState::get_inverse_inertia); diff --git a/servers/visual/rasterizer.h b/servers/visual/rasterizer.h index 9e4acac25d..187a0b180b 100644 --- a/servers/visual/rasterizer.h +++ b/servers/visual/rasterizer.h @@ -213,6 +213,7 @@ public: virtual RID material_create() = 0; + virtual void material_set_render_priority(RID p_material, int priority) = 0; virtual void material_set_shader(RID p_shader_material, RID p_shader) = 0; virtual RID material_get_shader(RID p_shader_material) const = 0; diff --git a/servers/visual/shader_language.cpp b/servers/visual/shader_language.cpp index bc59acead5..d17cf472b3 100644 --- a/servers/visual/shader_language.cpp +++ b/servers/visual/shader_language.cpp @@ -1042,12 +1042,6 @@ bool ShaderLanguage::_validate_operator(OperatorNode *p_op, DataType *r_ret_type } } break; case OP_ASSIGN: { - - if (p_op->arguments[0]->type != Node::TYPE_MEMBER && p_op->arguments[0]->type != Node::TYPE_VARIABLE) { - valid = false; - break; - } - DataType na = p_op->arguments[0]->get_datatype(); DataType nb = p_op->arguments[1]->get_datatype(); valid = na == nb; diff --git a/servers/visual/shader_types.cpp b/servers/visual/shader_types.cpp index d8d1b1c1b1..ef0d063f83 100644 --- a/servers/visual/shader_types.cpp +++ b/servers/visual/shader_types.cpp @@ -128,12 +128,13 @@ ShaderTypes::ShaderTypes() { shader_modes[VS::SHADER_SPATIAL].modes.insert("depth_draw_never"); shader_modes[VS::SHADER_SPATIAL].modes.insert("depth_draw_alpha_prepass"); + shader_modes[VS::SHADER_SPATIAL].modes.insert("depth_test_disable"); + shader_modes[VS::SHADER_SPATIAL].modes.insert("cull_front"); shader_modes[VS::SHADER_SPATIAL].modes.insert("cull_back"); shader_modes[VS::SHADER_SPATIAL].modes.insert("cull_disabled"); shader_modes[VS::SHADER_SPATIAL].modes.insert("unshaded"); - shader_modes[VS::SHADER_SPATIAL].modes.insert("ontop"); shader_modes[VS::SHADER_SPATIAL].modes.insert("diffuse_lambert"); shader_modes[VS::SHADER_SPATIAL].modes.insert("diffuse_half_lambert"); diff --git a/servers/visual/visual_server_raster.h b/servers/visual/visual_server_raster.h index 774b692a22..3953bc5f48 100644 --- a/servers/visual/visual_server_raster.h +++ b/servers/visual/visual_server_raster.h @@ -690,6 +690,7 @@ public: BIND3(material_set_param, RID, const StringName &, const Variant &) BIND2RC(Variant, material_get_param, RID, const StringName &) + BIND2(material_set_render_priority, RID, int) BIND2(material_set_line_width, RID, float) BIND2(material_set_next_pass, RID, RID) diff --git a/servers/visual/visual_server_scene.cpp b/servers/visual/visual_server_scene.cpp index cd68c14de8..2a6cba453c 100644 --- a/servers/visual/visual_server_scene.cpp +++ b/servers/visual/visual_server_scene.cpp @@ -1434,7 +1434,7 @@ void VisualServerScene::_render_scene(const Transform p_cam_transform, const Cam } ins->depth = near_plane.distance_to(ins->transform.origin); - ins->depth_layer = CLAMP(int(ins->depth * 8 / z_far), 0, 7); + ins->depth_layer = CLAMP(int(ins->depth * 16 / z_far), 0, 15); } if (!keep) { diff --git a/servers/visual/visual_server_wrap_mt.h b/servers/visual/visual_server_wrap_mt.h index 7143178b04..f24049be92 100644 --- a/servers/visual/visual_server_wrap_mt.h +++ b/servers/visual/visual_server_wrap_mt.h @@ -128,6 +128,7 @@ public: FUNC3(material_set_param, RID, const StringName &, const Variant &) FUNC2RC(Variant, material_get_param, RID, const StringName &) + FUNC2(material_set_render_priority, RID, int) FUNC2(material_set_line_width, RID, float) FUNC2(material_set_next_pass, RID, RID) diff --git a/servers/visual_server.h b/servers/visual_server.h index acf5675aa5..45eaeeea25 100644 --- a/servers/visual_server.h +++ b/servers/visual_server.h @@ -166,6 +166,11 @@ public: /* COMMON MATERIAL API */ + enum { + MATERIAL_RENDER_PRIORITY_MIN = -128, + MATERIAL_RENDER_PRIORITY_MAX = 127, + + }; virtual RID material_create() = 0; virtual void material_set_shader(RID p_shader_material, RID p_shader) = 0; @@ -174,6 +179,8 @@ public: virtual void material_set_param(RID p_material, const StringName &p_param, const Variant &p_value) = 0; virtual Variant material_get_param(RID p_material, const StringName &p_param) const = 0; + virtual void material_set_render_priority(RID p_material, int priority) = 0; + virtual void material_set_line_width(RID p_material, float p_width) = 0; virtual void material_set_next_pass(RID p_material, RID p_next_material) = 0; diff --git a/thirdparty/README.md b/thirdparty/README.md index 7b70a8e342..76d51d7066 100644 --- a/thirdparty/README.md +++ b/thirdparty/README.md @@ -51,9 +51,23 @@ Files extracted from upstream source: ## fonts -- Upstream: ? +### Noto Sans -TODO. +- Upstream: https://github.com/googlei18n/noto-fonts +- Version: 1.06 +- License: OFL-1.1 + +Use UI font if exists, because it has tight vertial metrix and good for UI. + +### Adobe Source Code Pro Regular + +- Upstream: https://github.com/adobe-fonts/source-code-pro +- Version: 2.030 +- License: OFL-1.1 + +### DroidSans*.ttf + +- Upstream: ? ## freetype diff --git a/thirdparty/fonts/DroidSans.ttf b/thirdparty/fonts/DroidSans.ttf Binary files differdeleted file mode 100644 index 767c63ad00..0000000000 --- a/thirdparty/fonts/DroidSans.ttf +++ /dev/null diff --git a/thirdparty/fonts/DroidSansArabic.ttf b/thirdparty/fonts/DroidSansArabic.ttf Binary files differdeleted file mode 100644 index 660e2a9916..0000000000 --- a/thirdparty/fonts/DroidSansArabic.ttf +++ /dev/null diff --git a/thirdparty/fonts/DroidSansHebrew.ttf b/thirdparty/fonts/DroidSansHebrew.ttf Binary files differdeleted file mode 100644 index 8d77e3e4cf..0000000000 --- a/thirdparty/fonts/DroidSansHebrew.ttf +++ /dev/null diff --git a/thirdparty/fonts/LICENSE.Noto.txt b/thirdparty/fonts/LICENSE.Noto.txt new file mode 100644 index 0000000000..d952d62c06 --- /dev/null +++ b/thirdparty/fonts/LICENSE.Noto.txt @@ -0,0 +1,92 @@ +This Font Software is licensed under the SIL Open Font License, +Version 1.1. + +This license is copied below, and is also available with a FAQ at: +http://scripts.sil.org/OFL + +----------------------------------------------------------- +SIL OPEN FONT LICENSE Version 1.1 - 26 February 2007 +----------------------------------------------------------- + +PREAMBLE +The goals of the Open Font License (OFL) are to stimulate worldwide +development of collaborative font projects, to support the font +creation efforts of academic and linguistic communities, and to +provide a free and open framework in which fonts may be shared and +improved in partnership with others. + +The OFL allows the licensed fonts to be used, studied, modified and +redistributed freely as long as they are not sold by themselves. The +fonts, including any derivative works, can be bundled, embedded, +redistributed and/or sold with any software provided that any reserved +names are not used by derivative works. The fonts and derivatives, +however, cannot be released under any other type of license. The +requirement for fonts to remain under this license does not apply to +any document created using the fonts or their derivatives. + +DEFINITIONS +"Font Software" refers to the set of files released by the Copyright +Holder(s) under this license and clearly marked as such. This may +include source files, build scripts and documentation. + +"Reserved Font Name" refers to any names specified as such after the +copyright statement(s). + +"Original Version" refers to the collection of Font Software +components as distributed by the Copyright Holder(s). + +"Modified Version" refers to any derivative made by adding to, +deleting, or substituting -- in part or in whole -- any of the +components of the Original Version, by changing formats or by porting +the Font Software to a new environment. + +"Author" refers to any designer, engineer, programmer, technical +writer or other person who contributed to the Font Software. + +PERMISSION & CONDITIONS +Permission is hereby granted, free of charge, to any person obtaining +a copy of the Font Software, to use, study, copy, merge, embed, +modify, redistribute, and sell modified and unmodified copies of the +Font Software, subject to the following conditions: + +1) Neither the Font Software nor any of its individual components, in +Original or Modified Versions, may be sold by itself. + +2) Original or Modified Versions of the Font Software may be bundled, +redistributed and/or sold with any software, provided that each copy +contains the above copyright notice and this license. These 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. + +3) No Modified Version of the Font Software may use the Reserved Font +Name(s) unless explicit written permission is granted by the +corresponding Copyright Holder. This restriction only applies to the +primary font name as presented to the users. + +4) The name(s) of the Copyright Holder(s) or 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 the +Copyright Holder(s) and the Author(s) or with their explicit written +permission. + +5) The Font Software, modified or unmodified, in part or in whole, +must be distributed entirely under this license, and must not be +distributed under any other license. The requirement for fonts to +remain under this license does not apply to any document created using +the Font Software. + +TERMINATION +This license becomes null and void if any of the above conditions are +not met. + +DISCLAIMER +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. diff --git a/thirdparty/fonts/NotoNaskhArabicUI_Regular.ttf b/thirdparty/fonts/NotoNaskhArabicUI_Regular.ttf Binary files differnew file mode 100644 index 0000000000..67713c697e --- /dev/null +++ b/thirdparty/fonts/NotoNaskhArabicUI_Regular.ttf diff --git a/thirdparty/fonts/NotoSansHebrew_Regular.ttf b/thirdparty/fonts/NotoSansHebrew_Regular.ttf Binary files differnew file mode 100644 index 0000000000..5027f5c228 --- /dev/null +++ b/thirdparty/fonts/NotoSansHebrew_Regular.ttf diff --git a/thirdparty/fonts/DroidSansThai.ttf b/thirdparty/fonts/NotoSansThaiUI_Regular.ttf Binary files differindex f849baeff9..9c50a1b8f5 100644 --- a/thirdparty/fonts/DroidSansThai.ttf +++ b/thirdparty/fonts/NotoSansThaiUI_Regular.ttf diff --git a/thirdparty/fonts/NotoSansUI_Regular.ttf b/thirdparty/fonts/NotoSansUI_Regular.ttf Binary files differnew file mode 100644 index 0000000000..65b29fcff1 --- /dev/null +++ b/thirdparty/fonts/NotoSansUI_Regular.ttf diff --git a/thirdparty/fonts/source_code_pro.otf b/thirdparty/fonts/source_code_pro.otf Binary files differindex 4e3b9d0bcd..1bae0027ff 100644 --- a/thirdparty/fonts/source_code_pro.otf +++ b/thirdparty/fonts/source_code_pro.otf |