summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--core/class_db.cpp8
-rw-r--r--core/hash_map.h90
-rw-r--r--core/helper/math_fieldwise.cpp2
-rw-r--r--core/helper/math_fieldwise.h2
-rw-r--r--core/math/a_star.h2
-rw-r--r--core/ordered_hash_map.h315
-rw-r--r--core/pair.h10
-rw-r--r--core/project_settings.cpp2
-rw-r--r--core/project_settings.h2
-rw-r--r--core/script_language.cpp1
-rw-r--r--drivers/alsa/audio_driver_alsa.cpp19
-rw-r--r--drivers/alsa/audio_driver_alsa.h1
-rw-r--r--drivers/convex_decomp/b2d_decompose.cpp2
-rw-r--r--drivers/gles3/rasterizer_scene_gles3.cpp16
-rw-r--r--drivers/gles3/rasterizer_scene_gles3.h42
-rw-r--r--drivers/gles3/rasterizer_storage_gles3.cpp15
-rw-r--r--drivers/gles3/rasterizer_storage_gles3.h6
-rw-r--r--drivers/pulseaudio/audio_driver_pulseaudio.cpp44
-rw-r--r--drivers/pulseaudio/audio_driver_pulseaudio.h1
-rw-r--r--drivers/rtaudio/audio_driver_rtaudio.cpp13
-rw-r--r--drivers/wasapi/audio_driver_wasapi.cpp35
-rw-r--r--drivers/wasapi/audio_driver_wasapi.h3
-rw-r--r--editor/code_editor.cpp1
-rw-r--r--editor/editor_data.cpp2
-rw-r--r--editor/editor_data.h2
-rw-r--r--editor/editor_export.cpp2
-rw-r--r--editor/editor_export.h2
-rw-r--r--editor/editor_node.cpp2
-rw-r--r--editor/editor_settings.cpp1
-rw-r--r--editor/export_template_manager.h2
-rw-r--r--editor/import_dock.cpp12
-rw-r--r--editor/plugins/gradient_editor_plugin.cpp2
-rw-r--r--editor/plugins/gradient_editor_plugin.h2
-rw-r--r--editor/plugins/shader_editor_plugin.cpp1
-rw-r--r--editor/plugins/spatial_editor_plugin.cpp6
-rw-r--r--editor/project_settings_editor.cpp2
-rw-r--r--editor/project_settings_editor.h2
-rw-r--r--editor/script_create_dialog.cpp9
-rw-r--r--editor/spatial_editor_gizmos.cpp12
-rw-r--r--main/tests/test_main.cpp6
-rw-r--r--main/tests/test_ordered_hash_map.cpp171
-rw-r--r--main/tests/test_ordered_hash_map.h38
-rw-r--r--modules/etc/SCsub2
-rw-r--r--modules/gridmap/grid_map_editor_plugin.cpp4
-rw-r--r--modules/hdr/image_loader_hdr.cpp2
-rw-r--r--modules/hdr/image_loader_hdr.h2
-rw-r--r--modules/nativescript/godot_nativescript.h2
-rw-r--r--modules/regex/SCsub7
-rw-r--r--modules/stb_vorbis/audio_stream_ogg_vorbis.cpp2
-rw-r--r--modules/tga/image_loader_tga.cpp2
-rw-r--r--modules/tga/image_loader_tga.h2
-rw-r--r--modules/tinyexr/image_loader_tinyexr.cpp2
-rw-r--r--modules/tinyexr/image_loader_tinyexr.h2
-rw-r--r--modules/visual_script/visual_script_editor.cpp2
-rw-r--r--modules/visual_script/visual_script_nodes.h2
-rw-r--r--modules/webm/video_stream_webm.cpp2
-rw-r--r--modules/webm/video_stream_webm.h2
-rw-r--r--platform/android/audio_driver_opensl.cpp2
-rw-r--r--platform/iphone/icloud.h2
-rw-r--r--platform/iphone/icloud.mm2
-rw-r--r--platform/osx/audio_driver_osx.cpp26
-rw-r--r--platform/osx/audio_driver_osx.h5
-rw-r--r--platform/osx/joypad_osx.h2
-rw-r--r--platform/osx/power_osx.cpp2
-rw-r--r--platform/windows/joypad.cpp2
-rw-r--r--platform/windows/joypad.h2
-rw-r--r--scene/2d/audio_stream_player_2d.cpp4
-rw-r--r--scene/3d/audio_stream_player_3d.cpp4
-rw-r--r--scene/3d/collision_shape.cpp2
-rw-r--r--scene/3d/collision_shape.h2
-rw-r--r--scene/3d/immediate_geometry.h2
-rw-r--r--scene/3d/remote_transform.cpp3
-rw-r--r--scene/animation/animation_tree_player.h2
-rw-r--r--scene/audio/audio_player.cpp4
-rw-r--r--scene/gui/check_box.h2
-rw-r--r--scene/main/scene_tree.cpp2
-rw-r--r--scene/main/scene_tree.h2
-rw-r--r--scene/resources/default_theme/default_theme.h2
-rw-r--r--scene/resources/material.cpp35
-rw-r--r--scene/resources/material.h12
-rw-r--r--servers/audio/audio_driver_dummy.cpp17
-rw-r--r--servers/audio/audio_driver_dummy.h3
-rw-r--r--servers/audio_server.cpp23
-rw-r--r--servers/audio_server.h3
-rw-r--r--servers/visual/rasterizer.h1
-rw-r--r--servers/visual/shader_language.cpp2
-rw-r--r--servers/visual/shader_types.cpp3
-rw-r--r--servers/visual/visual_server_raster.h1
-rw-r--r--servers/visual/visual_server_scene.cpp2
-rw-r--r--servers/visual/visual_server_wrap_mt.h1
-rw-r--r--servers/visual_server.h7
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(&parameters, NULL, RTAUDIO_SINT32, mix_rate, &buffer_size, &callback, this, &options);
+ dac->openStream(&parameters, 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;