diff options
91 files changed, 925 insertions, 206 deletions
diff --git a/core/class_db.cpp b/core/class_db.cpp index 1cb287a143..872e466e72 100644 --- a/core/class_db.cpp +++ b/core/class_db.cpp @@ -535,7 +535,13 @@ void ClassDB::get_method_list(StringName p_class, List<MethodInfo> *p_methods, b minfo.return_val = method->get_return_info(); minfo.flags = method->get_hint_flags(); - minfo.default_arguments = method->get_default_arguments(); + + int defval_count = method->get_default_argument_count(); + minfo.default_arguments.resize(defval_count); + + for (int i = 0; i < defval_count; i++) { + minfo.default_arguments[i] = method->get_default_argument(defval_count - i - 1); + } p_methods->push_back(minfo); } 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/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/drivers/alsa/audio_driver_alsa.cpp b/drivers/alsa/audio_driver_alsa.cpp index 40c66b0bc5..216100bac6 100644 --- a/drivers/alsa/audio_driver_alsa.cpp +++ b/drivers/alsa/audio_driver_alsa.cpp @@ -31,6 +31,7 @@ #ifdef ALSA_ENABLED +#include "os/os.h" #include "project_settings.h" #include <errno.h> @@ -44,7 +45,7 @@ Error AudioDriverALSA::init() { samples_in = NULL; samples_out = NULL; - mix_rate = GLOBAL_DEF("audio/mix_rate", 44100); + mix_rate = GLOBAL_DEF("audio/mix_rate", DEFAULT_MIX_RATE); speaker_mode = SPEAKER_MODE_STEREO; channels = 2; @@ -86,19 +87,25 @@ Error AudioDriverALSA::init() { status = snd_pcm_hw_params_set_rate_near(pcm_handle, hwparams, &mix_rate, NULL); CHECK_FAIL(status < 0); - int latency = GLOBAL_DEF("audio/output_latency", 25); - buffer_size = closest_power_of_2(latency * mix_rate / 1000); + // In ALSA the period size seems to be the one that will determine the actual latency + // Ref: https://www.alsa-project.org/main/index.php/FramesPeriods + unsigned int periods = 2; + int latency = GLOBAL_DEF("audio/output_latency", DEFAULT_OUTPUT_LATENCY); + buffer_frames = closest_power_of_2(latency * mix_rate / 1000); + buffer_size = buffer_frames * periods; + period_size = buffer_frames; // set buffer size from project settings status = snd_pcm_hw_params_set_buffer_size_near(pcm_handle, hwparams, &buffer_size); CHECK_FAIL(status < 0); - // make period size 1/8 - period_size = buffer_size >> 3; status = snd_pcm_hw_params_set_period_size_near(pcm_handle, hwparams, &period_size, NULL); CHECK_FAIL(status < 0); - unsigned int periods = 2; + if (OS::get_singleton()->is_stdout_verbose()) { + print_line("audio buffer frames: " + itos(period_size) + " calculated latency: " + itos(period_size * 1000 / mix_rate) + "ms"); + } + status = snd_pcm_hw_params_set_periods_near(pcm_handle, hwparams, &periods, NULL); CHECK_FAIL(status < 0); diff --git a/drivers/alsa/audio_driver_alsa.h b/drivers/alsa/audio_driver_alsa.h index 83601be41b..c76ec0da61 100644 --- a/drivers/alsa/audio_driver_alsa.h +++ b/drivers/alsa/audio_driver_alsa.h @@ -51,6 +51,7 @@ class AudioDriverALSA : public AudioDriver { unsigned int mix_rate; SpeakerMode speaker_mode; + snd_pcm_uframes_t buffer_frames; snd_pcm_uframes_t buffer_size; snd_pcm_uframes_t period_size; int channels; 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 047b2375f8..3f60dcd175 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 c4dab1290b..5503dba5c4 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 a66a3d020b..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: { 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/pulseaudio/audio_driver_pulseaudio.cpp b/drivers/pulseaudio/audio_driver_pulseaudio.cpp index 356b1ad958..1798c84d85 100644 --- a/drivers/pulseaudio/audio_driver_pulseaudio.cpp +++ b/drivers/pulseaudio/audio_driver_pulseaudio.cpp @@ -33,6 +33,7 @@ #include <pulse/error.h> +#include "os/os.h" #include "project_settings.h" Error AudioDriverPulseAudio::init() { @@ -44,7 +45,7 @@ Error AudioDriverPulseAudio::init() { samples_in = NULL; samples_out = NULL; - mix_rate = GLOBAL_DEF("audio/mix_rate", 44100); + mix_rate = GLOBAL_DEF("audio/mix_rate", DEFAULT_MIX_RATE); speaker_mode = SPEAKER_MODE_STEREO; channels = 2; @@ -53,12 +54,17 @@ Error AudioDriverPulseAudio::init() { spec.channels = channels; spec.rate = mix_rate; - int latency = GLOBAL_DEF("audio/output_latency", 25); - buffer_size = closest_power_of_2(latency * mix_rate / 1000); + int latency = GLOBAL_DEF("audio/output_latency", DEFAULT_OUTPUT_LATENCY); + buffer_frames = closest_power_of_2(latency * mix_rate / 1000); + buffer_size = buffer_frames * channels; + + if (OS::get_singleton()->is_stdout_verbose()) { + print_line("audio buffer frames: " + itos(buffer_frames) + " calculated latency: " + itos(buffer_frames * 1000 / mix_rate) + "ms"); + } pa_buffer_attr attr; - // set to appropriate buffer size from global settings - attr.tlength = buffer_size; + // set to appropriate buffer length (in bytes) from global settings + attr.tlength = buffer_size * sizeof(int16_t); // set them to be automatically chosen attr.prebuf = (uint32_t)-1; attr.maxlength = (uint32_t)-1; @@ -80,8 +86,8 @@ Error AudioDriverPulseAudio::init() { ERR_FAIL_COND_V(pulse == NULL, ERR_CANT_OPEN); } - samples_in = memnew_arr(int32_t, buffer_size * channels); - samples_out = memnew_arr(int16_t, buffer_size * channels); + samples_in = memnew_arr(int32_t, buffer_size); + samples_out = memnew_arr(int16_t, buffer_size); mutex = Mutex::create(); thread = Thread::create(AudioDriverPulseAudio::thread_func, this); @@ -106,18 +112,18 @@ void AudioDriverPulseAudio::thread_func(void *p_udata) { while (!ad->exit_thread) { if (!ad->active) { - for (unsigned int i = 0; i < ad->buffer_size * ad->channels; i++) { + for (unsigned int i = 0; i < ad->buffer_size; i++) { ad->samples_out[i] = 0; } } else { ad->lock(); - ad->audio_server_process(ad->buffer_size, ad->samples_in); + ad->audio_server_process(ad->buffer_frames, ad->samples_in); ad->unlock(); - for (unsigned int i = 0; i < ad->buffer_size * ad->channels; i++) { + for (unsigned int i = 0; i < ad->buffer_size; i++) { ad->samples_out[i] = ad->samples_in[i] >> 16; } } @@ -125,7 +131,7 @@ void AudioDriverPulseAudio::thread_func(void *p_udata) { // pa_simple_write always consumes the entire buffer int error_code; - int byte_size = ad->buffer_size * sizeof(int16_t) * ad->channels; + int byte_size = ad->buffer_size * sizeof(int16_t); if (pa_simple_write(ad->pulse, ad->samples_out, byte_size, &error_code) < 0) { // can't recover here fprintf(stderr, "PulseAudio failed and can't recover: %s\n", pa_strerror(error_code)); @@ -175,13 +181,20 @@ void AudioDriverPulseAudio::finish() { exit_thread = true; Thread::wait_to_finish(thread); - if (pulse) + if (pulse) { pa_simple_free(pulse); + pulse = NULL; + } if (samples_in) { memdelete_arr(samples_in); + samples_in = NULL; + } + + if (samples_out) { memdelete_arr(samples_out); - }; + samples_out = NULL; + } memdelete(thread); if (mutex) { @@ -194,10 +207,15 @@ void AudioDriverPulseAudio::finish() { AudioDriverPulseAudio::AudioDriverPulseAudio() { + samples_in = NULL; + samples_out = NULL; mutex = NULL; thread = NULL; pulse = NULL; latency = 0; + buffer_frames = 0; + buffer_size = 0; + channels = 0; } AudioDriverPulseAudio::~AudioDriverPulseAudio() { diff --git a/drivers/pulseaudio/audio_driver_pulseaudio.h b/drivers/pulseaudio/audio_driver_pulseaudio.h index 2f56726617..9ae0b7e50c 100644 --- a/drivers/pulseaudio/audio_driver_pulseaudio.h +++ b/drivers/pulseaudio/audio_driver_pulseaudio.h @@ -51,6 +51,7 @@ class AudioDriverPulseAudio : public AudioDriver { unsigned int mix_rate; SpeakerMode speaker_mode; + unsigned int buffer_frames; unsigned int buffer_size; int channels; diff --git a/drivers/rtaudio/audio_driver_rtaudio.cpp b/drivers/rtaudio/audio_driver_rtaudio.cpp index 7de3ff192e..ae5fdd28b6 100644 --- a/drivers/rtaudio/audio_driver_rtaudio.cpp +++ b/drivers/rtaudio/audio_driver_rtaudio.cpp @@ -107,14 +107,13 @@ Error AudioDriverRtAudio::init() { options.numberOfBuffers = 4; parameters.firstChannel = 0; - mix_rate = GLOBAL_DEF("audio/mix_rate", 44100); + mix_rate = GLOBAL_DEF("audio/mix_rate", DEFAULT_MIX_RATE); - int latency = GLOBAL_DEF("audio/output_latency", 25); - // calculate desired buffer_size - unsigned int buffer_size = closest_power_of_2(latency * mix_rate / 1000); + int latency = GLOBAL_DEF("audio/output_latency", DEFAULT_OUTPUT_LATENCY); + unsigned int buffer_frames = closest_power_of_2(latency * mix_rate / 1000); if (OS::get_singleton()->is_stdout_verbose()) { - print_line("audio buffer size: " + itos(buffer_size)); + print_line("audio buffer frames: " + itos(buffer_frames) + " calculated latency: " + itos(buffer_frames * 1000 / mix_rate) + "ms"); } short int tries = 2; @@ -127,7 +126,7 @@ Error AudioDriverRtAudio::init() { }; try { - dac->openStream(¶meters, NULL, RTAUDIO_SINT32, mix_rate, &buffer_size, &callback, this, &options); + dac->openStream(¶meters, NULL, RTAUDIO_SINT32, mix_rate, &buffer_frames, &callback, this, &options); active = true; break; @@ -199,7 +198,7 @@ AudioDriverRtAudio::AudioDriverRtAudio() { active = false; mutex = NULL; dac = NULL; - mix_rate = 44100; + mix_rate = DEFAULT_MIX_RATE; speaker_mode = SPEAKER_MODE_STEREO; } diff --git a/drivers/wasapi/audio_driver_wasapi.cpp b/drivers/wasapi/audio_driver_wasapi.cpp index 6e01b5f524..29d1e5deed 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 */ @@ -65,6 +65,18 @@ Error AudioDriverWASAPI::init_device() { format_tag = pwfex->wFormatTag; bits_per_sample = pwfex->wBitsPerSample; + switch (channels) { + case 2: // Stereo + case 6: // Surround 5.1 + case 8: // Surround 7.1 + break; + + default: + ERR_PRINT("WASAPI: Unsupported number of channels"); + ERR_FAIL_V(ERR_CANT_OPEN); + break; + } + if (format_tag == WAVE_FORMAT_EXTENSIBLE) { WAVEFORMATEXTENSIBLE *wfex = (WAVEFORMATEXTENSIBLE *)pwfex; @@ -83,13 +95,6 @@ Error AudioDriverWASAPI::init_device() { } } - int latency = GLOBAL_DEF("audio/output_latency", 25); - buffer_size = closest_power_of_2(latency * mix_rate / 1000); - - if (OS::get_singleton()->is_stdout_verbose()) { - print_line("audio buffer size: " + itos(buffer_size)); - } - hr = audio_client->Initialize(AUDCLNT_SHAREMODE_SHARED, AUDCLNT_STREAMFLAGS_EVENTCALLBACK, 0, 0, pwfex, NULL); ERR_FAIL_COND_V(hr != S_OK, ERR_CANT_OPEN); @@ -102,11 +107,20 @@ Error AudioDriverWASAPI::init_device() { hr = audio_client->GetService(IID_IAudioRenderClient, (void **)&render_client); ERR_FAIL_COND_V(hr != S_OK, ERR_CANT_OPEN); + UINT32 max_frames; hr = audio_client->GetBufferSize(&max_frames); ERR_FAIL_COND_V(hr != S_OK, ERR_CANT_OPEN); + // Due to WASAPI Shared Mode we have no control of the buffer size + buffer_frames = max_frames; + + // Sample rate is independent of channels (ref: https://stackoverflow.com/questions/11048825/audio-sample-frequency-rely-on-channels) + buffer_size = buffer_frames * channels; samples_in.resize(buffer_size); - buffer_frames = buffer_size / channels; + + if (OS::get_singleton()->is_stdout_verbose()) { + print_line("audio buffer frames: " + itos(buffer_frames) + " calculated latency: " + itos(buffer_frames * 1000 / mix_rate) + "ms"); + } return OK; } @@ -200,7 +214,7 @@ void AudioDriverWASAPI::thread_func(void *p_udata) { HRESULT hr = ad->audio_client->GetCurrentPadding(&cur_frames); if (hr == S_OK) { // Check how much frames are available on the WASAPI buffer - UINT32 avail_frames = ad->max_frames - cur_frames; + UINT32 avail_frames = ad->buffer_frames - cur_frames; UINT32 write_frames = avail_frames > left_frames ? left_frames : avail_frames; BYTE *buffer = NULL; @@ -332,7 +346,6 @@ AudioDriverWASAPI::AudioDriverWASAPI() { mutex = NULL; thread = NULL; - max_frames = 0; format_tag = 0; bits_per_sample = 0; diff --git a/drivers/wasapi/audio_driver_wasapi.h b/drivers/wasapi/audio_driver_wasapi.h index b91751f87e..fab8ab3250 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 */ @@ -48,7 +48,6 @@ class AudioDriverWASAPI : public AudioDriver { Mutex *mutex; Thread *thread; - UINT32 max_frames; WORD format_tag; WORD bits_per_sample; 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_data.cpp b/editor/editor_data.cpp index cb74a7b852..2cb5340b8b 100644 --- a/editor/editor_data.cpp +++ b/editor/editor_data.cpp @@ -141,7 +141,7 @@ ObjectID EditorHistory::get_history_obj(int p_obj) const { return history[p_obj].path[history[p_obj].level].object; } -bool EditorHistory::is_at_begining() const { +bool EditorHistory::is_at_beginning() const { return current <= 0; } bool EditorHistory::is_at_end() const { diff --git a/editor/editor_data.h b/editor/editor_data.h index cbba4d60ad..33a4091a65 100644 --- a/editor/editor_data.h +++ b/editor/editor_data.h @@ -74,7 +74,7 @@ class EditorHistory { void _add_object(ObjectID p_object, const String &p_property, int p_level_change); public: - bool is_at_begining() const; + bool is_at_beginning() const; bool is_at_end() const; void add_object(ObjectID p_object); 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_node.cpp b/editor/editor_node.cpp index 8575cd164f..e39895e4d8 100644 --- a/editor/editor_node.cpp +++ b/editor/editor_node.cpp @@ -1373,7 +1373,7 @@ void EditorNode::_edit_current() { uint32_t current = editor_history.get_current(); Object *current_obj = current > 0 ? ObjectDB::get_instance(current) : NULL; - property_back->set_disabled(editor_history.is_at_begining()); + property_back->set_disabled(editor_history.is_at_beginning()); property_forward->set_disabled(editor_history.is_at_end()); this->current = current_obj; 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/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_dock.cpp b/editor/import_dock.cpp index a60f5d7294..112e3abcb5 100644 --- a/editor/import_dock.cpp +++ b/editor/import_dock.cpp @@ -265,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); 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/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 4e6c9fa23f..d9fc2f32f7 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_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/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/etc/SCsub b/modules/etc/SCsub index f0c1ee64b9..9c3e703f11 100644 --- a/modules/etc/SCsub +++ b/modules/etc/SCsub @@ -34,7 +34,7 @@ env_etc.Append(CPPPATH=[thirdparty_dir]) env_etc.add_source_files(env.modules_sources, "*.cpp") # upstream uses c++11 -env_etc.Append(CXXFLAGS="-std=gnu++11") +env_etc.Append(CCFLAGS="-std=gnu++11") # -ffast-math seems to be incompatible with ec2comp on recent versions of # GCC and Clang if '-ffast-math' in env_etc['CCFLAGS']: 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 d263c61464..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 */ 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/stb_vorbis/audio_stream_ogg_vorbis.cpp b/modules/stb_vorbis/audio_stream_ogg_vorbis.cpp index 49d959203c..ed184fc486 100644 --- a/modules/stb_vorbis/audio_stream_ogg_vorbis.cpp +++ b/modules/stb_vorbis/audio_stream_ogg_vorbis.cpp @@ -112,8 +112,8 @@ float AudioStreamPlaybackOGGVorbis::get_length() const { AudioStreamPlaybackOGGVorbis::~AudioStreamPlaybackOGGVorbis() { if (ogg_alloc.alloc_buffer) { - AudioServer::get_singleton()->audio_data_free(ogg_alloc.alloc_buffer); stb_vorbis_close(ogg_stream); + AudioServer::get_singleton()->audio_data_free(ogg_alloc.alloc_buffer); } } diff --git a/modules/tga/image_loader_tga.cpp b/modules/tga/image_loader_tga.cpp index 8b1d422ce2..7c7cf5bcbe 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/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/audio_driver_osx.cpp b/platform/osx/audio_driver_osx.cpp index 8c5a734f76..78c52af201 100644 --- a/platform/osx/audio_driver_osx.cpp +++ b/platform/osx/audio_driver_osx.cpp @@ -77,7 +77,7 @@ Error AudioDriverOSX::initDevice() { break; }*/ - mix_rate = GLOBAL_DEF("audio/mix_rate", 44100); + mix_rate = GLOBAL_DEF("audio/mix_rate", DEFAULT_MIX_RATE); zeromem(&strdesc, sizeof(strdesc)); strdesc.mFormatID = kAudioFormatLinearPCM; @@ -92,15 +92,19 @@ Error AudioDriverOSX::initDevice() { result = AudioUnitSetProperty(audio_unit, kAudioUnitProperty_StreamFormat, kAudioUnitScope_Input, kOutputBus, &strdesc, sizeof(strdesc)); ERR_FAIL_COND_V(result != noErr, FAILED); - int latency = GLOBAL_DEF("audio/output_latency", 25); - unsigned int buffer_size = closest_power_of_2(latency * mix_rate / 1000); + int latency = GLOBAL_DEF("audio/output_latency", DEFAULT_OUTPUT_LATENCY); + // Sample rate is independent of channels (ref: https://stackoverflow.com/questions/11048825/audio-sample-frequency-rely-on-channels) + buffer_frames = closest_power_of_2(latency * mix_rate / 1000); - if (OS::get_singleton()->is_stdout_verbose()) { - print_line("audio buffer size: " + itos(buffer_size) + " calculated latency: " + itos(buffer_size * 1000 / mix_rate)); - } + result = AudioUnitSetProperty(audio_unit, kAudioDevicePropertyBufferFrameSize, kAudioUnitScope_Global, kOutputBus, &buffer_frames, sizeof(UInt32)); + ERR_FAIL_COND_V(result != noErr, FAILED); + buffer_size = buffer_frames * channels; samples_in.resize(buffer_size); - buffer_frames = buffer_size / channels; + + if (OS::get_singleton()->is_stdout_verbose()) { + print_line("audio buffer frames: " + itos(buffer_frames) + " calculated latency: " + itos(buffer_frames * 1000 / mix_rate) + "ms"); + } AURenderCallbackStruct callback; zeromem(&callback, sizeof(AURenderCallbackStruct)); @@ -234,7 +238,7 @@ void AudioDriverOSX::start() { }; int AudioDriverOSX::get_mix_rate() const { - return 44100; + return mix_rate; }; AudioDriver::SpeakerMode AudioDriverOSX::get_speaker_mode() const { @@ -282,8 +286,12 @@ AudioDriverOSX::AudioDriverOSX() { active = false; mutex = NULL; - mix_rate = 44100; + mix_rate = 0; channels = 2; + + buffer_size = 0; + buffer_frames = 0; + samples_in.clear(); }; diff --git a/platform/osx/audio_driver_osx.h b/platform/osx/audio_driver_osx.h index ac178b89f3..a7e68c8141 100644 --- a/platform/osx/audio_driver_osx.h +++ b/platform/osx/audio_driver_osx.h @@ -45,8 +45,9 @@ class AudioDriverOSX : public AudioDriver { Mutex *mutex; int mix_rate; - int channels; - int buffer_frames; + unsigned int channels; + unsigned int buffer_frames; + unsigned int buffer_size; Vector<int32_t> samples_in; 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/2d/audio_stream_player_2d.cpp b/scene/2d/audio_stream_player_2d.cpp index eb186a8e1f..39d3f2d6bf 100644 --- a/scene/2d/audio_stream_player_2d.cpp +++ b/scene/2d/audio_stream_player_2d.cpp @@ -246,12 +246,14 @@ void AudioStreamPlayer2D::set_stream(Ref<AudioStream> p_stream) { stream = p_stream; stream_playback = p_stream->instance_playback(); + AudioServer::get_singleton()->unlock(); + if (stream_playback.is_null()) { stream.unref(); ERR_FAIL_COND(stream_playback.is_null()); } - AudioServer::get_singleton()->unlock(); + } Ref<AudioStream> AudioStreamPlayer2D::get_stream() const { diff --git a/scene/3d/audio_stream_player_3d.cpp b/scene/3d/audio_stream_player_3d.cpp index 6efdf25f0d..1ad36102ba 100644 --- a/scene/3d/audio_stream_player_3d.cpp +++ b/scene/3d/audio_stream_player_3d.cpp @@ -555,12 +555,12 @@ void AudioStreamPlayer3D::set_stream(Ref<AudioStream> p_stream) { stream = p_stream; stream_playback = p_stream->instance_playback(); + AudioServer::get_singleton()->unlock(); + if (stream_playback.is_null()) { stream.unref(); ERR_FAIL_COND(stream_playback.is_null()); } - - AudioServer::get_singleton()->unlock(); } Ref<AudioStream> AudioStreamPlayer3D::get_stream() const { 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/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.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/audio/audio_player.cpp b/scene/audio/audio_player.cpp index 5d71f702df..8bd924e7ce 100644 --- a/scene/audio/audio_player.cpp +++ b/scene/audio/audio_player.cpp @@ -139,12 +139,12 @@ void AudioStreamPlayer::set_stream(Ref<AudioStream> p_stream) { stream = p_stream; stream_playback = p_stream->instance_playback(); + AudioServer::get_singleton()->unlock(); + if (stream_playback.is_null()) { stream.unref(); ERR_FAIL_COND(stream_playback.is_null()); } - - AudioServer::get_singleton()->unlock(); } Ref<AudioStream> AudioStreamPlayer::get_stream() 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/main/scene_tree.cpp b/scene/main/scene_tree.cpp index 766b7923d3..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 */ 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/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 315351d039..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() { @@ -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"; @@ -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 6a0eead708..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, @@ -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/servers/audio/audio_driver_dummy.cpp b/servers/audio/audio_driver_dummy.cpp index 992fece85f..1ae0e7b96b 100644 --- a/servers/audio/audio_driver_dummy.cpp +++ b/servers/audio/audio_driver_dummy.cpp @@ -37,17 +37,16 @@ Error AudioDriverDummy::init() { active = false; thread_exited = false; exit_thread = false; - pcm_open = false; samples_in = NULL; - mix_rate = 44100; + mix_rate = DEFAULT_MIX_RATE; speaker_mode = SPEAKER_MODE_STEREO; channels = 2; - int latency = GLOBAL_DEF("audio/output_latency", 25); - buffer_size = next_power_of_2(latency * mix_rate / 1000); + int latency = GLOBAL_DEF("audio/output_latency", DEFAULT_OUTPUT_LATENCY); + buffer_frames = closest_power_of_2(latency * mix_rate / 1000); - samples_in = memnew_arr(int32_t, buffer_size * channels); + samples_in = memnew_arr(int32_t, buffer_frames * channels); mutex = Mutex::create(); thread = Thread::create(AudioDriverDummy::thread_func, this); @@ -59,17 +58,15 @@ void AudioDriverDummy::thread_func(void *p_udata) { AudioDriverDummy *ad = (AudioDriverDummy *)p_udata; - uint64_t usdelay = (ad->buffer_size / float(ad->mix_rate)) * 1000000; + uint64_t usdelay = (ad->buffer_frames / float(ad->mix_rate)) * 1000000; while (!ad->exit_thread) { - if (!ad->active) { - - } else { + if (ad->active) { ad->lock(); - ad->audio_server_process(ad->buffer_size, ad->samples_in); + ad->audio_server_process(ad->buffer_frames, ad->samples_in); ad->unlock(); }; diff --git a/servers/audio/audio_driver_dummy.h b/servers/audio/audio_driver_dummy.h index b3fea59389..90af1961b7 100644 --- a/servers/audio/audio_driver_dummy.h +++ b/servers/audio/audio_driver_dummy.h @@ -43,8 +43,8 @@ class AudioDriverDummy : public AudioDriver { int32_t *samples_in; static void thread_func(void *p_udata); - int buffer_size; + unsigned int buffer_frames; unsigned int mix_rate; SpeakerMode speaker_mode; @@ -53,7 +53,6 @@ class AudioDriverDummy : public AudioDriver { bool active; bool thread_exited; mutable bool exit_thread; - bool pcm_open; public: const char *get_name() const { diff --git a/servers/audio_server.cpp b/servers/audio_server.cpp index c0343399c3..3139c6bb7a 100644 --- a/servers/audio_server.cpp +++ b/servers/audio_server.cpp @@ -155,6 +155,29 @@ void AudioServer::_driver_process(int p_frames, int32_t *p_buffer) { todo -= to_copy; to_mix -= to_copy; } + +#ifdef DEBUG_ENABLED + if (OS::get_singleton() && OS::get_singleton()->is_stdout_verbose()) { + static uint64_t first_ticks = 0; + static uint64_t last_ticks = 0; + static uint64_t ticks = 0; + static int count = 0; + static int total = 0; + + ticks = OS::get_singleton()->get_ticks_msec(); + if ((ticks - first_ticks) > 10 * 1000) { + print_line("Audio Driver " + String(AudioDriver::get_singleton()->get_name()) + " average latency: " + itos(total / count) + "ms (frame=" + itos(p_frames) + ")"); + first_ticks = ticks; + total = 0; + count = 0; + } + + total += ticks - last_ticks; + count++; + + last_ticks = ticks; + } +#endif } void AudioServer::_mix_step() { diff --git a/servers/audio_server.h b/servers/audio_server.h index 05e92ceaf0..13a74856c8 100644 --- a/servers/audio_server.h +++ b/servers/audio_server.h @@ -54,6 +54,9 @@ public: SPEAKER_SURROUND_71, }; + static const int DEFAULT_MIX_RATE = 44100; + static const int DEFAULT_OUTPUT_LATENCY = 15; + static AudioDriver *get_singleton(); void set_singleton(); 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 d17cf472b3..09f8a3775e 100644 --- a/servers/visual/shader_language.cpp +++ b/servers/visual/shader_language.cpp @@ -3349,7 +3349,7 @@ Error ShaderLanguage::_parse_shader(const Map<StringName, FunctionInfo> &p_funct Token tk = _get_token(); if (tk.type != TK_SHADER_TYPE) { - _set_error("Expected 'shader_type' at the begining of shader."); + _set_error("Expected 'shader_type' at the beginning of shader."); return ERR_PARSE_ERROR; } 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 1d9e6bef24..61ebc6e6de 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; |