summaryrefslogtreecommitdiffstats
path: root/core
diff options
context:
space:
mode:
Diffstat (limited to 'core')
-rw-r--r--core/config/engine.cpp1
-rw-r--r--core/config/project_settings.cpp4
-rw-r--r--core/core_constants.cpp4
-rw-r--r--core/error/error_macros.h10
-rw-r--r--core/extension/gdextension.cpp18
-rw-r--r--core/extension/gdextension.h20
-rw-r--r--core/extension/gdextension_interface.cpp17
-rw-r--r--core/extension/gdextension_interface.h25
-rw-r--r--core/input/gamecontrollerdb.txt38
-rw-r--r--core/input/input_event.cpp44
-rw-r--r--core/input/input_event.h5
-rw-r--r--core/io/file_access.cpp2
-rw-r--r--core/io/file_access_memory.cpp2
-rw-r--r--core/io/resource_loader.cpp21
-rw-r--r--core/io/resource_loader.h6
-rw-r--r--core/math/basis.cpp4
-rw-r--r--core/math/convex_hull.cpp16
-rw-r--r--core/math/quaternion.cpp22
-rw-r--r--core/math/quaternion.h5
-rw-r--r--core/math/vector2.cpp8
-rw-r--r--core/math/vector3.cpp2
-rw-r--r--core/math/vector3.h10
-rw-r--r--core/object/class_db.h20
-rw-r--r--core/object/message_queue.cpp12
-rw-r--r--core/object/object.cpp1
-rw-r--r--core/os/keyboard.h6
-rw-r--r--core/os/memory.cpp24
-rw-r--r--core/os/memory.h43
-rw-r--r--core/os/mutex.h80
-rw-r--r--core/os/safe_binary_mutex.h124
-rw-r--r--core/os/spin_lock.h21
-rw-r--r--core/string/translation_po.cpp4
-rw-r--r--core/string/ustring.cpp28
-rw-r--r--core/templates/cowdata.h100
-rw-r--r--core/templates/local_vector.h10
-rw-r--r--core/templates/paged_allocator.h2
-rw-r--r--core/templates/paged_array.h16
-rw-r--r--core/templates/safe_refcount.h2
-rw-r--r--core/typedefs.h1
-rw-r--r--core/variant/binder_common.h9
-rw-r--r--core/variant/dictionary.cpp2
-rw-r--r--core/variant/type_info.h12
-rw-r--r--core/variant/typed_array.h36
-rw-r--r--core/variant/variant.cpp212
-rw-r--r--core/variant/variant.h47
-rw-r--r--core/version.h6
46 files changed, 697 insertions, 405 deletions
diff --git a/core/config/engine.cpp b/core/config/engine.cpp
index 24080c056a..203f8c3882 100644
--- a/core/config/engine.cpp
+++ b/core/config/engine.cpp
@@ -110,7 +110,6 @@ Dictionary Engine::get_version_info() const {
dict["hex"] = VERSION_HEX;
dict["status"] = VERSION_STATUS;
dict["build"] = VERSION_BUILD;
- dict["year"] = VERSION_YEAR;
String hash = String(VERSION_HASH);
dict["hash"] = hash.is_empty() ? String("unknown") : hash;
diff --git a/core/config/project_settings.cpp b/core/config/project_settings.cpp
index 90e2e27320..329af9068e 100644
--- a/core/config/project_settings.cpp
+++ b/core/config/project_settings.cpp
@@ -1410,8 +1410,8 @@ ProjectSettings::ProjectSettings() {
GLOBAL_DEF("display/window/size/extend_to_title", false);
GLOBAL_DEF("display/window/size/no_focus", false);
- GLOBAL_DEF(PropertyInfo(Variant::INT, "display/window/size/window_width_override", PROPERTY_HINT_RANGE, "1,7680,1,or_greater"), 0); // 8K resolution
- GLOBAL_DEF(PropertyInfo(Variant::INT, "display/window/size/window_height_override", PROPERTY_HINT_RANGE, "1,4320,1,or_greater"), 0); // 8K resolution
+ GLOBAL_DEF(PropertyInfo(Variant::INT, "display/window/size/window_width_override", PROPERTY_HINT_RANGE, "0,7680,1,or_greater"), 0); // 8K resolution
+ GLOBAL_DEF(PropertyInfo(Variant::INT, "display/window/size/window_height_override", PROPERTY_HINT_RANGE, "0,4320,1,or_greater"), 0); // 8K resolution
GLOBAL_DEF("display/window/energy_saving/keep_screen_on", true);
GLOBAL_DEF("display/window/energy_saving/keep_screen_on.editor", false);
diff --git a/core/core_constants.cpp b/core/core_constants.cpp
index 3b96fc20c6..aaabbabfd9 100644
--- a/core/core_constants.cpp
+++ b/core/core_constants.cpp
@@ -507,6 +507,10 @@ void register_global_constants() {
BIND_CORE_BITFIELD_CLASS_FLAG(KeyModifierMask, KEY_MASK, KPAD);
BIND_CORE_BITFIELD_CLASS_FLAG(KeyModifierMask, KEY_MASK, GROUP_SWITCH);
+ BIND_CORE_ENUM_CLASS_CONSTANT(KeyLocation, KEY_LOCATION, UNSPECIFIED);
+ BIND_CORE_ENUM_CLASS_CONSTANT(KeyLocation, KEY_LOCATION, LEFT);
+ BIND_CORE_ENUM_CLASS_CONSTANT(KeyLocation, KEY_LOCATION, RIGHT);
+
BIND_CORE_ENUM_CLASS_CONSTANT(MouseButton, MOUSE_BUTTON, NONE);
BIND_CORE_ENUM_CLASS_CONSTANT(MouseButton, MOUSE_BUTTON, LEFT);
BIND_CORE_ENUM_CLASS_CONSTANT(MouseButton, MOUSE_BUTTON, RIGHT);
diff --git a/core/error/error_macros.h b/core/error/error_macros.h
index c8182975d5..016c963e04 100644
--- a/core/error/error_macros.h
+++ b/core/error/error_macros.h
@@ -812,4 +812,14 @@ void _err_flush_stdout();
#define DEV_ASSERT(m_cond)
#endif
+#ifdef DEV_ENABLED
+#define DEV_CHECK_ONCE(m_cond) \
+ if (unlikely(!(m_cond))) { \
+ ERR_PRINT_ONCE("DEV_CHECK_ONCE failed \"" _STR(m_cond) "\" is false."); \
+ } else \
+ ((void)0)
+#else
+#define DEV_CHECK_ONCE(m_cond)
+#endif
+
#endif // ERROR_MACROS_H
diff --git a/core/extension/gdextension.cpp b/core/extension/gdextension.cpp
index ce01531b5c..aba96befd6 100644
--- a/core/extension/gdextension.cpp
+++ b/core/extension/gdextension.cpp
@@ -653,6 +653,8 @@ void GDExtension::_unregister_extension_class(GDExtensionClassLibraryPtr p_libra
if (!ext->is_reloading) {
self->extension_classes.erase(class_name);
}
+
+ GDExtensionEditorHelp::remove_class(class_name);
#else
self->extension_classes.erase(class_name);
#endif
@@ -792,6 +794,9 @@ void GDExtension::deinitialize_library(InitializationLevel p_level) {
ERR_FAIL_COND(p_level > int32_t(level_initialized));
level_initialized = int32_t(p_level) - 1;
+
+ ERR_FAIL_NULL(initialization.deinitialize);
+
initialization.deinitialize(initialization.userdata, GDExtensionInitializationLevel(p_level));
}
@@ -1196,4 +1201,17 @@ void GDExtensionEditorPlugins::remove_extension_class(const StringName &p_class_
extension_classes.erase(p_class_name);
}
}
+
+GDExtensionEditorHelp::EditorHelpLoadXmlBufferFunc GDExtensionEditorHelp::editor_help_load_xml_buffer = nullptr;
+GDExtensionEditorHelp::EditorHelpRemoveClassFunc GDExtensionEditorHelp::editor_help_remove_class = nullptr;
+
+void GDExtensionEditorHelp::load_xml_buffer(const uint8_t *p_buffer, int p_size) {
+ ERR_FAIL_NULL(editor_help_load_xml_buffer);
+ editor_help_load_xml_buffer(p_buffer, p_size);
+}
+
+void GDExtensionEditorHelp::remove_class(const String &p_class) {
+ ERR_FAIL_NULL(editor_help_remove_class);
+ editor_help_remove_class(p_class);
+}
#endif // TOOLS_ENABLED
diff --git a/core/extension/gdextension.h b/core/extension/gdextension.h
index 0b39581751..588efed017 100644
--- a/core/extension/gdextension.h
+++ b/core/extension/gdextension.h
@@ -197,6 +197,26 @@ public:
return extension_classes;
}
};
+
+class GDExtensionEditorHelp {
+protected:
+ friend class EditorHelp;
+
+ // Similarly to EditorNode above, we need to be able to ask EditorHelp to parse
+ // new documentation data. Note though that, differently from EditorHelp, this
+ // is initialized even _before_ it gets instantiated, as we need to rely on
+ // this method while initializing the engine.
+ typedef void (*EditorHelpLoadXmlBufferFunc)(const uint8_t *p_buffer, int p_size);
+ static EditorHelpLoadXmlBufferFunc editor_help_load_xml_buffer;
+
+ typedef void (*EditorHelpRemoveClassFunc)(const String &p_class);
+ static EditorHelpRemoveClassFunc editor_help_remove_class;
+
+public:
+ static void load_xml_buffer(const uint8_t *p_buffer, int p_size);
+ static void remove_class(const String &p_class);
+};
+
#endif // TOOLS_ENABLED
#endif // GDEXTENSION_H
diff --git a/core/extension/gdextension_interface.cpp b/core/extension/gdextension_interface.cpp
index e02e7aa701..88572f24f0 100644
--- a/core/extension/gdextension_interface.cpp
+++ b/core/extension/gdextension_interface.cpp
@@ -42,6 +42,8 @@
#include "core/variant/variant.h"
#include "core/version.h"
+#include <string.h>
+
class CallableCustomExtension : public CallableCustom {
void *userdata;
void *token;
@@ -1373,6 +1375,19 @@ static void gdextension_editor_remove_plugin(GDExtensionConstStringNamePtr p_cla
#endif
}
+static void gdextension_editor_help_load_xml_from_utf8_chars_and_len(const char *p_data, GDExtensionInt p_size) {
+#ifdef TOOLS_ENABLED
+ GDExtensionEditorHelp::load_xml_buffer((const uint8_t *)p_data, p_size);
+#endif
+}
+
+static void gdextension_editor_help_load_xml_from_utf8_chars(const char *p_data) {
+#ifdef TOOLS_ENABLED
+ size_t len = strlen(p_data);
+ gdextension_editor_help_load_xml_from_utf8_chars_and_len(p_data, len);
+#endif
+}
+
#define REGISTER_INTERFACE_FUNC(m_name) GDExtension::register_interface_function(#m_name, (GDExtensionInterfaceFunctionPtr)&gdextension_##m_name)
void gdextension_setup_interface() {
@@ -1516,6 +1531,8 @@ void gdextension_setup_interface() {
REGISTER_INTERFACE_FUNC(classdb_get_class_tag);
REGISTER_INTERFACE_FUNC(editor_add_plugin);
REGISTER_INTERFACE_FUNC(editor_remove_plugin);
+ REGISTER_INTERFACE_FUNC(editor_help_load_xml_from_utf8_chars);
+ REGISTER_INTERFACE_FUNC(editor_help_load_xml_from_utf8_chars_and_len);
}
#undef REGISTER_INTERFACE_FUNCTION
diff --git a/core/extension/gdextension_interface.h b/core/extension/gdextension_interface.h
index d58f0226d8..8fda11c651 100644
--- a/core/extension/gdextension_interface.h
+++ b/core/extension/gdextension_interface.h
@@ -2617,6 +2617,31 @@ typedef void (*GDExtensionInterfaceEditorAddPlugin)(GDExtensionConstStringNamePt
*/
typedef void (*GDExtensionInterfaceEditorRemovePlugin)(GDExtensionConstStringNamePtr p_class_name);
+/**
+ * @name editor_help_load_xml_from_utf8_chars
+ * @since 4.3
+ *
+ * Loads new XML-formatted documentation data in the editor.
+ *
+ * The provided pointer can be immediately freed once the function returns.
+ *
+ * @param p_data A pointer to an UTF-8 encoded C string (null terminated).
+ */
+typedef void (*GDExtensionsInterfaceEditorHelpLoadXmlFromUtf8Chars)(const char *p_data);
+
+/**
+ * @name editor_help_load_xml_from_utf8_chars_and_len
+ * @since 4.3
+ *
+ * Loads new XML-formatted documentation data in the editor.
+ *
+ * The provided pointer can be immediately freed once the function returns.
+ *
+ * @param p_data A pointer to an UTF-8 encoded C string.
+ * @param p_size The number of bytes (not code units).
+ */
+typedef void (*GDExtensionsInterfaceEditorHelpLoadXmlFromUtf8CharsAndLen)(const char *p_data, GDExtensionInt p_size);
+
#ifdef __cplusplus
}
#endif
diff --git a/core/input/gamecontrollerdb.txt b/core/input/gamecontrollerdb.txt
index 77655e9b6a..420de7f9b7 100644
--- a/core/input/gamecontrollerdb.txt
+++ b/core/input/gamecontrollerdb.txt
@@ -314,6 +314,7 @@
03000000242e00000b20000000000000,Hyperkin Admiral N64 Controller,+rightx:b11,+righty:b13,-rightx:b8,-righty:b12,a:b1,b:b0,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,lefttrigger:b14,leftx:a0,lefty:a1,rightshoulder:b5,start:b9,platform:Windows,
03000000242e0000ff0b000000000000,Hyperkin N64 Adapter,a:b1,b:b2,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightx:a2,righty:a3,start:b9,platform:Windows,
03000000790000004e95000000000000,Hyperkin N64 Controller Adapter,a:b1,b:b2,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b7,lefttrigger:b4,leftx:a0,lefty:a1,rightshoulder:b5,rightx:a5,righty:a2,start:b9,platform:Windows,
+03000000242e00006a48000000000000,Hyperkin RetroN Sq,a:b3,b:b7,back:b5,dpdown:+a4,dpleft:-a0,dpright:+a0,dpup:-a4,leftshoulder:b0,rightshoulder:b1,start:b4,x:b2,y:b6,platform:Windows,
03000000242e00006a38000000000000,Hyperkin Trooper 2,a:b0,b:b1,back:b4,leftshoulder:b2,leftx:a0,lefty:a1,rightshoulder:b3,start:b5,platform:Windows,
03000000d81d00000e00000000000000,iBuffalo AC02 Arcade Joystick,a:b0,b:b1,back:b9,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b6,leftstick:b10,lefttrigger:b7,leftx:a0,lefty:a1,rightshoulder:b2,rightstick:b11,righttrigger:b3,rightx:a2,righty:a5,start:b8,x:b4,y:b5,platform:Windows,
03000000d81d00000f00000000000000,iBuffalo BSGP1204 Series,a:b2,b:b1,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b6,leftstick:b10,lefttrigger:b4,leftx:a0,lefty:a1,rightshoulder:b7,rightstick:b11,righttrigger:b5,rightx:a2,righty:a3,start:b9,x:b3,y:b0,platform:Windows,
@@ -352,7 +353,7 @@
030000006d040000d2ca000000000000,Logitech Cordless Precision,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b0,y:b3,platform:Windows,
030000006d04000011c2000000000000,Logitech Cordless Wingman,a:b0,b:b1,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b9,leftstick:b5,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b10,rightstick:b2,righttrigger:b7,rightx:a3,righty:a4,x:b4,platform:Windows,
030000006d04000016c2000000000000,Logitech Dual Action,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b0,y:b3,platform:Windows,
-030000006d0400001dc2000000000000,Logitech F310,a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b8,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b9,rightx:a3,righty:a4,start:b7,x:b2,y:b3,platform:Windows,
+030000006d0400001dc2000000000000,Logitech F310,a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b8,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b9,righttrigger:a5,rightx:a3,righty:a4,start:b7,x:b2,y:b3,platform:Windows,
030000006d04000018c2000000000000,Logitech F510,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b0,y:b3,platform:Windows,
030000006d0400001ec2000000000000,Logitech F510,a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b8,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b9,rightx:a3,righty:a4,start:b7,x:b2,y:b3,platform:Windows,
030000006d04000019c2000000000000,Logitech F710,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b0,y:b3,platform:Windows,
@@ -429,6 +430,8 @@
03000000f70600000100000000000000,N64 Adaptoid,+rightx:b2,+righty:b1,-rightx:b4,-righty:b5,a:b0,b:b3,dpdown:b11,dpleft:b12,dpright:b13,dpup:b10,leftshoulder:b6,lefttrigger:b9,leftx:a0,lefty:a1,rightshoulder:b7,start:b8,platform:Windows,
030000006b140000010c000000000000,Nacon GC 400ES,a:b0,b:b1,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b2,y:b3,platform:Windows,
030000006b1400001106000000000000,Nacon Revolution 3 PS4 Controller,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a5,start:b9,x:b0,y:b3,platform:Windows,
+0300000085320000170d000000000000,Nacon Revolution 5 Pro,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:a3,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:a4,rightx:a2,righty:a5,start:b9,touchpad:b13,x:b0,y:b3,platform:Windows,
+0300000085320000190d000000000000,Nacon Revolution 5 Pro,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:a3,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:a4,rightx:a2,righty:a5,start:b9,touchpad:b13,x:b0,y:b3,platform:Windows,
030000006b140000100d000000000000,Nacon Revolution Infinity PS4 Controller,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b0,y:b3,platform:Windows,
030000006b140000080d000000000000,Nacon Revolution Unlimited Pro Controller,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b0,y:b3,platform:Windows,
03000000bd12000001c0000000000000,Nebular,a:b2,b:b1,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a5,righty:a2,start:b9,x:b3,y:b0,platform:Windows,
@@ -450,7 +453,7 @@
03000000550900001072000000000000,NVIDIA Shield,a:b9,b:b8,back:b11,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b5,leftstick:b3,lefttrigger:a3,leftx:a0,lefty:a1,rightshoulder:b4,rightstick:b2,righttrigger:a4,rightx:a2,righty:a5,start:b0,x:b7,y:b6,platform:Windows,
030000005509000000b4000000000000,NVIDIA Virtual,a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b8,lefttrigger:+a2,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b9,righttrigger:-a2,rightx:a3,righty:a4,start:b7,x:b2,y:b3,platform:Windows,
03000000120c00000288000000000000,Nyko Air Flo Xbox Controller,a:b0,b:b1,back:b7,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b8,lefttrigger:b10,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b9,righttrigger:b11,rightx:a3,righty:a4,start:b6,x:b2,y:b3,platform:Windows,
-030000004b120000014d000000000000,Nyko Airflo,a:b0,b:b1,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b10,leftshoulder:a3,leftstick:a0,lefttrigger:b6,rightshoulder:b5,rightstick:a2,righttrigger:b7,start:b9,x:b2,y:b3,platform:Windows,
+030000004b120000014d000000000000,NYKO Airflo EX,a:b0,b:b1,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b10,leftshoulder:b4,leftstick:b11,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b12,righttrigger:b7,rightx:a3,righty:a2,start:b9,x:b2,y:b3,platform:Windows,
03000000d62000001d57000000000000,Nyko Airflo PS3 Controller,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b0,y:b3,platform:Windows,
03000000791d00000900000000000000,Nyko Playpad,a:b0,b:b1,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b6,leftstick:b13,leftx:a0,lefty:a1,rightshoulder:b7,rightstick:b14,rightx:a2,righty:a5,start:b11,x:b3,y:b4,platform:Windows,
03000000782300000a10000000000000,Onlive Controller,a:b15,b:b14,back:b7,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b5,leftshoulder:b11,leftstick:b9,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b10,rightstick:b8,righttrigger:a5,rightx:a3,righty:a4,start:b6,x:b13,y:b12,platform:Windows,
@@ -459,7 +462,7 @@
030000008916000000fd000000000000,Onza TE,a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b8,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b9,righttrigger:a5,rightx:a3,righty:a4,start:b7,x:b2,y:b3,platform:Windows,
03000000d62000006d57000000000000,OPP PS3 Controller,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b0,y:b3,platform:Windows,
030000006b14000001a1000000000000,Orange Controller,a:b0,b:b1,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b10,leftshoulder:b4,leftstick:b6,lefttrigger:a3,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b7,righttrigger:a4,rightx:a5,righty:a2,start:b9,x:b2,y:b3,platform:Windows,
-03000000362800000100000000000000,OUYA Controller,a:b0,b:b3,dpdown:b9,dpleft:b10,dpright:b11,dpup:b8,guide:b14,leftshoulder:b4,leftstick:b6,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b7,righttrigger:b13,rightx:a3,righty:a4,x:b1,y:b2,platform:Windows,
+03000000362800000100000000000000,OUYA Controller,a:b0,b:b3,dpdown:b9,dpleft:b10,dpright:b11,dpup:b8,guide:b14,leftshoulder:b4,leftstick:b6,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b7,righttrigger:a5,rightx:a3,righty:a4,x:b1,y:b2,platform:Windows,
03000000120c0000f60e000000000000,P4 Gamepad,a:b1,b:b2,back:b12,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b8,leftshoulder:b5,lefttrigger:b7,rightshoulder:b4,righttrigger:b6,start:b9,x:b0,y:b3,platform:Windows,
03000000790000002201000000000000,PC Controller,a:b2,b:b1,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b3,y:b0,platform:Windows,
030000006f0e00008501000000000000,PDP Fightpad Pro GameCube Controller,a:b1,b:b0,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,misc1:b13,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b2,y:b3,platform:Windows,
@@ -532,6 +535,7 @@
030000004c050000a00b000000000000,PS4 Controller,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:a3,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:a4,rightx:a2,righty:a5,start:b9,x:b0,y:b3,platform:Windows,
030000004c050000c405000000000000,PS4 Controller,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:a3,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:a4,rightx:a2,righty:a5,start:b9,touchpad:b13,x:b0,y:b3,platform:Windows,
030000004c050000cc09000000000000,PS4 Controller,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:a3,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:a4,rightx:a2,righty:a5,start:b9,x:b0,y:b3,platform:Windows,
+030000004c0500005f0e000000000000,PS5 Access Controller,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:a3,leftx:a0,lefty:a1,misc1:b14,rightshoulder:b5,rightstick:b11,righttrigger:a4,rightx:a2,righty:a5,start:b9,touchpad:b13,x:b0,y:b3,platform:Windows,
030000004c050000e60c000000000000,PS5 Controller,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:a3,leftx:a0,lefty:a1,misc1:b14,rightshoulder:b5,rightstick:b11,righttrigger:a4,rightx:a2,righty:a5,start:b9,touchpad:b13,x:b0,y:b3,platform:Windows,
030000004c050000f20d000000000000,PS5 Controller,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:a3,leftx:a0,lefty:a1,misc1:b14,rightshoulder:b5,rightstick:b11,righttrigger:a4,rightx:a2,righty:a5,start:b9,touchpad:b13,x:b0,y:b3,platform:Windows,
03000000830500005020000000000000,PSX,a:b0,b:b1,back:b10,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b8,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b9,righttrigger:b7,rightx:a2,righty:a3,start:b11,x:b2,y:b3,platform:Windows,
@@ -556,6 +560,7 @@
030000009b2800003200000000000000,Raphnet GC and N64 Adapter,a:b0,b:b7,dpdown:b11,dpleft:b12,dpright:b13,dpup:b10,lefttrigger:+a5,leftx:a0,lefty:a1,rightshoulder:b2,righttrigger:+a2,rightx:a3,righty:a4,start:b3,x:b1,y:b8,platform:Windows,
030000009b2800006000000000000000,Raphnet GC and N64 Adapter,a:b0,b:b7,dpdown:b11,dpleft:b12,dpright:b13,dpup:b10,lefttrigger:+a5,leftx:a0,lefty:a1,rightshoulder:b2,righttrigger:+a2,rightx:a3,righty:a4,start:b3,x:b1,y:b8,platform:Windows,
030000009b2800001800000000000000,Raphnet Jaguar Adapter,a:b2,b:b1,back:b4,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b13,lefttrigger:b8,leftx:a0,lefty:a1,rightshoulder:b0,righttrigger:b10,start:b3,x:b11,y:b12,platform:Windows,
+030000009b2800006100000000000000,Raphnet N64 Adapter,+rightx:b9,+righty:b7,-rightx:b8,-righty:b6,a:b0,b:b1,dpdown:b11,dpleft:b12,dpright:b13,dpup:b10,leftshoulder:b4,lefttrigger:b2,leftx:a0,lefty:a1,rightshoulder:b5,start:b3,platform:Windows,
030000009b2800006300000000000000,Raphnet N64 Adapter,+rightx:b9,+righty:b7,-rightx:b8,-righty:b6,a:b0,b:b1,dpdown:b11,dpleft:b12,dpright:b13,dpup:b10,leftshoulder:b4,lefttrigger:b2,leftx:a0,lefty:a1,rightshoulder:b5,start:b3,platform:Windows,
030000009b2800000200000000000000,Raphnet NES Adapter,a:b7,b:b6,back:b5,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftx:a0,lefty:a1,start:b4,platform:Windows,
030000009b2800004400000000000000,Raphnet PS1 and PS2 Adapter,a:b1,b:b2,back:b5,dpdown:b13,dpleft:b14,dpright:b15,dpup:b12,leftshoulder:b6,leftstick:b10,lefttrigger:b8,leftx:a0,lefty:a1,rightshoulder:b7,rightstick:b11,righttrigger:b9,rightx:a3,righty:a4,start:b4,x:b0,y:b3,platform:Windows,
@@ -608,6 +613,7 @@
03000000050b00001a1a000000000000,ROG Chakram X,a:b1,b:b0,leftx:a0,lefty:a1,x:b2,y:b3,platform:Windows,
03000000050b00001c1a000000000000,ROG Chakram X,a:b1,b:b0,leftx:a0,lefty:a1,x:b2,y:b3,platform:Windows,
030000004f04000001d0000000000000,Rumble Force,a:b0,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b10,lefttrigger:b5,leftx:a0,lefty:a1,rightshoulder:b6,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b1,y:b3,platform:Windows,
+030000000d0f0000ad00000000000000,RX Gamepad,a:b0,b:b4,back:b11,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b3,rightshoulder:b6,start:b9,x:b2,y:b1,platform:Windows,
030000008916000000fe000000000000,Sabertooth,a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b8,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b9,righttrigger:a5,rightx:a3,righty:a4,start:b7,x:b2,y:b3,platform:Windows,
03000000c6240000045d000000000000,Sabertooth,a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b8,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b9,righttrigger:a5,rightx:a3,righty:a4,start:b7,x:b2,y:b3,platform:Windows,
03000000a30600001af5000000000000,Saitek Cyborg,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a3,righty:a4,start:b9,x:b0,y:b3,platform:Windows,
@@ -674,6 +680,7 @@
03000000457500002211000000000000,Szmy Power PC Gamepad,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b0,y:b3,platform:Windows,
030000004f0400000ab1000000000000,T16000M,a:b0,b:b1,back:b12,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b11,leftshoulder:b4,lefttrigger:b9,leftx:a0,lefty:a1,rightshoulder:b6,righttrigger:b7,start:b10,x:b2,y:b3,platform:Windows,
030000000d0f00007b00000000000000,TAC GEAR,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a5,start:b9,x:b0,y:b3,platform:Windows,
+03000000e40a00000307000000000000,Taito Egret II Mini Control Panel,a:b4,b:b2,back:b6,guide:b9,leftx:a0,lefty:a1,rightshoulder:b0,righttrigger:b1,start:b7,x:b8,y:b3,platform:Windows,
03000000e40a00000207000000000000,Taito Egret II Mini Controller,a:b4,b:b2,back:b6,dpdown:+a1,dpleft:-a0,dpright:+a0,dpup:-a1,guide:b9,rightshoulder:b0,righttrigger:b1,start:b7,x:b8,y:b3,platform:Windows,
03000000d814000001a0000000000000,TE Kitty,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b0,y:b3,platform:Windows,
03000000fa1900000706000000000000,Team 5,a:b2,b:b1,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b3,y:b0,platform:Windows,
@@ -961,6 +968,7 @@ xinput,XInput Controller,a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,
030000004c050000c405000000000000,PS4 Controller,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:a3,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:a4,rightx:a2,righty:a5,start:b9,x:b0,y:b3,platform:Mac OS X,
030000004c050000c405000000010000,PS4 Controller,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:a3,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:a4,rightx:a2,righty:a5,start:b9,x:b0,y:b3,platform:Mac OS X,
030000004c050000cc09000000010000,PS4 Controller,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:a3,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:a4,rightx:a2,righty:a5,start:b9,x:b0,y:b3,platform:Mac OS X,
+0300004b4c0500005f0e000000010000,PS5 Access Controller,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:a3,leftx:a0,lefty:a1,misc1:b14,rightshoulder:b5,rightstick:b11,righttrigger:a4,rightx:a2,righty:a5,start:b9,touchpad:b13,x:b0,y:b3,platform:Mac OS X,
030000004c050000e60c000000010000,PS5 Controller,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:a3,leftx:a0,lefty:a1,misc1:b14,rightshoulder:b5,rightstick:b11,righttrigger:a4,rightx:a2,righty:a5,start:b9,touchpad:b13,x:b0,y:b3,platform:Mac OS X,
030000004c050000f20d000000010000,PS5 Controller,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:a3,leftx:a0,lefty:a1,misc1:b14,rightshoulder:b5,rightstick:b11,righttrigger:a4,rightx:a2,righty:a5,start:b9,touchpad:b13,x:b0,y:b3,platform:Mac OS X,
050000004c050000e60c000000010000,PS5 Controller,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:a3,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:a4,rightx:a2,righty:a5,start:b9,touchpad:b13,x:b0,y:b3,platform:Mac OS X,
@@ -1013,6 +1021,8 @@ xinput,XInput Controller,a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,
03000000110100001714000020010000,SteelSeries Stratus XL,a:b0,b:b1,dpdown:b9,dpleft:b11,dpright:b10,dpup:b8,leftshoulder:b4,lefttrigger:b6,leftx:a0,lefty:a1~,rightshoulder:b5,righttrigger:b7,rightx:a2,righty:a3~,start:b12,x:b2,y:b3,platform:Mac OS X,
030000000d0f0000f600000000010000,Switch Hori Pad,a:b0,b:b1,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b2,y:b3,platform:Mac OS X,
03000000457500002211000000010000,SZMY Power PC Gamepad,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b0,y:b3,platform:Mac OS X,
+03000000e40a00000307000001000000,Taito Egret II Mini Control Panel,a:b4,b:b2,back:b6,guide:b9,leftx:a0,lefty:a1,rightshoulder:b0,righttrigger:b1,start:b7,x:b8,y:b3,platform:Mac OS X,
+03000000e40a00000207000001000000,Taito Egret II Mini Controller,a:b4,b:b2,back:b6,guide:b9,leftx:a0,lefty:a1,rightshoulder:b0,righttrigger:b1,start:b7,x:b8,y:b3,platform:Mac OS X,
03000000790000001c18000003100000,TGZ Controller,a:b0,b:b1,back:b10,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b6,leftstick:b13,lefttrigger:a5,leftx:a0,lefty:a1,rightshoulder:b7,rightstick:b14,righttrigger:a4,rightx:a2,righty:a3,start:b11,x:b3,y:b4,platform:Mac OS X,
03000000591c00002400000021000000,THEC64 Joystick,a:b0,b:b1,back:b6,leftshoulder:b4,leftx:a0,lefty:a4,rightshoulder:b5,start:b7,x:b2,y:b3,platform:Mac OS X,
03000000591c00002600000021000000,THEGamepad,a:b2,b:b1,back:b6,dpdown:+a4,dpleft:-a0,dpright:+a0,dpup:-a4,leftshoulder:b4,rightshoulder:b5,start:b7,x:b3,y:b0,platform:Mac OS X,
@@ -1164,14 +1174,15 @@ xinput,XInput Controller,a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,
03000000c21100000791000011010000,Be1 GC101 Controller 1.03,a:b2,b:b1,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b3,y:b0,platform:Linux,
03000000c31100000791000011010000,Be1 GC101 Controller 1.03,a:b0,b:b1,back:b10,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b6,leftstick:b13,lefttrigger:a5,leftx:a0,lefty:a1,rightshoulder:b7,rightstick:b14,righttrigger:a4,rightx:a2,righty:a3,start:b11,x:b3,y:b4,platform:Linux,
030000005e0400008e02000003030000,Be1 GC101 Xbox 360,a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b8,leftshoulder:b4,leftstick:b9,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b10,righttrigger:a5,rightx:a3,righty:a4,start:b7,x:b2,y:b3,platform:Linux,
-03000000bc2000004d50000011010000,BEITONG A1T2 BFM,a:b0,b:b1,back:b10,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b6,leftstick:b13,lefttrigger:b8,leftx:a0,lefty:a1,rightshoulder:b7,rightstick:b14,righttrigger:b9,rightx:a2,righty:a3,start:b11,x:b3,y:b4,platform:Linux,
-05000000bc2000000055000001000000,BETOP AX1 BFM,a:b0,b:b1,back:b10,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b6,leftstick:b13,lefttrigger:b8,leftx:a0,lefty:a1,rightshoulder:b7,rightstick:b14,righttrigger:b9,rightx:a2,righty:a3,start:b11,x:b3,y:b4,platform:Linux,
+03000000bc2000004d50000011010000,Beitong A1T2 BFM,a:b0,b:b1,back:b10,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b6,leftstick:b13,lefttrigger:b8,leftx:a0,lefty:a1,rightshoulder:b7,rightstick:b14,righttrigger:b9,rightx:a2,righty:a3,start:b11,x:b3,y:b4,platform:Linux,
+05000000bc2000000055000001000000,Betop AX1 BFM,a:b0,b:b1,back:b10,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b6,leftstick:b13,lefttrigger:b8,leftx:a0,lefty:a1,rightshoulder:b7,rightstick:b14,righttrigger:b9,rightx:a2,righty:a3,start:b11,x:b3,y:b4,platform:Linux,
03000000bc2000006412000011010000,Betop Controller,a:b2,b:b1,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b30,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b3,y:b0,platform:Linux,
030000006b1400000209000011010000,Bigben,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b0,y:b3,platform:Linux,
03000000120c0000200e000011010000,Brook Mars PS4 Controller,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:a3,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:a4,rightx:a2,righty:a5,start:b9,x:b0,y:b3,platform:Linux,
03000000120c0000210e000011010000,Brook Mars PS4 Controller,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b0,y:b3,platform:Linux,
03000000120c0000f70e000011010000,Brook Universal Fighting Board,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:b6,rightshoulder:b5,rightstick:b11,righttrigger:b7,start:b9,x:b0,y:b3,platform:Linux,
03000000e82000006058000001010000,Cideko AK08b,a:b2,b:b1,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b3,y:b0,platform:Linux,
+03000000af1e00002400000010010000,Clockwork Pi DevTerm,a:b2,b:b1,back:b8,dpdown:+a1,dpleft:-a0,dpright:+a0,dpup:-a1,start:b9,x:b3,y:b0,platform:Linux,
030000000b0400003365000000010000,Competition Pro,a:b0,b:b1,back:b2,leftx:a0,lefty:a1,start:b3,platform:Linux,
03000000260900008888000000010000,Cyber Gadget GameCube Controller,a:b0,b:b1,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,lefttrigger:a4,leftx:a0,lefty:a1,rightshoulder:b6,righttrigger:a5,rightx:a2,righty:a3~,start:b7,x:b2,y:b3,platform:Linux,
03000000a306000022f6000011010000,Cyborg V3 Rumble,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:+a3,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:-a3,rightx:a2,righty:a4,start:b9,x:b0,y:b3,platform:Linux,
@@ -1218,7 +1229,6 @@ xinput,XInput Controller,a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,
06000000adde0000efbe000002010000,Hidromancer Controller,a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b8,leftshoulder:b4,leftstick:b9,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b10,righttrigger:a5,rightx:a3,righty:a4,start:b7,x:b2,y:b3,platform:Linux,
03000000d81400000862000011010000,HitBox PS3 PC Analog Mode,a:b1,b:b2,back:b8,dpdown:+a1,dpleft:-a0,dpright:+a0,dpup:-a1,guide:b9,leftshoulder:b4,lefttrigger:b6,rightshoulder:b5,righttrigger:b7,start:b12,x:b0,y:b3,platform:Linux,
03000000c9110000f055000011010000,HJC Gamepad,a:b0,b:b1,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b2,y:b3,platform:Linux,
-03000000632500002605000010010000,HJDX,a:b0,b:b1,back:b10,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b6,leftstick:b13,lefttrigger:a4,leftx:a0,lefty:a1,rightshoulder:b7,rightstick:b14,righttrigger:a5,rightx:a2,righty:a3,start:b11,x:b3,y:b4,platform:Linux,
030000000d0f00000d00000000010000,Hori,a:b0,b:b6,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b10,leftshoulder:b3,rightshoulder:b7,start:b9,x:b1,y:b2,platform:Linux,
030000000d0f00006d00000020010000,Hori EDGE 301,a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b8,leftshoulder:b4,leftstick:b9,lefttrigger:+a2,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b10,righttrigger:+a5,rightx:a3,righty:a4,start:b7,x:b2,y:b3,platform:Linux,
030000000d0f00008400000011010000,Hori Fighting Commander,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:a3,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:a4,rightx:a2,righty:a5,start:b9,x:b0,y:b3,platform:Linux,
@@ -1256,6 +1266,7 @@ xinput,XInput Controller,a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,
03000000242e00008816000001010000,Hyperkin X91,a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b8,leftshoulder:b4,leftstick:b9,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b10,righttrigger:a5,rightx:a3,righty:a4,start:b7,x:b2,y:b3,platform:Linux,
03000000f00300008d03000011010000,HyperX Clutch,a:b0,b:b1,back:b10,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b6,leftstick:b13,lefttrigger:a5,leftx:a0,lefty:a1,rightshoulder:b7,rightstick:b14,righttrigger:a4,rightx:a2,righty:a3,start:b11,x:b3,y:b4,platform:Linux,
03000000830500006020000010010000,iBuffalo Super Famicom Controller,a:b1,b:b0,back:b6,dpdown:+a1,dpleft:-a0,dpright:+a0,dpup:-a1,leftshoulder:b4,rightshoulder:b5,start:b7,x:b3,y:b2,platform:Linux,
+030000008f0e00001330000001010000,iCode Retro Adapter,b:b3,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b8,leftshoulder:b9,lefttrigger:b10,leftx:a0,lefty:a1,rightshoulder:b5,righttrigger:b1,start:b7,x:b2,y:b0,platform:Linux,
050000006964726f69643a636f6e0000,idroidcon Controller,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b0,y:b3,platform:Linux,
03000000b50700001503000010010000,Impact,a:b2,b:b3,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b10,lefttrigger:b5,leftx:a0,lefty:a1,rightshoulder:b6,rightstick:b11,righttrigger:b7,rightx:a3,righty:a2,start:b9,x:b0,y:b1,platform:Linux,
03000000d80400008200000003000000,IMS PCU0,a:b1,b:b0,back:b4,dpdown:+a1,dpleft:-a0,dpright:+a0,dpup:-a1,start:b5,x:b3,y:b2,platform:Linux,
@@ -1389,6 +1400,7 @@ xinput,XInput Controller,a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,
03000000550900001072000011010000,NVIDIA Controller,a:b0,b:b1,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b13,leftshoulder:b4,leftstick:b8,lefttrigger:a5,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b9,righttrigger:a4,rightx:a2,righty:a3,start:b7,x:b2,y:b3,platform:Linux,
03000000550900001472000011010000,NVIDIA Controller v01.04,a:b0,b:b1,back:b14,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b16,leftshoulder:b4,leftstick:b7,lefttrigger:a3,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b8,righttrigger:a4,rightx:a2,righty:a5,start:b6,x:b2,y:b3,platform:Linux,
05000000550900001472000001000000,NVIDIA Controller v01.04,a:b0,b:b1,back:b14,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b16,leftshoulder:b4,leftstick:b7,lefttrigger:a3,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b8,righttrigger:a4,rightx:a2,righty:a5,start:b6,x:b2,y:b3,platform:Linux,
+030000004b120000014d000000010000,NYKO Airflo EX,a:b0,b:b1,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b10,leftshoulder:b4,leftstick:b11,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b12,righttrigger:b7,rightx:a3,righty:a2,start:b9,x:b2,y:b3,platform:Linux,
03000000451300000830000010010000,NYKO CORE,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a5,start:b9,x:b0,y:b3,platform:Linux,
19000000010000000100000001010000,ODROID Go 2,a:b1,b:b0,dpdown:b7,dpleft:b8,dpright:b9,dpup:b6,guide:b10,leftshoulder:b4,leftstick:b12,lefttrigger:b11,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b13,righttrigger:b14,start:b15,x:b2,y:b3,platform:Linux,
19000000010000000200000011000000,ODROID Go 2,a:b1,b:b0,dpdown:b9,dpleft:b10,dpright:b11,dpup:b8,guide:b12,leftshoulder:b4,leftstick:b14,lefttrigger:b13,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b15,righttrigger:b16,start:b17,x:b2,y:b3,platform:Linux,
@@ -1407,6 +1419,7 @@ xinput,XInput Controller,a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,
030000006f0e0000c802000012010000,PDP Kingdom Hearts Controller,a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b8,leftshoulder:b4,leftstick:b9,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b10,righttrigger:a5,rightx:a3,righty:a4,start:b7,x:b2,y:b3,platform:Linux,
030000006f0e00002801000011010000,PDP PS3 Rock Candy Controller,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b0,y:b3,platform:Linux,
030000006f0e00000901000011010000,PDP PS3 Versus Fighting,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,lefttrigger:b6,rightshoulder:b5,righttrigger:b7,start:b9,x:b0,y:b3,platform:Linux,
+030000006f0e00002f01000011010000,PDP Wired PS3 Controller,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b0,y:b3,platform:Linux,
03000000ad1b000004f9000000010000,PDP Xbox 360 Versus Fighting,a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b8,leftshoulder:b4,lefttrigger:a2,rightshoulder:b5,righttrigger:a5,start:b7,x:b2,y:b3,platform:Linux,
030000006f0e0000a802000023020000,PDP Xbox One Controller,a:b0,b:b1,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b10,leftshoulder:b4,leftstick:b11,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b12,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b2,y:b3,platform:Linux,
030000006f0e0000a702000023020000,PDP Xbox One Raven Black,a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b8,leftshoulder:b4,leftstick:b9,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b10,righttrigger:a5,rightx:a3,righty:a4,start:b7,x:b2,y:b3,platform:Linux,
@@ -1463,6 +1476,7 @@ xinput,XInput Controller,a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,
050000004c050000cc09000000010000,PS4 Controller,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:a3,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:a4,rightx:a2,righty:a5,start:b9,x:b0,y:b3,platform:Linux,
050000004c050000cc09000000810000,PS4 Controller,a:b0,b:b1,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b10,leftshoulder:b4,leftstick:b11,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b12,righttrigger:a5,rightx:a3,righty:a4,start:b9,x:b3,y:b2,platform:Linux,
050000004c050000cc09000001800000,PS4 Controller,a:b0,b:b1,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b10,leftshoulder:b4,leftstick:b11,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b12,righttrigger:a5,rightx:a3,righty:a4,start:b9,x:b3,y:b2,platform:Linux,
+0300004b4c0500005f0e000011010000,PS5 Access Controller,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:a3,leftx:a0,lefty:a1,misc1:b14,rightshoulder:b5,rightstick:b11,righttrigger:a4,rightx:a2,righty:a5,start:b9,touchpad:b13,x:b0,y:b3,platform:Linux,
030000004c050000e60c000011010000,PS5 Controller,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:a3,leftx:a0,lefty:a1,misc1:b14,rightshoulder:b5,rightstick:b11,righttrigger:a4,rightx:a2,righty:a5,start:b9,touchpad:b13,x:b0,y:b3,platform:Linux,
030000004c050000e60c000011810000,PS5 Controller,a:b0,b:b1,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b10,leftshoulder:b4,leftstick:b11,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b12,righttrigger:a5,rightx:a3,righty:a4,start:b9,x:b3,y:b2,platform:Linux,
030000004c050000f20d000011010000,PS5 Controller,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:a3,leftx:a0,lefty:a1,misc1:b14,rightshoulder:b5,rightstick:b11,righttrigger:a4,rightx:a2,righty:a5,start:b9,touchpad:b13,x:b0,y:b3,platform:Linux,
@@ -1528,9 +1542,10 @@ xinput,XInput Controller,a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,
03000000b40400000a01000000010000,Sega Saturn,a:b0,b:b1,dpdown:+a1,dpleft:-a0,dpright:+a0,dpup:-a1,leftshoulder:b6,lefttrigger:b7,rightshoulder:b5,righttrigger:b2,start:b8,x:b3,y:b4,platform:Linux,
030000001f08000001e4000010010000,SFC Controller,a:b2,b:b1,back:b8,dpdown:+a1,dpleft:-a0,dpright:+a0,dpup:-a1,leftshoulder:b4,rightshoulder:b5,start:b9,x:b3,y:b0,platform:Linux,
03000000632500002305000010010000,ShanWan Gamepad,a:b2,b:b1,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b3,y:b0,platform:Linux,
+03000000632500002605000010010000,Shanwan Gamepad,a:b0,b:b1,back:b10,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b6,leftstick:b13,lefttrigger:a5,leftx:a0,lefty:a1,rightshoulder:b7,rightstick:b14,righttrigger:a4,rightx:a2,righty:a3,start:b11,x:b3,y:b4,platform:Linux,
+03000000632500007505000010010000,Shanwan Gamepad,a:b2,b:b1,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b3,y:b0,platform:Linux,
+03000000bc2000000055000010010000,Shanwan Gamepad,a:b0,b:b1,back:b10,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b6,leftstick:b13,lefttrigger:a5,leftx:a0,lefty:a1,rightshoulder:b7,rightstick:b14,righttrigger:a4,rightx:a2,righty:a3,start:b11,x:b3,y:b4,platform:Linux,
03000000f025000021c1000010010000,Shanwan Gioteck PS3 Controller,a:b2,b:b1,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b3,y:b0,platform:Linux,
-03000000632500007505000010010000,Shanwan PS3 PC,a:b2,b:b1,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b3,y:b0,platform:Linux,
-03000000bc2000000055000010010000,Shanwan PS3 PC ,a:b0,b:b1,back:b10,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b6,leftstick:b13,lefttrigger:a5,leftx:a0,lefty:a1,rightshoulder:b7,rightstick:b14,righttrigger:a4,rightx:a2,righty:a3,start:b11,x:b3,y:b4,platform:Linux,
03000000341a00000908000010010000,SL6566,a:b0,b:b1,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b2,y:b3,platform:Linux,
050000004c050000cc09000001000000,Sony DualShock 4,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:a3,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:a4,rightx:a2,righty:a5,start:b9,x:b0,y:b3,platform:Linux,
03000000ff000000cb01000010010000,Sony PlayStation Portable,a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftx:a0,lefty:a1,rightshoulder:b5,start:b7,x:b2,y:b3,platform:Linux,
@@ -1564,6 +1579,8 @@ xinput,XInput Controller,a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,
03000000457500000401000011010000,SZMY Power DS4 Wired Controller,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:a3,leftx:a0,lefty:a1,misc1:b13,rightshoulder:b5,rightstick:b11,righttrigger:a4,rightx:a2,righty:a5,start:b9,x:b0,y:b3,platform:Linux,
03000000457500002211000010010000,SZMY Power Gamepad,a:b2,b:b1,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b3,y:b0,platform:Linux,
030000008f0e00001431000010010000,SZMY Power PS3,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b0,y:b3,platform:Linux,
+03000000e40a00000307000011010000,Taito Egret II Mini Control Panel,a:b4,b:b2,back:b6,guide:b9,leftx:a0,lefty:a1,rightshoulder:b0,righttrigger:b1,start:b7,x:b8,y:b3,platform:Linux,
+03000000e40a00000207000011010000,Taito Egret II Mini Controller,a:b4,b:b2,back:b6,guide:b9,leftx:a0,lefty:a1,rightshoulder:b0,righttrigger:b1,start:b7,x:b8,y:b3,platform:Linux,
03000000ba2200000701000001010000,Technology Innovation PS2 Adapter,a:b0,b:b1,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a5,righty:a2,start:b9,x:b3,y:b2,platform:Linux,
03000000790000001c18000011010000,TGZ Controller,a:b0,b:b1,back:b10,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b6,leftstick:b13,lefttrigger:b8,leftx:a0,lefty:a1,rightshoulder:b7,rightstick:b14,righttrigger:b9,rightx:a2,righty:a3,start:b11,x:b3,y:b4,platform:Linux,
03000000591c00002400000010010000,THEC64 Joystick,a:b0,b:b1,back:b6,leftshoulder:b4,leftx:a0,lefty:a1,rightshoulder:b5,start:b7,x:b2,y:b3,platform:Linux,
@@ -1871,9 +1888,9 @@ xinput,XInput Controller,a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,
36313938306539326233393732613361,Retro Bit SNES Controller,a:b0,b:b1,back:b15,dpdown:+a1,dpleft:-a0,dpright:+a0,dpup:-a1,leftshoulder:b9,rightshoulder:b10,start:b6,x:b2,y:b3,platform:Android,
526574726f466c616720576972656420,Retro Controller,a:b0,b:b1,back:b9,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b17,rightshoulder:b18,start:b10,x:b2,y:b3,platform:Android,
61343739353764363165343237303336,Retro Controller,a:b0,b:b1,back:b9,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b17,lefttrigger:b18,leftx:a0,lefty:a1,start:b10,x:b2,y:b3,platform:Android,
+526574726f696420506f636b65742043,Retroid Pocket,a:b1,b:b0,back:b4,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b9,leftstick:b7,lefttrigger:a5,leftx:a0,lefty:a1,paddle1:b17,paddle2:b18,rightshoulder:b10,rightstick:b8,righttrigger:a4,rightx:a2,righty:a3,start:b6,x:b3,y:b2,platform:Android,
+582d426f7820436f6e74726f6c6c6572,Retroid Pocket,a:b0,b:b1,back:b4,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b9,leftstick:b7,lefttrigger:a5,leftx:a0,lefty:a1,paddle1:b17,paddle2:b18,rightshoulder:b10,rightstick:b8,righttrigger:a4,rightx:a2,righty:a3,start:b6,x:b2,y:b3,platform:Android,
38653130373365613538333235303036,Retroid Pocket 2,a:b0,b:b1,back:b15,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b9,lefttrigger:b17,leftx:a0,lefty:a1,rightshoulder:b10,righttrigger:b18,rightx:a2,righty:a3,start:b6,x:b2,y:b3,platform:Android,
-526574726f696420506f636b65742043,Retroid Pocket Flip,a:b1,b:b0,back:b4,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b9,leftstick:b7,lefttrigger:a5,leftx:a0,lefty:a1,paddle1:b17,paddle2:b18,rightshoulder:b10,rightstick:b8,righttrigger:a4,rightx:a2,righty:a3,start:b6,x:b3,y:b2,platform:Android,
-582d426f7820436f6e74726f6c6c6572,Retroid Pocket Flip,a:b0,b:b1,back:b4,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b9,leftstick:b7,lefttrigger:a5,leftx:a0,lefty:a1,paddle1:b17,paddle2:b18,rightshoulder:b10,rightstick:b8,righttrigger:a4,rightx:a2,righty:a3,start:b6,x:b2,y:b3,platform:Android,
64363363336633363736393038313463,Retrolink,a:b1,b:b0,back:b15,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,start:b6,platform:Android,
37393234373533633333323633646531,RetroUSB N64 RetroPort,+rightx:b17,+righty:b15,-rightx:b18,-righty:b6,a:b10,b:b9,dpdown:b19,dpleft:b1,dpright:b0,dpup:b2,leftshoulder:b7,lefttrigger:b20,leftx:a0,lefty:a1,rightshoulder:b5,start:b3,platform:Android,
5365616c6965436f6d707574696e6720,RetroUSB N64 RetroPort,+rightx:b17,+righty:b15,-rightx:b18,-righty:b6,a:b10,b:b9,dpdown:b19,dpleft:b1,dpright:b0,dpup:b2,leftshoulder:b7,lefttrigger:b20,leftx:a0,lefty:a1,rightshoulder:b5,start:b3,platform:Android,
@@ -1902,6 +1919,7 @@ xinput,XInput Controller,a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,
05000000de2800000611000001000000,Steam Controller,a:b0,b:b1,back:b6,guide:b8,leftshoulder:b4,leftstick:b9,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b5,righttrigger:a3,start:b7,x:b2,y:b3,platform:Android,
0500000011010000201400000f7e0f00,SteelSeries Nimbus,a:b0,b:b1,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b3,lefttrigger:b9,leftx:a0,lefty:a1,rightshoulder:b20,righttrigger:b10,rightx:a2,righty:a3,x:b19,y:b2,platform:Android,
35306436396437373135383665646464,SteelSeries Nimbus Plus,a:b0,b:b1,leftshoulder:b3,leftstick:b17,lefttrigger:b9,leftx:a0,rightshoulder:b20,rightstick:b18,righttrigger:b10,rightx:a2,x:b19,y:b2,platform:Android,
+33313930373536613937326534303931,Taito Egret II Mini Control Panel,a:b25,b:b23,back:b27,guide:b30,leftx:a0,lefty:a1,rightshoulder:b21,righttrigger:b22,start:b28,x:b29,y:b24,platform:Android,
54475a20436f6e74726f6c6c65720000,TGZ Controller,a:b0,b:b1,back:b15,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b9,leftstick:b7,lefttrigger:b17,leftx:a0,lefty:a1,rightshoulder:b10,rightstick:b8,righttrigger:b18,rightx:a2,righty:a3,start:b6,x:b2,y:b3,platform:Android,
62363434353532386238336663643836,TGZ Controller,a:b0,b:b1,back:b15,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b9,leftstick:b7,lefttrigger:b17,leftx:a0,lefty:a1,rightshoulder:b10,rightstick:b8,righttrigger:b18,rightx:a2,righty:a3,start:b6,x:b2,y:b3,platform:Android,
37323236633763666465316365313236,THEC64 Joystick,a:b21,b:b22,back:b27,leftshoulder:b25,leftx:a0,lefty:a1,rightshoulder:b26,start:b27,x:b23,y:b24,platform:Android,
diff --git a/core/input/input_event.cpp b/core/input/input_event.cpp
index e99dd04599..89ffcecf50 100644
--- a/core/input/input_event.cpp
+++ b/core/input/input_event.cpp
@@ -364,6 +364,15 @@ char32_t InputEventKey::get_unicode() const {
return unicode;
}
+void InputEventKey::set_location(KeyLocation p_key_location) {
+ location = p_key_location;
+ emit_changed();
+}
+
+KeyLocation InputEventKey::get_location() const {
+ return location;
+}
+
void InputEventKey::set_echo(bool p_enable) {
echo = p_enable;
emit_changed();
@@ -436,6 +445,23 @@ String InputEventKey::as_text_key_label() const {
return mods_text.is_empty() ? kc : mods_text + "+" + kc;
}
+String InputEventKey::as_text_location() const {
+ String loc;
+
+ switch (location) {
+ case KeyLocation::LEFT:
+ loc = "left";
+ break;
+ case KeyLocation::RIGHT:
+ loc = "right";
+ break;
+ default:
+ break;
+ }
+
+ return loc;
+}
+
String InputEventKey::as_text() const {
String kc;
@@ -464,6 +490,11 @@ String InputEventKey::to_string() {
String kc = "";
String physical = "false";
+ String loc = as_text_location();
+ if (loc.is_empty()) {
+ loc = "unspecified";
+ }
+
if (keycode == Key::NONE && physical_keycode == Key::NONE && unicode != 0) {
kc = "U+" + String::num_uint64(unicode, 16) + " (" + String::chr(unicode) + ")";
} else if (keycode != Key::NONE) {
@@ -478,7 +509,7 @@ String InputEventKey::to_string() {
String mods = InputEventWithModifiers::as_text();
mods = mods.is_empty() ? "none" : mods;
- return vformat("InputEventKey: keycode=%s, mods=%s, physical=%s, pressed=%s, echo=%s", kc, mods, physical, p, e);
+ return vformat("InputEventKey: keycode=%s, mods=%s, physical=%s, location=%s, pressed=%s, echo=%s", kc, mods, physical, loc, p, e);
}
Ref<InputEventKey> InputEventKey::create_reference(Key p_keycode, bool p_physical) {
@@ -531,6 +562,9 @@ bool InputEventKey::action_match(const Ref<InputEvent> &p_event, bool p_exact_ma
match = keycode == key->keycode;
} else if (physical_keycode != Key::NONE) {
match = physical_keycode == key->physical_keycode;
+ if (location != KeyLocation::UNSPECIFIED) {
+ match &= location == key->location;
+ }
} else {
match = false;
}
@@ -572,6 +606,9 @@ bool InputEventKey::is_match(const Ref<InputEvent> &p_event, bool p_exact_match)
return (keycode == key->keycode) &&
(!p_exact_match || get_modifiers_mask() == key->get_modifiers_mask());
} else if (physical_keycode != Key::NONE) {
+ if (location != KeyLocation::UNSPECIFIED && location != key->location) {
+ return false;
+ }
return (physical_keycode == key->physical_keycode) &&
(!p_exact_match || get_modifiers_mask() == key->get_modifiers_mask());
} else {
@@ -594,6 +631,9 @@ void InputEventKey::_bind_methods() {
ClassDB::bind_method(D_METHOD("set_unicode", "unicode"), &InputEventKey::set_unicode);
ClassDB::bind_method(D_METHOD("get_unicode"), &InputEventKey::get_unicode);
+ ClassDB::bind_method(D_METHOD("set_location", "location"), &InputEventKey::set_location);
+ ClassDB::bind_method(D_METHOD("get_location"), &InputEventKey::get_location);
+
ClassDB::bind_method(D_METHOD("set_echo", "echo"), &InputEventKey::set_echo);
ClassDB::bind_method(D_METHOD("get_keycode_with_modifiers"), &InputEventKey::get_keycode_with_modifiers);
@@ -603,12 +643,14 @@ void InputEventKey::_bind_methods() {
ClassDB::bind_method(D_METHOD("as_text_keycode"), &InputEventKey::as_text_keycode);
ClassDB::bind_method(D_METHOD("as_text_physical_keycode"), &InputEventKey::as_text_physical_keycode);
ClassDB::bind_method(D_METHOD("as_text_key_label"), &InputEventKey::as_text_key_label);
+ ClassDB::bind_method(D_METHOD("as_text_location"), &InputEventKey::as_text_location);
ADD_PROPERTY(PropertyInfo(Variant::BOOL, "pressed"), "set_pressed", "is_pressed");
ADD_PROPERTY(PropertyInfo(Variant::INT, "keycode"), "set_keycode", "get_keycode");
ADD_PROPERTY(PropertyInfo(Variant::INT, "physical_keycode"), "set_physical_keycode", "get_physical_keycode");
ADD_PROPERTY(PropertyInfo(Variant::INT, "key_label"), "set_key_label", "get_key_label");
ADD_PROPERTY(PropertyInfo(Variant::INT, "unicode"), "set_unicode", "get_unicode");
+ ADD_PROPERTY(PropertyInfo(Variant::INT, "location", PROPERTY_HINT_ENUM, "Unspecified,Left,Right"), "set_location", "get_location");
ADD_PROPERTY(PropertyInfo(Variant::BOOL, "echo"), "set_echo", "is_echo");
}
diff --git a/core/input/input_event.h b/core/input/input_event.h
index ed7ccf0a9f..61a53116e9 100644
--- a/core/input/input_event.h
+++ b/core/input/input_event.h
@@ -157,6 +157,7 @@ class InputEventKey : public InputEventWithModifiers {
Key physical_keycode = Key::NONE;
Key key_label = Key::NONE;
uint32_t unicode = 0; ///unicode
+ KeyLocation location = KeyLocation::UNSPECIFIED;
bool echo = false; /// true if this is an echo key
@@ -178,6 +179,9 @@ public:
void set_unicode(char32_t p_unicode);
char32_t get_unicode() const;
+ void set_location(KeyLocation p_key_location);
+ KeyLocation get_location() const;
+
void set_echo(bool p_enable);
virtual bool is_echo() const override;
@@ -193,6 +197,7 @@ public:
virtual String as_text_physical_keycode() const;
virtual String as_text_keycode() const;
virtual String as_text_key_label() const;
+ virtual String as_text_location() const;
virtual String as_text() const override;
virtual String to_string() override;
diff --git a/core/io/file_access.cpp b/core/io/file_access.cpp
index 6026dbf896..55286277fa 100644
--- a/core/io/file_access.cpp
+++ b/core/io/file_access.cpp
@@ -38,7 +38,7 @@
#include "core/io/marshalls.h"
#include "core/os/os.h"
-FileAccess::CreateFunc FileAccess::create_func[ACCESS_MAX] = { nullptr, nullptr };
+FileAccess::CreateFunc FileAccess::create_func[ACCESS_MAX] = {};
FileAccess::FileCloseFailNotify FileAccess::close_fail_notify = nullptr;
diff --git a/core/io/file_access_memory.cpp b/core/io/file_access_memory.cpp
index 0983920b94..da02c883e8 100644
--- a/core/io/file_access_memory.cpp
+++ b/core/io/file_access_memory.cpp
@@ -119,7 +119,7 @@ uint64_t FileAccessMemory::get_length() const {
}
bool FileAccessMemory::eof_reached() const {
- return pos > length;
+ return pos >= length;
}
uint8_t FileAccessMemory::get_8() const {
diff --git a/core/io/resource_loader.cpp b/core/io/resource_loader.cpp
index ba11d84bce..2fb3bda87d 100644
--- a/core/io/resource_loader.cpp
+++ b/core/io/resource_loader.cpp
@@ -36,6 +36,7 @@
#include "core/object/script_language.h"
#include "core/os/condition_variable.h"
#include "core/os/os.h"
+#include "core/os/safe_binary_mutex.h"
#include "core/string/print_string.h"
#include "core/string/translation.h"
#include "core/variant/variant_parser.h"
@@ -244,11 +245,11 @@ Ref<Resource> ResourceLoader::_load(const String &p_path, const String &p_origin
thread_load_mutex.lock();
HashMap<String, ThreadLoadTask>::Iterator E = thread_load_tasks.find(load_paths_stack->get(load_paths_stack->size() - 1));
if (E) {
- E->value.sub_tasks.insert(p_path);
+ E->value.sub_tasks.insert(p_original_path);
}
thread_load_mutex.unlock();
}
- load_paths_stack->push_back(p_path);
+ load_paths_stack->push_back(p_original_path);
// Try all loaders and pick the first match for the type hint
bool found = false;
@@ -509,20 +510,20 @@ Ref<ResourceLoader::LoadToken> ResourceLoader::_load_start(const String &p_path,
float ResourceLoader::_dependency_get_progress(const String &p_path) {
if (thread_load_tasks.has(p_path)) {
ThreadLoadTask &load_task = thread_load_tasks[p_path];
+ float current_progress = 0.0;
int dep_count = load_task.sub_tasks.size();
if (dep_count > 0) {
- float dep_progress = 0;
for (const String &E : load_task.sub_tasks) {
- dep_progress += _dependency_get_progress(E);
+ current_progress += _dependency_get_progress(E);
}
- dep_progress /= float(dep_count);
- dep_progress *= 0.5;
- dep_progress += load_task.progress * 0.5;
- return dep_progress;
+ current_progress /= float(dep_count);
+ current_progress *= 0.5;
+ current_progress += load_task.progress * 0.5;
} else {
- return load_task.progress;
+ current_progress = load_task.progress;
}
-
+ load_task.max_reported_progress = MAX(load_task.max_reported_progress, current_progress);
+ return load_task.max_reported_progress;
} else {
return 1.0; //assume finished loading it so it no longer exists
}
diff --git a/core/io/resource_loader.h b/core/io/resource_loader.h
index 3c32a19066..3099d9aab3 100644
--- a/core/io/resource_loader.h
+++ b/core/io/resource_loader.h
@@ -39,6 +39,9 @@
class ConditionVariable;
+template <int Tag>
+class SafeBinaryMutex;
+
class ResourceFormatLoader : public RefCounted {
GDCLASS(ResourceFormatLoader, RefCounted);
@@ -167,7 +170,8 @@ private:
String remapped_path;
String dependent_path;
String type_hint;
- float progress = 0.0;
+ float progress = 0.0f;
+ float max_reported_progress = 0.0f;
ThreadLoadStatus status = THREAD_LOAD_IN_PROGRESS;
ResourceFormatLoader::CacheMode cache_mode = ResourceFormatLoader::CACHE_MODE_REUSE;
Error error = OK;
diff --git a/core/math/basis.cpp b/core/math/basis.cpp
index cd8c87b158..1ff6cdd588 100644
--- a/core/math/basis.cpp
+++ b/core/math/basis.cpp
@@ -722,7 +722,7 @@ Basis::operator String() const {
Quaternion Basis::get_quaternion() const {
#ifdef MATH_CHECKS
- ERR_FAIL_COND_V_MSG(!is_rotation(), Quaternion(), "Basis must be normalized in order to be casted to a Quaternion. Use get_rotation_quaternion() or call orthonormalized() if the Basis contains linearly independent vectors.");
+ ERR_FAIL_COND_V_MSG(!is_rotation(), Quaternion(), "Basis " + operator String() + " must be normalized in order to be casted to a Quaternion. Use get_rotation_quaternion() or call orthonormalized() if the Basis contains linearly independent vectors.");
#endif
/* Allow getting a quaternion from an unnormalized transform */
Basis m = *this;
@@ -849,7 +849,7 @@ void Basis::set_quaternion(const Quaternion &p_quaternion) {
void Basis::set_axis_angle(const Vector3 &p_axis, real_t p_angle) {
// Rotation matrix from axis and angle, see https://en.wikipedia.org/wiki/Rotation_matrix#Rotation_matrix_from_axis_angle
#ifdef MATH_CHECKS
- ERR_FAIL_COND_MSG(!p_axis.is_normalized(), "The axis Vector3 must be normalized.");
+ ERR_FAIL_COND_MSG(!p_axis.is_normalized(), "The axis Vector3 " + p_axis.operator String() + " must be normalized.");
#endif
Vector3 axis_sq(p_axis.x * p_axis.x, p_axis.y * p_axis.y, p_axis.z * p_axis.z);
real_t cosine = Math::cos(p_angle);
diff --git a/core/math/convex_hull.cpp b/core/math/convex_hull.cpp
index 68d995fe67..478fde3a64 100644
--- a/core/math/convex_hull.cpp
+++ b/core/math/convex_hull.cpp
@@ -344,31 +344,31 @@ public:
Rational128(int64_t p_value) {
if (p_value > 0) {
sign = 1;
- this->numerator = p_value;
+ numerator = p_value;
} else if (p_value < 0) {
sign = -1;
- this->numerator = -p_value;
+ numerator = -p_value;
} else {
sign = 0;
- this->numerator = (uint64_t)0;
+ numerator = (uint64_t)0;
}
- this->denominator = (uint64_t)1;
+ denominator = (uint64_t)1;
is_int_64 = true;
}
Rational128(const Int128 &p_numerator, const Int128 &p_denominator) {
sign = p_numerator.get_sign();
if (sign >= 0) {
- this->numerator = p_numerator;
+ numerator = p_numerator;
} else {
- this->numerator = -p_numerator;
+ numerator = -p_numerator;
}
int32_t dsign = p_denominator.get_sign();
if (dsign >= 0) {
- this->denominator = p_denominator;
+ denominator = p_denominator;
} else {
sign = -sign;
- this->denominator = -p_denominator;
+ denominator = -p_denominator;
}
is_int_64 = false;
}
diff --git a/core/math/quaternion.cpp b/core/math/quaternion.cpp
index e4ad17c8ef..cbaaa1371a 100644
--- a/core/math/quaternion.cpp
+++ b/core/math/quaternion.cpp
@@ -41,7 +41,7 @@ real_t Quaternion::angle_to(const Quaternion &p_to) const {
Vector3 Quaternion::get_euler(EulerOrder p_order) const {
#ifdef MATH_CHECKS
- ERR_FAIL_COND_V_MSG(!is_normalized(), Vector3(0, 0, 0), "The quaternion must be normalized.");
+ ERR_FAIL_COND_V_MSG(!is_normalized(), Vector3(0, 0, 0), "The quaternion " + operator String() + " must be normalized.");
#endif
return Basis(*this).get_euler(p_order);
}
@@ -88,7 +88,7 @@ bool Quaternion::is_normalized() const {
Quaternion Quaternion::inverse() const {
#ifdef MATH_CHECKS
- ERR_FAIL_COND_V_MSG(!is_normalized(), Quaternion(), "The quaternion must be normalized.");
+ ERR_FAIL_COND_V_MSG(!is_normalized(), Quaternion(), "The quaternion " + operator String() + " must be normalized.");
#endif
return Quaternion(-x, -y, -z, w);
}
@@ -112,8 +112,8 @@ Quaternion Quaternion::exp() const {
Quaternion Quaternion::slerp(const Quaternion &p_to, const real_t &p_weight) const {
#ifdef MATH_CHECKS
- ERR_FAIL_COND_V_MSG(!is_normalized(), Quaternion(), "The start quaternion must be normalized.");
- ERR_FAIL_COND_V_MSG(!p_to.is_normalized(), Quaternion(), "The end quaternion must be normalized.");
+ ERR_FAIL_COND_V_MSG(!is_normalized(), Quaternion(), "The start quaternion " + operator String() + " must be normalized.");
+ ERR_FAIL_COND_V_MSG(!p_to.is_normalized(), Quaternion(), "The end quaternion " + p_to.operator String() + " must be normalized.");
#endif
Quaternion to1;
real_t omega, cosom, sinom, scale0, scale1;
@@ -153,8 +153,8 @@ Quaternion Quaternion::slerp(const Quaternion &p_to, const real_t &p_weight) con
Quaternion Quaternion::slerpni(const Quaternion &p_to, const real_t &p_weight) const {
#ifdef MATH_CHECKS
- ERR_FAIL_COND_V_MSG(!is_normalized(), Quaternion(), "The start quaternion must be normalized.");
- ERR_FAIL_COND_V_MSG(!p_to.is_normalized(), Quaternion(), "The end quaternion must be normalized.");
+ ERR_FAIL_COND_V_MSG(!is_normalized(), Quaternion(), "The start quaternion " + operator String() + " must be normalized.");
+ ERR_FAIL_COND_V_MSG(!p_to.is_normalized(), Quaternion(), "The end quaternion " + p_to.operator String() + " must be normalized.");
#endif
const Quaternion &from = *this;
@@ -177,8 +177,8 @@ Quaternion Quaternion::slerpni(const Quaternion &p_to, const real_t &p_weight) c
Quaternion Quaternion::spherical_cubic_interpolate(const Quaternion &p_b, const Quaternion &p_pre_a, const Quaternion &p_post_b, const real_t &p_weight) const {
#ifdef MATH_CHECKS
- ERR_FAIL_COND_V_MSG(!is_normalized(), Quaternion(), "The start quaternion must be normalized.");
- ERR_FAIL_COND_V_MSG(!p_b.is_normalized(), Quaternion(), "The end quaternion must be normalized.");
+ ERR_FAIL_COND_V_MSG(!is_normalized(), Quaternion(), "The start quaternion " + operator String() + " must be normalized.");
+ ERR_FAIL_COND_V_MSG(!p_b.is_normalized(), Quaternion(), "The end quaternion " + p_b.operator String() + " must be normalized.");
#endif
Quaternion from_q = *this;
Quaternion pre_q = p_pre_a;
@@ -228,8 +228,8 @@ Quaternion Quaternion::spherical_cubic_interpolate(const Quaternion &p_b, const
Quaternion Quaternion::spherical_cubic_interpolate_in_time(const Quaternion &p_b, const Quaternion &p_pre_a, const Quaternion &p_post_b, const real_t &p_weight,
const real_t &p_b_t, const real_t &p_pre_a_t, const real_t &p_post_b_t) const {
#ifdef MATH_CHECKS
- ERR_FAIL_COND_V_MSG(!is_normalized(), Quaternion(), "The start quaternion must be normalized.");
- ERR_FAIL_COND_V_MSG(!p_b.is_normalized(), Quaternion(), "The end quaternion must be normalized.");
+ ERR_FAIL_COND_V_MSG(!is_normalized(), Quaternion(), "The start quaternion " + operator String() + " must be normalized.");
+ ERR_FAIL_COND_V_MSG(!p_b.is_normalized(), Quaternion(), "The end quaternion " + p_b.operator String() + " must be normalized.");
#endif
Quaternion from_q = *this;
Quaternion pre_q = p_pre_a;
@@ -294,7 +294,7 @@ real_t Quaternion::get_angle() const {
Quaternion::Quaternion(const Vector3 &p_axis, real_t p_angle) {
#ifdef MATH_CHECKS
- ERR_FAIL_COND_MSG(!p_axis.is_normalized(), "The axis Vector3 must be normalized.");
+ ERR_FAIL_COND_MSG(!p_axis.is_normalized(), "The axis Vector3 " + p_axis.operator String() + " must be normalized.");
#endif
real_t d = p_axis.length();
if (d == 0) {
diff --git a/core/math/quaternion.h b/core/math/quaternion.h
index ea952304a5..f8133df559 100644
--- a/core/math/quaternion.h
+++ b/core/math/quaternion.h
@@ -33,8 +33,7 @@
#include "core/math/math_funcs.h"
#include "core/math/vector3.h"
-
-class String;
+#include "core/string/ustring.h"
struct _NO_DISCARD_ Quaternion {
union {
@@ -90,7 +89,7 @@ struct _NO_DISCARD_ Quaternion {
_FORCE_INLINE_ Vector3 xform(const Vector3 &v) const {
#ifdef MATH_CHECKS
- ERR_FAIL_COND_V_MSG(!is_normalized(), v, "The quaternion must be normalized.");
+ ERR_FAIL_COND_V_MSG(!is_normalized(), v, "The quaternion " + operator String() + " must be normalized.");
#endif
Vector3 u(x, y, z);
Vector3 uv = u.cross(v);
diff --git a/core/math/vector2.cpp b/core/math/vector2.cpp
index df8c804243..74631d3e29 100644
--- a/core/math/vector2.cpp
+++ b/core/math/vector2.cpp
@@ -162,9 +162,9 @@ Vector2 Vector2::move_toward(const Vector2 &p_to, const real_t p_delta) const {
// slide returns the component of the vector along the given plane, specified by its normal vector.
Vector2 Vector2::slide(const Vector2 &p_normal) const {
#ifdef MATH_CHECKS
- ERR_FAIL_COND_V_MSG(!p_normal.is_normalized(), Vector2(), "The normal Vector2 must be normalized.");
+ ERR_FAIL_COND_V_MSG(!p_normal.is_normalized(), Vector2(), "The normal Vector2 " + p_normal.operator String() + "must be normalized.");
#endif
- return *this - p_normal * this->dot(p_normal);
+ return *this - p_normal * dot(p_normal);
}
Vector2 Vector2::bounce(const Vector2 &p_normal) const {
@@ -173,9 +173,9 @@ Vector2 Vector2::bounce(const Vector2 &p_normal) const {
Vector2 Vector2::reflect(const Vector2 &p_normal) const {
#ifdef MATH_CHECKS
- ERR_FAIL_COND_V_MSG(!p_normal.is_normalized(), Vector2(), "The normal Vector2 must be normalized.");
+ ERR_FAIL_COND_V_MSG(!p_normal.is_normalized(), Vector2(), "The normal Vector2 " + p_normal.operator String() + "must be normalized.");
#endif
- return 2.0f * p_normal * this->dot(p_normal) - *this;
+ return 2.0f * p_normal * dot(p_normal) - *this;
}
bool Vector2::is_equal_approx(const Vector2 &p_v) const {
diff --git a/core/math/vector3.cpp b/core/math/vector3.cpp
index ae009fc4ef..c483d659a3 100644
--- a/core/math/vector3.cpp
+++ b/core/math/vector3.cpp
@@ -109,7 +109,7 @@ Vector3 Vector3::octahedron_decode(const Vector2 &p_oct) {
Vector2 Vector3::octahedron_tangent_encode(const float sign) const {
const float bias = 1.0f / 32767.0f;
- Vector2 res = this->octahedron_encode();
+ Vector2 res = octahedron_encode();
res.y = MAX(res.y, bias);
res.y = res.y * 0.5f + 0.5f;
res.y = sign >= 0.0f ? res.y : 1 - res.y;
diff --git a/core/math/vector3.h b/core/math/vector3.h
index 18943a820f..5d4e2c7d87 100644
--- a/core/math/vector3.h
+++ b/core/math/vector3.h
@@ -33,8 +33,8 @@
#include "core/error/error_macros.h"
#include "core/math/math_funcs.h"
+#include "core/string/ustring.h"
-class String;
struct Basis;
struct Vector2;
struct Vector3i;
@@ -512,9 +512,9 @@ void Vector3::zero() {
// slide returns the component of the vector along the given plane, specified by its normal vector.
Vector3 Vector3::slide(const Vector3 &p_normal) const {
#ifdef MATH_CHECKS
- ERR_FAIL_COND_V_MSG(!p_normal.is_normalized(), Vector3(), "The normal Vector3 must be normalized.");
+ ERR_FAIL_COND_V_MSG(!p_normal.is_normalized(), Vector3(), "The normal Vector3 " + p_normal.operator String() + " must be normalized.");
#endif
- return *this - p_normal * this->dot(p_normal);
+ return *this - p_normal * dot(p_normal);
}
Vector3 Vector3::bounce(const Vector3 &p_normal) const {
@@ -523,9 +523,9 @@ Vector3 Vector3::bounce(const Vector3 &p_normal) const {
Vector3 Vector3::reflect(const Vector3 &p_normal) const {
#ifdef MATH_CHECKS
- ERR_FAIL_COND_V_MSG(!p_normal.is_normalized(), Vector3(), "The normal Vector3 must be normalized.");
+ ERR_FAIL_COND_V_MSG(!p_normal.is_normalized(), Vector3(), "The normal Vector3 " + p_normal.operator String() + " must be normalized.");
#endif
- return 2.0f * p_normal * this->dot(p_normal) - *this;
+ return 2.0f * p_normal * dot(p_normal) - *this;
}
#endif // VECTOR3_H
diff --git a/core/object/class_db.h b/core/object/class_db.h
index 7a4ee1afa4..21243230de 100644
--- a/core/object/class_db.h
+++ b/core/object/class_db.h
@@ -188,7 +188,7 @@ public:
template <class T>
static void register_class(bool p_virtual = false) {
GLOBAL_LOCK_FUNCTION;
- static_assert(TypesAreSame<typename T::self_type, T>::value, "Class not declared properly, please use GDCLASS.");
+ static_assert(types_are_same_v<typename T::self_type, T>, "Class not declared properly, please use GDCLASS.");
T::initialize_class();
ClassInfo *t = classes.getptr(T::get_class_static());
ERR_FAIL_NULL(t);
@@ -203,7 +203,7 @@ public:
template <class T>
static void register_abstract_class() {
GLOBAL_LOCK_FUNCTION;
- static_assert(TypesAreSame<typename T::self_type, T>::value, "Class not declared properly, please use GDCLASS.");
+ static_assert(types_are_same_v<typename T::self_type, T>, "Class not declared properly, please use GDCLASS.");
T::initialize_class();
ClassInfo *t = classes.getptr(T::get_class_static());
ERR_FAIL_NULL(t);
@@ -216,7 +216,7 @@ public:
template <class T>
static void register_internal_class() {
GLOBAL_LOCK_FUNCTION;
- static_assert(TypesAreSame<typename T::self_type, T>::value, "Class not declared properly, please use GDCLASS.");
+ static_assert(types_are_same_v<typename T::self_type, T>, "Class not declared properly, please use GDCLASS.");
T::initialize_class();
ClassInfo *t = classes.getptr(T::get_class_static());
ERR_FAIL_NULL(t);
@@ -239,7 +239,7 @@ public:
template <class T>
static void register_custom_instance_class() {
GLOBAL_LOCK_FUNCTION;
- static_assert(TypesAreSame<typename T::self_type, T>::value, "Class not declared properly, please use GDCLASS.");
+ static_assert(types_are_same_v<typename T::self_type, T>, "Class not declared properly, please use GDCLASS.");
T::initialize_class();
ClassInfo *t = classes.getptr(T::get_class_static());
ERR_FAIL_NULL(t);
@@ -296,7 +296,7 @@ public:
argptrs[i] = &args[i];
}
MethodBind *bind = create_method_bind(p_method);
- if constexpr (std::is_same<typename member_function_traits<M>::return_type, Object *>::value) {
+ if constexpr (std::is_same_v<typename member_function_traits<M>::return_type, Object *>) {
bind->set_return_type_is_raw_object_ptr(true);
}
return bind_methodfi(METHOD_FLAGS_DEFAULT, bind, false, p_method_name, sizeof...(p_args) == 0 ? nullptr : (const Variant **)argptrs, sizeof...(p_args));
@@ -311,7 +311,7 @@ public:
}
MethodBind *bind = create_static_method_bind(p_method);
bind->set_instance_class(p_class);
- if constexpr (std::is_same<typename member_function_traits<M>::return_type, Object *>::value) {
+ if constexpr (std::is_same_v<typename member_function_traits<M>::return_type, Object *>) {
bind->set_return_type_is_raw_object_ptr(true);
}
return bind_methodfi(METHOD_FLAGS_DEFAULT, bind, false, p_method_name, sizeof...(p_args) == 0 ? nullptr : (const Variant **)argptrs, sizeof...(p_args));
@@ -325,7 +325,7 @@ public:
argptrs[i] = &args[i];
}
MethodBind *bind = create_method_bind(p_method);
- if constexpr (std::is_same<typename member_function_traits<M>::return_type, Object *>::value) {
+ if constexpr (std::is_same_v<typename member_function_traits<M>::return_type, Object *>) {
bind->set_return_type_is_raw_object_ptr(true);
}
return bind_methodfi(METHOD_FLAGS_DEFAULT, bind, true, p_method_name, sizeof...(p_args) == 0 ? nullptr : (const Variant **)argptrs, sizeof...(p_args));
@@ -340,7 +340,7 @@ public:
}
MethodBind *bind = create_static_method_bind(p_method);
bind->set_instance_class(p_class);
- if constexpr (std::is_same<typename member_function_traits<M>::return_type, Object *>::value) {
+ if constexpr (std::is_same_v<typename member_function_traits<M>::return_type, Object *>) {
bind->set_return_type_is_raw_object_ptr(true);
}
return bind_methodfi(METHOD_FLAGS_DEFAULT, bind, true, p_method_name, sizeof...(p_args) == 0 ? nullptr : (const Variant **)argptrs, sizeof...(p_args));
@@ -353,7 +353,7 @@ public:
MethodBind *bind = create_vararg_method_bind(p_method, p_info, p_return_nil_is_variant);
ERR_FAIL_NULL_V(bind, nullptr);
- if constexpr (std::is_same<typename member_function_traits<M>::return_type, Object *>::value) {
+ if constexpr (std::is_same_v<typename member_function_traits<M>::return_type, Object *>) {
bind->set_return_type_is_raw_object_ptr(true);
}
return _bind_vararg_method(bind, p_name, p_default_args, false);
@@ -366,7 +366,7 @@ public:
MethodBind *bind = create_vararg_method_bind(p_method, p_info, p_return_nil_is_variant);
ERR_FAIL_NULL_V(bind, nullptr);
- if constexpr (std::is_same<typename member_function_traits<M>::return_type, Object *>::value) {
+ if constexpr (std::is_same_v<typename member_function_traits<M>::return_type, Object *>) {
bind->set_return_type_is_raw_object_ptr(true);
}
return _bind_vararg_method(bind, p_name, p_default_args, true);
diff --git a/core/object/message_queue.cpp b/core/object/message_queue.cpp
index a394c957d0..83a19554dc 100644
--- a/core/object/message_queue.cpp
+++ b/core/object/message_queue.cpp
@@ -40,12 +40,12 @@
#ifdef DEV_ENABLED
// Includes safety checks to ensure that a queue set as a thread singleton override
// is only ever called from the thread it was set for.
-#define LOCK_MUTEX \
- if (this != MessageQueue::thread_singleton) { \
- DEV_ASSERT(!this->is_current_thread_override); \
- mutex.lock(); \
- } else { \
- DEV_ASSERT(this->is_current_thread_override); \
+#define LOCK_MUTEX \
+ if (this != MessageQueue::thread_singleton) { \
+ DEV_ASSERT(!is_current_thread_override); \
+ mutex.lock(); \
+ } else { \
+ DEV_ASSERT(is_current_thread_override); \
}
#else
#define LOCK_MUTEX \
diff --git a/core/object/object.cpp b/core/object/object.cpp
index 3901c4835d..cc33d0ab8a 100644
--- a/core/object/object.cpp
+++ b/core/object/object.cpp
@@ -1683,6 +1683,7 @@ void Object::_bind_methods() {
BIND_CONSTANT(NOTIFICATION_POSTINITIALIZE);
BIND_CONSTANT(NOTIFICATION_PREDELETE);
+ BIND_CONSTANT(NOTIFICATION_EXTENSION_RELOADED);
BIND_ENUM_CONSTANT(CONNECT_DEFERRED);
BIND_ENUM_CONSTANT(CONNECT_PERSIST);
diff --git a/core/os/keyboard.h b/core/os/keyboard.h
index 785972d31d..2051973336 100644
--- a/core/os/keyboard.h
+++ b/core/os/keyboard.h
@@ -260,6 +260,12 @@ enum class KeyModifierMask {
GROUP_SWITCH = (1 << 30)
};
+enum class KeyLocation {
+ UNSPECIFIED,
+ LEFT,
+ RIGHT
+};
+
// To avoid having unnecessary operators, only define the ones that are needed.
constexpr Key operator-(uint32_t a, Key b) {
diff --git a/core/os/memory.cpp b/core/os/memory.cpp
index 5f6216a5f1..32c316e58e 100644
--- a/core/os/memory.cpp
+++ b/core/os/memory.cpp
@@ -72,23 +72,23 @@ void *Memory::alloc_static(size_t p_bytes, bool p_pad_align) {
bool prepad = p_pad_align;
#endif
- void *mem = malloc(p_bytes + (prepad ? PAD_ALIGN : 0));
+ void *mem = malloc(p_bytes + (prepad ? DATA_OFFSET : 0));
ERR_FAIL_NULL_V(mem, nullptr);
alloc_count.increment();
if (prepad) {
- uint64_t *s = (uint64_t *)mem;
- *s = p_bytes;
-
uint8_t *s8 = (uint8_t *)mem;
+ uint64_t *s = (uint64_t *)(s8 + SIZE_OFFSET);
+ *s = p_bytes;
+
#ifdef DEBUG_ENABLED
uint64_t new_mem_usage = mem_usage.add(p_bytes);
max_usage.exchange_if_greater(new_mem_usage);
#endif
- return s8 + PAD_ALIGN;
+ return s8 + DATA_OFFSET;
} else {
return mem;
}
@@ -108,8 +108,8 @@ void *Memory::realloc_static(void *p_memory, size_t p_bytes, bool p_pad_align) {
#endif
if (prepad) {
- mem -= PAD_ALIGN;
- uint64_t *s = (uint64_t *)mem;
+ mem -= DATA_OFFSET;
+ uint64_t *s = (uint64_t *)(mem + SIZE_OFFSET);
#ifdef DEBUG_ENABLED
if (p_bytes > *s) {
@@ -126,14 +126,14 @@ void *Memory::realloc_static(void *p_memory, size_t p_bytes, bool p_pad_align) {
} else {
*s = p_bytes;
- mem = (uint8_t *)realloc(mem, p_bytes + PAD_ALIGN);
+ mem = (uint8_t *)realloc(mem, p_bytes + DATA_OFFSET);
ERR_FAIL_NULL_V(mem, nullptr);
- s = (uint64_t *)mem;
+ s = (uint64_t *)(mem + SIZE_OFFSET);
*s = p_bytes;
- return mem + PAD_ALIGN;
+ return mem + DATA_OFFSET;
}
} else {
mem = (uint8_t *)realloc(mem, p_bytes);
@@ -158,10 +158,10 @@ void Memory::free_static(void *p_ptr, bool p_pad_align) {
alloc_count.decrement();
if (prepad) {
- mem -= PAD_ALIGN;
+ mem -= DATA_OFFSET;
#ifdef DEBUG_ENABLED
- uint64_t *s = (uint64_t *)mem;
+ uint64_t *s = (uint64_t *)(mem + SIZE_OFFSET);
mem_usage.sub(*s);
#endif
diff --git a/core/os/memory.h b/core/os/memory.h
index a0524b0ea2..6f3f6fed39 100644
--- a/core/os/memory.h
+++ b/core/os/memory.h
@@ -38,10 +38,6 @@
#include <new>
#include <type_traits>
-#ifndef PAD_ALIGN
-#define PAD_ALIGN 16 //must always be greater than this at much
-#endif
-
class Memory {
#ifdef DEBUG_ENABLED
static SafeNumeric<uint64_t> mem_usage;
@@ -51,6 +47,17 @@ class Memory {
static SafeNumeric<uint64_t> alloc_count;
public:
+ // Alignment: ↓ max_align_t ↓ uint64_t ↓ max_align_t
+ // ┌─────────────────┬──┬────────────────┬──┬───────────...
+ // │ uint64_t │░░│ uint64_t │░░│ T[]
+ // │ alloc size │░░│ element count │░░│ data
+ // └─────────────────┴──┴────────────────┴──┴───────────...
+ // Offset: ↑ SIZE_OFFSET ↑ ELEMENT_OFFSET ↑ DATA_OFFSET
+
+ static constexpr size_t SIZE_OFFSET = 0;
+ static constexpr size_t ELEMENT_OFFSET = ((SIZE_OFFSET + sizeof(uint64_t)) % alignof(uint64_t) == 0) ? (SIZE_OFFSET + sizeof(uint64_t)) : ((SIZE_OFFSET + sizeof(uint64_t)) + alignof(uint64_t) - ((SIZE_OFFSET + sizeof(uint64_t)) % alignof(uint64_t)));
+ static constexpr size_t DATA_OFFSET = ((ELEMENT_OFFSET + sizeof(uint64_t)) % alignof(max_align_t) == 0) ? (ELEMENT_OFFSET + sizeof(uint64_t)) : ((ELEMENT_OFFSET + sizeof(uint64_t)) + alignof(max_align_t) - ((ELEMENT_OFFSET + sizeof(uint64_t)) % alignof(max_align_t)));
+
static void *alloc_static(size_t p_bytes, bool p_pad_align = false);
static void *realloc_static(void *p_memory, size_t p_bytes, bool p_pad_align = false);
static void free_static(void *p_ptr, bool p_pad_align = false);
@@ -105,7 +112,7 @@ void memdelete(T *p_class) {
if (!predelete_handler(p_class)) {
return; // doesn't want to be deleted
}
- if (!std::is_trivially_destructible<T>::value) {
+ if constexpr (!std::is_trivially_destructible_v<T>) {
p_class->~T();
}
@@ -117,7 +124,7 @@ void memdelete_allocator(T *p_class) {
if (!predelete_handler(p_class)) {
return; // doesn't want to be deleted
}
- if (!std::is_trivially_destructible<T>::value) {
+ if constexpr (!std::is_trivially_destructible_v<T>) {
p_class->~T();
}
@@ -133,6 +140,10 @@ void memdelete_allocator(T *p_class) {
#define memnew_arr(m_class, m_count) memnew_arr_template<m_class>(m_count)
+_FORCE_INLINE_ uint64_t *_get_element_count_ptr(uint8_t *p_ptr) {
+ return (uint64_t *)(p_ptr - Memory::DATA_OFFSET + Memory::ELEMENT_OFFSET);
+}
+
template <typename T>
T *memnew_arr_template(size_t p_elements) {
if (p_elements == 0) {
@@ -142,12 +153,14 @@ T *memnew_arr_template(size_t p_elements) {
same strategy used by std::vector, and the Vector class, so it should be safe.*/
size_t len = sizeof(T) * p_elements;
- uint64_t *mem = (uint64_t *)Memory::alloc_static(len, true);
+ uint8_t *mem = (uint8_t *)Memory::alloc_static(len, true);
T *failptr = nullptr; //get rid of a warning
ERR_FAIL_NULL_V(mem, failptr);
- *(mem - 1) = p_elements;
- if (!std::is_trivially_constructible<T>::value) {
+ uint64_t *_elem_count_ptr = _get_element_count_ptr(mem);
+ *(_elem_count_ptr) = p_elements;
+
+ if constexpr (!std::is_trivially_constructible_v<T>) {
T *elems = (T *)mem;
/* call operator new */
@@ -166,16 +179,18 @@ T *memnew_arr_template(size_t p_elements) {
template <typename T>
size_t memarr_len(const T *p_class) {
- uint64_t *ptr = (uint64_t *)p_class;
- return *(ptr - 1);
+ uint8_t *ptr = (uint8_t *)p_class;
+ uint64_t *_elem_count_ptr = _get_element_count_ptr(ptr);
+ return *(_elem_count_ptr);
}
template <typename T>
void memdelete_arr(T *p_class) {
- uint64_t *ptr = (uint64_t *)p_class;
+ uint8_t *ptr = (uint8_t *)p_class;
- if (!std::is_trivially_destructible<T>::value) {
- uint64_t elem_count = *(ptr - 1);
+ if constexpr (!std::is_trivially_destructible_v<T>) {
+ uint64_t *_elem_count_ptr = _get_element_count_ptr(ptr);
+ uint64_t elem_count = *(_elem_count_ptr);
for (uint64_t i = 0; i < elem_count; i++) {
p_class[i].~T();
diff --git a/core/os/mutex.h b/core/os/mutex.h
index 69f494d9cd..a4eab0cd86 100644
--- a/core/os/mutex.h
+++ b/core/os/mutex.h
@@ -70,56 +70,6 @@ public:
}
};
-// A very special kind of mutex, used in scenarios where these
-// requirements hold at the same time:
-// - Must be used with a condition variable (only binary mutexes are suitable).
-// - Must have recursive semnantics (or simulate, as this one does).
-// The implementation keeps the lock count in TS. Therefore, only
-// one object of each version of the template can exists; hence the Tag argument.
-// Tags must be unique across the Godot codebase.
-// Also, don't forget to declare the thread_local variable on each use.
-template <int Tag>
-class SafeBinaryMutex {
- friend class MutexLock<SafeBinaryMutex>;
-
- using StdMutexType = THREADING_NAMESPACE::mutex;
-
- mutable THREADING_NAMESPACE::mutex mutex;
- static thread_local uint32_t count;
-
-public:
- _ALWAYS_INLINE_ void lock() const {
- if (++count == 1) {
- mutex.lock();
- }
- }
-
- _ALWAYS_INLINE_ void unlock() const {
- DEV_ASSERT(count);
- if (--count == 0) {
- mutex.unlock();
- }
- }
-
- _ALWAYS_INLINE_ bool try_lock() const {
- if (count) {
- count++;
- return true;
- } else {
- if (mutex.try_lock()) {
- count++;
- return true;
- } else {
- return false;
- }
- }
- }
-
- ~SafeBinaryMutex() {
- DEV_ASSERT(!count);
- }
-};
-
template <class MutexT>
class MutexLock {
friend class ConditionVariable;
@@ -131,24 +81,6 @@ public:
lock(p_mutex.mutex) {}
};
-// This specialization is needed so manual locking and MutexLock can be used
-// at the same time on a SafeBinaryMutex.
-template <int Tag>
-class MutexLock<SafeBinaryMutex<Tag>> {
- friend class ConditionVariable;
-
- THREADING_NAMESPACE::unique_lock<THREADING_NAMESPACE::mutex> lock;
-
-public:
- _ALWAYS_INLINE_ explicit MutexLock(const SafeBinaryMutex<Tag> &p_mutex) :
- lock(p_mutex.mutex) {
- SafeBinaryMutex<Tag>::count++;
- };
- _ALWAYS_INLINE_ ~MutexLock() {
- SafeBinaryMutex<Tag>::count--;
- };
-};
-
using Mutex = MutexImpl<THREADING_NAMESPACE::recursive_mutex>; // Recursive, for general use
using BinaryMutex = MutexImpl<THREADING_NAMESPACE::mutex>; // Non-recursive, handle with care
@@ -168,24 +100,12 @@ public:
bool try_lock() const { return true; }
};
-template <int Tag>
-class SafeBinaryMutex : public MutexImpl {
- static thread_local uint32_t count;
-};
-
template <class MutexT>
class MutexLock {
public:
MutexLock(const MutexT &p_mutex) {}
};
-template <int Tag>
-class MutexLock<SafeBinaryMutex<Tag>> {
-public:
- MutexLock(const SafeBinaryMutex<Tag> &p_mutex) {}
- ~MutexLock() {}
-};
-
using Mutex = MutexImpl;
using BinaryMutex = MutexImpl;
diff --git a/core/os/safe_binary_mutex.h b/core/os/safe_binary_mutex.h
new file mode 100644
index 0000000000..1e98cc074c
--- /dev/null
+++ b/core/os/safe_binary_mutex.h
@@ -0,0 +1,124 @@
+/**************************************************************************/
+/* safe_binary_mutex.h */
+/**************************************************************************/
+/* This file is part of: */
+/* GODOT ENGINE */
+/* https://godotengine.org */
+/**************************************************************************/
+/* Copyright (c) 2014-present Godot Engine contributors (see AUTHORS.md). */
+/* Copyright (c) 2007-2014 Juan Linietsky, Ariel Manzur. */
+/* */
+/* 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 SAFE_BINARY_MUTEX_H
+#define SAFE_BINARY_MUTEX_H
+
+#include "core/error/error_macros.h"
+#include "core/os/mutex.h"
+#include "core/typedefs.h"
+
+#ifdef THREADS_ENABLED
+
+// A very special kind of mutex, used in scenarios where these
+// requirements hold at the same time:
+// - Must be used with a condition variable (only binary mutexes are suitable).
+// - Must have recursive semnantics (or simulate, as this one does).
+// The implementation keeps the lock count in TS. Therefore, only
+// one object of each version of the template can exists; hence the Tag argument.
+// Tags must be unique across the Godot codebase.
+// Also, don't forget to declare the thread_local variable on each use.
+template <int Tag>
+class SafeBinaryMutex {
+ friend class MutexLock<SafeBinaryMutex>;
+
+ using StdMutexType = THREADING_NAMESPACE::mutex;
+
+ mutable THREADING_NAMESPACE::mutex mutex;
+ static thread_local uint32_t count;
+
+public:
+ _ALWAYS_INLINE_ void lock() const {
+ if (++count == 1) {
+ mutex.lock();
+ }
+ }
+
+ _ALWAYS_INLINE_ void unlock() const {
+ DEV_ASSERT(count);
+ if (--count == 0) {
+ mutex.unlock();
+ }
+ }
+
+ _ALWAYS_INLINE_ bool try_lock() const {
+ if (count) {
+ count++;
+ return true;
+ } else {
+ if (mutex.try_lock()) {
+ count++;
+ return true;
+ } else {
+ return false;
+ }
+ }
+ }
+
+ ~SafeBinaryMutex() {
+ DEV_ASSERT(!count);
+ }
+};
+
+// This specialization is needed so manual locking and MutexLock can be used
+// at the same time on a SafeBinaryMutex.
+template <int Tag>
+class MutexLock<SafeBinaryMutex<Tag>> {
+ friend class ConditionVariable;
+
+ THREADING_NAMESPACE::unique_lock<THREADING_NAMESPACE::mutex> lock;
+
+public:
+ _ALWAYS_INLINE_ explicit MutexLock(const SafeBinaryMutex<Tag> &p_mutex) :
+ lock(p_mutex.mutex) {
+ SafeBinaryMutex<Tag>::count++;
+ };
+ _ALWAYS_INLINE_ ~MutexLock() {
+ SafeBinaryMutex<Tag>::count--;
+ };
+};
+
+#else // No threads.
+
+template <int Tag>
+class SafeBinaryMutex : public MutexImpl {
+ static thread_local uint32_t count;
+};
+
+template <int Tag>
+class MutexLock<SafeBinaryMutex<Tag>> {
+public:
+ MutexLock(const SafeBinaryMutex<Tag> &p_mutex) {}
+ ~MutexLock() {}
+};
+
+#endif // THREADS_ENABLED
+
+#endif // SAFE_BINARY_MUTEX_H
diff --git a/core/os/spin_lock.h b/core/os/spin_lock.h
index 93ea782b60..d386cd5890 100644
--- a/core/os/spin_lock.h
+++ b/core/os/spin_lock.h
@@ -33,6 +33,25 @@
#include "core/typedefs.h"
+#if defined(__APPLE__)
+
+#include <os/lock.h>
+
+class SpinLock {
+ mutable os_unfair_lock _lock = OS_UNFAIR_LOCK_INIT;
+
+public:
+ _ALWAYS_INLINE_ void lock() const {
+ os_unfair_lock_lock(&_lock);
+ }
+
+ _ALWAYS_INLINE_ void unlock() const {
+ os_unfair_lock_unlock(&_lock);
+ }
+};
+
+#else
+
#include <atomic>
class SpinLock {
@@ -49,4 +68,6 @@ public:
}
};
+#endif // __APPLE__
+
#endif // SPIN_LOCK_H
diff --git a/core/string/translation_po.cpp b/core/string/translation_po.cpp
index 6b1595174a..06fd4717d7 100644
--- a/core/string/translation_po.cpp
+++ b/core/string/translation_po.cpp
@@ -41,8 +41,8 @@ void TranslationPO::print_translation_map() {
return;
}
- file->store_line("NPlural : " + String::num_int64(this->get_plural_forms()));
- file->store_line("Plural rule : " + this->get_plural_rule());
+ file->store_line("NPlural : " + String::num_int64(get_plural_forms()));
+ file->store_line("Plural rule : " + get_plural_rule());
file->store_line("");
List<StringName> context_l;
diff --git a/core/string/ustring.cpp b/core/string/ustring.cpp
index 6afe28a6a7..d094184c4b 100644
--- a/core/string/ustring.cpp
+++ b/core/string/ustring.cpp
@@ -302,7 +302,7 @@ void String::copy_from(const char *p_cstr) {
resize(len + 1); // include 0
- char32_t *dst = this->ptrw();
+ char32_t *dst = ptrw();
for (size_t i = 0; i <= len; i++) {
#if CHAR_MIN == 0
@@ -339,7 +339,7 @@ void String::copy_from(const char *p_cstr, const int p_clip_to) {
resize(len + 1); // include 0
- char32_t *dst = this->ptrw();
+ char32_t *dst = ptrw();
for (int i = 0; i < len; i++) {
#if CHAR_MIN == 0
@@ -1043,7 +1043,7 @@ String String::_camelcase_to_underscore() const {
String new_string;
int start_index = 0;
- for (int i = 1; i < this->size(); i++) {
+ for (int i = 1; i < size(); i++) {
bool is_prev_upper = is_ascii_upper_case(cstr[i - 1]);
bool is_prev_lower = is_ascii_lower_case(cstr[i - 1]);
bool is_prev_digit = is_digit(cstr[i - 1]);
@@ -1053,7 +1053,7 @@ String String::_camelcase_to_underscore() const {
bool is_curr_digit = is_digit(cstr[i]);
bool is_next_lower = false;
- if (i + 1 < this->size()) {
+ if (i + 1 < size()) {
is_next_lower = is_ascii_lower_case(cstr[i + 1]);
}
@@ -1063,17 +1063,17 @@ String String::_camelcase_to_underscore() const {
const bool cond_d = (is_prev_upper || is_prev_lower) && is_curr_digit; // A2, a2
if (cond_a || cond_b || cond_c || cond_d) {
- new_string += this->substr(start_index, i - start_index) + "_";
+ new_string += substr(start_index, i - start_index) + "_";
start_index = i;
}
}
- new_string += this->substr(start_index, this->size() - start_index);
+ new_string += substr(start_index, size() - start_index);
return new_string.to_lower();
}
String String::capitalize() const {
- String aux = this->_camelcase_to_underscore().replace("_", " ").strip_edges();
+ String aux = _camelcase_to_underscore().replace("_", " ").strip_edges();
String cap;
for (int i = 0; i < aux.get_slice_count(" "); i++) {
String slice = aux.get_slicec(' ', i);
@@ -1090,7 +1090,7 @@ String String::capitalize() const {
}
String String::to_camel_case() const {
- String s = this->to_pascal_case();
+ String s = to_pascal_case();
if (!s.is_empty()) {
s[0] = _find_lower(s[0]);
}
@@ -1098,11 +1098,11 @@ String String::to_camel_case() const {
}
String String::to_pascal_case() const {
- return this->capitalize().replace(" ", "");
+ return capitalize().replace(" ", "");
}
String String::to_snake_case() const {
- return this->_camelcase_to_underscore().replace(" ", "_").strip_edges();
+ return _camelcase_to_underscore().replace(" ", "_").strip_edges();
}
String String::get_with_code_lines() const {
@@ -1185,7 +1185,7 @@ String String::get_slicec(char32_t p_splitter, int p_slice) const {
return String();
}
- const char32_t *c = this->ptr();
+ const char32_t *c = ptr();
int i = 0;
int prev = 0;
int count = 0;
@@ -3516,7 +3516,7 @@ bool String::matchn(const String &p_wildcard) const {
}
String String::format(const Variant &values, const String &placeholder) const {
- String new_string = String(this->ptr());
+ String new_string = String(ptr());
if (values.get_type() == Variant::ARRAY) {
Array values_arr = values;
@@ -4467,7 +4467,7 @@ bool String::is_valid_float() const {
String String::path_to_file(const String &p_path) const {
// Don't get base dir for src, this is expected to be a dir already.
- String src = this->replace("\\", "/");
+ String src = replace("\\", "/");
String dst = p_path.replace("\\", "/").get_base_dir();
String rel = src.path_to(dst);
if (rel == dst) { // failed
@@ -4478,7 +4478,7 @@ String String::path_to_file(const String &p_path) const {
}
String String::path_to(const String &p_path) const {
- String src = this->replace("\\", "/");
+ String src = replace("\\", "/");
String dst = p_path.replace("\\", "/");
if (!src.ends_with("/")) {
src += "/";
diff --git a/core/templates/cowdata.h b/core/templates/cowdata.h
index d43cf8107f..466658951e 100644
--- a/core/templates/cowdata.h
+++ b/core/templates/cowdata.h
@@ -46,7 +46,7 @@ class CharString;
template <class T, class V>
class VMap;
-SAFE_NUMERIC_TYPE_PUN_GUARANTEES(uint64_t)
+static_assert(std::is_trivially_destructible_v<std::atomic<uint64_t>>);
// Silence a false positive warning (see GH-52119).
#if defined(__GNUC__) && !defined(__clang__)
@@ -89,18 +89,39 @@ private:
return ++x;
}
- static constexpr USize ALLOC_PAD = sizeof(USize) * 2; // For size and atomic refcount.
+ // Alignment: ↓ max_align_t ↓ USize ↓ max_align_t
+ // ┌────────────────────┬──┬─────────────┬──┬───────────...
+ // │ SafeNumeric<USize> │░░│ USize │░░│ T[]
+ // │ ref. count │░░│ data size │░░│ data
+ // └────────────────────┴──┴─────────────┴──┴───────────...
+ // Offset: ↑ REF_COUNT_OFFSET ↑ SIZE_OFFSET ↑ DATA_OFFSET
+
+ static constexpr size_t REF_COUNT_OFFSET = 0;
+ static constexpr size_t SIZE_OFFSET = ((REF_COUNT_OFFSET + sizeof(SafeNumeric<USize>)) % alignof(USize) == 0) ? (REF_COUNT_OFFSET + sizeof(SafeNumeric<USize>)) : ((REF_COUNT_OFFSET + sizeof(SafeNumeric<USize>)) + alignof(USize) - ((REF_COUNT_OFFSET + sizeof(SafeNumeric<USize>)) % alignof(USize)));
+ static constexpr size_t DATA_OFFSET = ((SIZE_OFFSET + sizeof(USize)) % alignof(max_align_t) == 0) ? (SIZE_OFFSET + sizeof(USize)) : ((SIZE_OFFSET + sizeof(USize)) + alignof(max_align_t) - ((SIZE_OFFSET + sizeof(USize)) % alignof(max_align_t)));
mutable T *_ptr = nullptr;
// internal helpers
+ static _FORCE_INLINE_ SafeNumeric<USize> *_get_refcount_ptr(uint8_t *p_ptr) {
+ return (SafeNumeric<USize> *)(p_ptr + REF_COUNT_OFFSET);
+ }
+
+ static _FORCE_INLINE_ USize *_get_size_ptr(uint8_t *p_ptr) {
+ return (USize *)(p_ptr + SIZE_OFFSET);
+ }
+
+ static _FORCE_INLINE_ T *_get_data_ptr(uint8_t *p_ptr) {
+ return (T *)(p_ptr + DATA_OFFSET);
+ }
+
_FORCE_INLINE_ SafeNumeric<USize> *_get_refcount() const {
if (!_ptr) {
return nullptr;
}
- return reinterpret_cast<SafeNumeric<USize> *>(_ptr) - 2;
+ return (SafeNumeric<USize> *)((uint8_t *)_ptr - DATA_OFFSET + REF_COUNT_OFFSET);
}
_FORCE_INLINE_ USize *_get_size() const {
@@ -108,7 +129,7 @@ private:
return nullptr;
}
- return reinterpret_cast<USize *>(_ptr) - 1;
+ return (USize *)((uint8_t *)_ptr - DATA_OFFSET + SIZE_OFFSET);
}
_FORCE_INLINE_ USize _get_alloc_size(USize p_elements) const {
@@ -233,7 +254,7 @@ void CowData<T>::_unref(void *p_data) {
}
// clean up
- if (!std::is_trivially_destructible<T>::value) {
+ if constexpr (!std::is_trivially_destructible_v<T>) {
USize *count = _get_size();
T *data = (T *)(count + 1);
@@ -244,7 +265,7 @@ void CowData<T>::_unref(void *p_data) {
}
// free mem
- Memory::free_static(((uint8_t *)p_data) - ALLOC_PAD, false);
+ Memory::free_static(((uint8_t *)p_data) - DATA_OFFSET, false);
}
template <class T>
@@ -260,26 +281,27 @@ typename CowData<T>::USize CowData<T>::_copy_on_write() {
/* in use by more than me */
USize current_size = *_get_size();
- USize *mem_new = (USize *)Memory::alloc_static(_get_alloc_size(current_size) + ALLOC_PAD, false);
- mem_new += 2;
+ uint8_t *mem_new = (uint8_t *)Memory::alloc_static(_get_alloc_size(current_size) + DATA_OFFSET, false);
+ ERR_FAIL_NULL_V(mem_new, 0);
- new (mem_new - 2) SafeNumeric<USize>(1); //refcount
- *(mem_new - 1) = current_size; //size
+ SafeNumeric<USize> *_refc_ptr = _get_refcount_ptr(mem_new);
+ USize *_size_ptr = _get_size_ptr(mem_new);
+ T *_data_ptr = _get_data_ptr(mem_new);
- T *_data = (T *)(mem_new);
+ new (_refc_ptr) SafeNumeric<USize>(1); //refcount
+ *(_size_ptr) = current_size; //size
// initialize new elements
- if (std::is_trivially_copyable<T>::value) {
- memcpy(mem_new, _ptr, current_size * sizeof(T));
-
+ if constexpr (std::is_trivially_copyable_v<T>) {
+ memcpy((uint8_t *)_data_ptr, _ptr, current_size * sizeof(T));
} else {
for (USize i = 0; i < current_size; i++) {
- memnew_placement(&_data[i], T(_ptr[i]));
+ memnew_placement(&_data_ptr[i], T(_ptr[i]));
}
}
_unref(_ptr);
- _ptr = _data;
+ _ptr = _data_ptr;
rc = 1;
}
@@ -315,27 +337,34 @@ Error CowData<T>::resize(Size p_size) {
if (alloc_size != current_alloc_size) {
if (current_size == 0) {
// alloc from scratch
- USize *ptr = (USize *)Memory::alloc_static(alloc_size + ALLOC_PAD, false);
- ptr += 2;
- ERR_FAIL_NULL_V(ptr, ERR_OUT_OF_MEMORY);
- *(ptr - 1) = 0; //size, currently none
- new (ptr - 2) SafeNumeric<USize>(1); //refcount
+ uint8_t *mem_new = (uint8_t *)Memory::alloc_static(alloc_size + DATA_OFFSET, false);
+ ERR_FAIL_NULL_V(mem_new, ERR_OUT_OF_MEMORY);
+
+ SafeNumeric<USize> *_refc_ptr = _get_refcount_ptr(mem_new);
+ USize *_size_ptr = _get_size_ptr(mem_new);
+ T *_data_ptr = _get_data_ptr(mem_new);
- _ptr = (T *)ptr;
+ new (_refc_ptr) SafeNumeric<USize>(1); //refcount
+ *(_size_ptr) = 0; //size, currently none
+
+ _ptr = _data_ptr;
} else {
- USize *_ptrnew = (USize *)Memory::realloc_static(((uint8_t *)_ptr) - ALLOC_PAD, alloc_size + ALLOC_PAD, false);
- ERR_FAIL_NULL_V(_ptrnew, ERR_OUT_OF_MEMORY);
- _ptrnew += 2;
- new (_ptrnew - 2) SafeNumeric<USize>(rc); //refcount
+ uint8_t *mem_new = (uint8_t *)Memory::realloc_static(((uint8_t *)_ptr) - DATA_OFFSET, alloc_size + DATA_OFFSET, false);
+ ERR_FAIL_NULL_V(mem_new, ERR_OUT_OF_MEMORY);
+
+ SafeNumeric<USize> *_refc_ptr = _get_refcount_ptr(mem_new);
+ T *_data_ptr = _get_data_ptr(mem_new);
- _ptr = (T *)(_ptrnew);
+ new (_refc_ptr) SafeNumeric<USize>(rc); //refcount
+
+ _ptr = _data_ptr;
}
}
// construct the newly created elements
- if (!std::is_trivially_constructible<T>::value) {
+ if constexpr (!std::is_trivially_constructible_v<T>) {
for (Size i = *_get_size(); i < p_size; i++) {
memnew_placement(&_ptr[i], T);
}
@@ -346,7 +375,7 @@ Error CowData<T>::resize(Size p_size) {
*_get_size() = p_size;
} else if (p_size < current_size) {
- if (!std::is_trivially_destructible<T>::value) {
+ if constexpr (!std::is_trivially_destructible_v<T>) {
// deinitialize no longer needed elements
for (USize i = p_size; i < *_get_size(); i++) {
T *t = &_ptr[i];
@@ -355,12 +384,15 @@ Error CowData<T>::resize(Size p_size) {
}
if (alloc_size != current_alloc_size) {
- USize *_ptrnew = (USize *)Memory::realloc_static(((uint8_t *)_ptr) - ALLOC_PAD, alloc_size + ALLOC_PAD, false);
- ERR_FAIL_NULL_V(_ptrnew, ERR_OUT_OF_MEMORY);
- _ptrnew += 2;
- new (_ptrnew - 2) SafeNumeric<USize>(rc); //refcount
+ uint8_t *mem_new = (uint8_t *)Memory::realloc_static(((uint8_t *)_ptr) - DATA_OFFSET, alloc_size + DATA_OFFSET, false);
+ ERR_FAIL_NULL_V(mem_new, ERR_OUT_OF_MEMORY);
+
+ SafeNumeric<USize> *_refc_ptr = _get_refcount_ptr(mem_new);
+ T *_data_ptr = _get_data_ptr(mem_new);
+
+ new (_refc_ptr) SafeNumeric<USize>(rc); //refcount
- _ptr = (T *)(_ptrnew);
+ _ptr = _data_ptr;
}
*_get_size() = p_size;
diff --git a/core/templates/local_vector.h b/core/templates/local_vector.h
index b454821a8f..17ddbf6161 100644
--- a/core/templates/local_vector.h
+++ b/core/templates/local_vector.h
@@ -64,7 +64,7 @@ public:
CRASH_COND_MSG(!data, "Out of memory");
}
- if constexpr (!std::is_trivially_constructible<T>::value && !force_trivial) {
+ if constexpr (!std::is_trivially_constructible_v<T> && !force_trivial) {
memnew_placement(&data[count++], T(p_elem));
} else {
data[count++] = p_elem;
@@ -77,7 +77,7 @@ public:
for (U i = p_index; i < count; i++) {
data[i] = data[i + 1];
}
- if constexpr (!std::is_trivially_destructible<T>::value && !force_trivial) {
+ if constexpr (!std::is_trivially_destructible_v<T> && !force_trivial) {
data[count].~T();
}
}
@@ -90,7 +90,7 @@ public:
if (count > p_index) {
data[p_index] = data[count];
}
- if constexpr (!std::is_trivially_destructible<T>::value && !force_trivial) {
+ if constexpr (!std::is_trivially_destructible_v<T> && !force_trivial) {
data[count].~T();
}
}
@@ -133,7 +133,7 @@ public:
_FORCE_INLINE_ U size() const { return count; }
void resize(U p_size) {
if (p_size < count) {
- if constexpr (!std::is_trivially_destructible<T>::value && !force_trivial) {
+ if constexpr (!std::is_trivially_destructible_v<T> && !force_trivial) {
for (U i = p_size; i < count; i++) {
data[i].~T();
}
@@ -145,7 +145,7 @@ public:
data = (T *)memrealloc(data, capacity * sizeof(T));
CRASH_COND_MSG(!data, "Out of memory");
}
- if constexpr (!std::is_trivially_constructible<T>::value && !force_trivial) {
+ if constexpr (!std::is_trivially_constructible_v<T> && !force_trivial) {
for (U i = count; i < p_size; i++) {
memnew_placement(&data[i], T);
}
diff --git a/core/templates/paged_allocator.h b/core/templates/paged_allocator.h
index d880eae0c3..48110d37e5 100644
--- a/core/templates/paged_allocator.h
+++ b/core/templates/paged_allocator.h
@@ -101,7 +101,7 @@ public:
private:
void _reset(bool p_allow_unfreed) {
- if (!p_allow_unfreed || !std::is_trivially_destructible<T>::value) {
+ if (!p_allow_unfreed || !std::is_trivially_destructible_v<T>) {
ERR_FAIL_COND(allocs_available < pages_allocated * page_size);
}
if (pages_allocated) {
diff --git a/core/templates/paged_array.h b/core/templates/paged_array.h
index 69a792958a..21053dd033 100644
--- a/core/templates/paged_array.h
+++ b/core/templates/paged_array.h
@@ -202,7 +202,7 @@ public:
uint32_t page = count >> page_size_shift;
uint32_t offset = count & page_size_mask;
- if (!std::is_trivially_constructible<T>::value) {
+ if constexpr (!std::is_trivially_constructible_v<T>) {
memnew_placement(&page_data[page][offset], T(p_value));
} else {
page_data[page][offset] = p_value;
@@ -214,7 +214,7 @@ public:
_FORCE_INLINE_ void pop_back() {
ERR_FAIL_COND(count == 0);
- if (!std::is_trivially_destructible<T>::value) {
+ if constexpr (!std::is_trivially_destructible_v<T>) {
uint32_t page = (count - 1) >> page_size_shift;
uint32_t offset = (count - 1) & page_size_mask;
page_data[page][offset].~T();
@@ -229,9 +229,15 @@ public:
count--;
}
+ void remove_at_unordered(uint64_t p_index) {
+ ERR_FAIL_UNSIGNED_INDEX(p_index, count);
+ (*this)[p_index] = (*this)[count - 1];
+ pop_back();
+ }
+
void clear() {
//destruct if needed
- if (!std::is_trivially_destructible<T>::value) {
+ if constexpr (!std::is_trivially_destructible_v<T>) {
for (uint64_t i = 0; i < count; i++) {
uint32_t page = i >> page_size_shift;
uint32_t offset = i & page_size_mask;
@@ -312,13 +318,13 @@ public:
uint32_t to_copy = MIN(page_size - new_remainder, remainder);
for (uint32_t i = 0; i < to_copy; i++) {
- if (!std::is_trivially_constructible<T>::value) {
+ if constexpr (!std::is_trivially_constructible_v<T>) {
memnew_placement(&dst_page[i + new_remainder], T(remainder_page[i + remainder - to_copy]));
} else {
dst_page[i + new_remainder] = remainder_page[i + remainder - to_copy];
}
- if (!std::is_trivially_destructible<T>::value) {
+ if constexpr (!std::is_trivially_destructible_v<T>) {
remainder_page[i + remainder - to_copy].~T();
}
}
diff --git a/core/templates/safe_refcount.h b/core/templates/safe_refcount.h
index 20fb0c6501..7bbceadc8d 100644
--- a/core/templates/safe_refcount.h
+++ b/core/templates/safe_refcount.h
@@ -54,7 +54,7 @@
#define SAFE_NUMERIC_TYPE_PUN_GUARANTEES(m_type) \
static_assert(sizeof(SafeNumeric<m_type>) == sizeof(m_type)); \
static_assert(alignof(SafeNumeric<m_type>) == alignof(m_type)); \
- static_assert(std::is_trivially_destructible<std::atomic<m_type>>::value);
+ static_assert(std::is_trivially_destructible_v<std::atomic<m_type>>);
#define SAFE_FLAG_TYPE_PUN_GUARANTEES \
static_assert(sizeof(SafeFlag) == sizeof(bool)); \
static_assert(alignof(SafeFlag) == alignof(bool));
diff --git a/core/typedefs.h b/core/typedefs.h
index 8b04960b9a..8807ee3c99 100644
--- a/core/typedefs.h
+++ b/core/typedefs.h
@@ -93,6 +93,7 @@
#undef OK
#undef CONNECT_DEFERRED // override from Windows SDK, clashes with Object enum
#undef MemoryBarrier
+#undef MONO_FONT
#endif
// Make room for our constexpr's below by overriding potential system-specific macros.
diff --git a/core/variant/binder_common.h b/core/variant/binder_common.h
index 34b54f1d00..a44b938395 100644
--- a/core/variant/binder_common.h
+++ b/core/variant/binder_common.h
@@ -51,7 +51,7 @@ template <class T>
struct VariantCaster {
static _FORCE_INLINE_ T cast(const Variant &p_variant) {
using TStripped = std::remove_pointer_t<T>;
- if constexpr (std::is_base_of<Object, TStripped>::value) {
+ if constexpr (std::is_base_of_v<Object, TStripped>) {
return Object::cast_to<TStripped>(p_variant);
} else {
return p_variant;
@@ -63,7 +63,7 @@ template <class T>
struct VariantCaster<T &> {
static _FORCE_INLINE_ T cast(const Variant &p_variant) {
using TStripped = std::remove_pointer_t<T>;
- if constexpr (std::is_base_of<Object, TStripped>::value) {
+ if constexpr (std::is_base_of_v<Object, TStripped>) {
return Object::cast_to<TStripped>(p_variant);
} else {
return p_variant;
@@ -75,7 +75,7 @@ template <class T>
struct VariantCaster<const T &> {
static _FORCE_INLINE_ T cast(const Variant &p_variant) {
using TStripped = std::remove_pointer_t<T>;
- if constexpr (std::is_base_of<Object, TStripped>::value) {
+ if constexpr (std::is_base_of_v<Object, TStripped>) {
return Object::cast_to<TStripped>(p_variant);
} else {
return p_variant;
@@ -176,6 +176,7 @@ VARIANT_ENUM_CAST(Variant::Operator);
VARIANT_ENUM_CAST(Key);
VARIANT_BITFIELD_CAST(KeyModifierMask);
+VARIANT_ENUM_CAST(KeyLocation);
static inline Key &operator|=(Key &a, BitField<KeyModifierMask> b) {
a = static_cast<Key>(static_cast<int>(a) | static_cast<int>(b.operator int64_t()));
@@ -225,7 +226,7 @@ template <typename T>
struct VariantObjectClassChecker {
static _FORCE_INLINE_ bool check(const Variant &p_variant) {
using TStripped = std::remove_pointer_t<T>;
- if constexpr (std::is_base_of<Object, TStripped>::value) {
+ if constexpr (std::is_base_of_v<Object, TStripped>) {
Object *obj = p_variant;
return Object::cast_to<TStripped>(p_variant) || !obj;
} else {
diff --git a/core/variant/dictionary.cpp b/core/variant/dictionary.cpp
index 8b61a8993a..9f65a73c6f 100644
--- a/core/variant/dictionary.cpp
+++ b/core/variant/dictionary.cpp
@@ -251,7 +251,7 @@ void Dictionary::clear() {
void Dictionary::merge(const Dictionary &p_dictionary, bool p_overwrite) {
for (const KeyValue<Variant, Variant> &E : p_dictionary._p->variant_map) {
if (p_overwrite || !has(E.key)) {
- this->operator[](E.key) = E.value;
+ operator[](E.key) = E.value;
}
}
}
diff --git a/core/variant/type_info.h b/core/variant/type_info.h
index c1f2f86a96..49c4db8229 100644
--- a/core/variant/type_info.h
+++ b/core/variant/type_info.h
@@ -43,14 +43,10 @@ struct EnableIf<false, T> {
};
template <typename, typename>
-struct TypesAreSame {
- static bool const value = false;
-};
+inline constexpr bool types_are_same_v = false;
-template <typename A>
-struct TypesAreSame<A, A> {
- static bool const value = true;
-};
+template <typename T>
+inline constexpr bool types_are_same_v<T, T> = true;
template <typename B, typename D>
struct TypeInherits {
@@ -60,7 +56,7 @@ struct TypeInherits {
static char (&test(...))[2];
static bool const value = sizeof(test(get_d())) == sizeof(char) &&
- !TypesAreSame<B volatile const, void volatile const>::value;
+ !types_are_same_v<B volatile const, void volatile const>;
};
namespace GodotTypeInfo {
diff --git a/core/variant/typed_array.h b/core/variant/typed_array.h
index 037c5c7c2e..24da31af16 100644
--- a/core/variant/typed_array.h
+++ b/core/variant/typed_array.h
@@ -120,15 +120,15 @@ MAKE_TYPED_ARRAY(Callable, Variant::CALLABLE)
MAKE_TYPED_ARRAY(Signal, Variant::SIGNAL)
MAKE_TYPED_ARRAY(Dictionary, Variant::DICTIONARY)
MAKE_TYPED_ARRAY(Array, Variant::ARRAY)
-MAKE_TYPED_ARRAY(Vector<uint8_t>, Variant::PACKED_BYTE_ARRAY)
-MAKE_TYPED_ARRAY(Vector<int32_t>, Variant::PACKED_INT32_ARRAY)
-MAKE_TYPED_ARRAY(Vector<int64_t>, Variant::PACKED_INT64_ARRAY)
-MAKE_TYPED_ARRAY(Vector<float>, Variant::PACKED_FLOAT32_ARRAY)
-MAKE_TYPED_ARRAY(Vector<double>, Variant::PACKED_FLOAT64_ARRAY)
-MAKE_TYPED_ARRAY(Vector<String>, Variant::PACKED_STRING_ARRAY)
-MAKE_TYPED_ARRAY(Vector<Vector2>, Variant::PACKED_VECTOR2_ARRAY)
-MAKE_TYPED_ARRAY(Vector<Vector3>, Variant::PACKED_VECTOR3_ARRAY)
-MAKE_TYPED_ARRAY(Vector<Color>, Variant::PACKED_COLOR_ARRAY)
+MAKE_TYPED_ARRAY(PackedByteArray, Variant::PACKED_BYTE_ARRAY)
+MAKE_TYPED_ARRAY(PackedInt32Array, Variant::PACKED_INT32_ARRAY)
+MAKE_TYPED_ARRAY(PackedInt64Array, Variant::PACKED_INT64_ARRAY)
+MAKE_TYPED_ARRAY(PackedFloat32Array, Variant::PACKED_FLOAT32_ARRAY)
+MAKE_TYPED_ARRAY(PackedFloat64Array, Variant::PACKED_FLOAT64_ARRAY)
+MAKE_TYPED_ARRAY(PackedStringArray, Variant::PACKED_STRING_ARRAY)
+MAKE_TYPED_ARRAY(PackedVector2Array, Variant::PACKED_VECTOR2_ARRAY)
+MAKE_TYPED_ARRAY(PackedVector3Array, Variant::PACKED_VECTOR3_ARRAY)
+MAKE_TYPED_ARRAY(PackedColorArray, Variant::PACKED_COLOR_ARRAY)
MAKE_TYPED_ARRAY(IPAddress, Variant::STRING)
template <class T>
@@ -218,15 +218,15 @@ MAKE_TYPED_ARRAY_INFO(Callable, Variant::CALLABLE)
MAKE_TYPED_ARRAY_INFO(Signal, Variant::SIGNAL)
MAKE_TYPED_ARRAY_INFO(Dictionary, Variant::DICTIONARY)
MAKE_TYPED_ARRAY_INFO(Array, Variant::ARRAY)
-MAKE_TYPED_ARRAY_INFO(Vector<uint8_t>, Variant::PACKED_BYTE_ARRAY)
-MAKE_TYPED_ARRAY_INFO(Vector<int32_t>, Variant::PACKED_INT32_ARRAY)
-MAKE_TYPED_ARRAY_INFO(Vector<int64_t>, Variant::PACKED_INT64_ARRAY)
-MAKE_TYPED_ARRAY_INFO(Vector<float>, Variant::PACKED_FLOAT32_ARRAY)
-MAKE_TYPED_ARRAY_INFO(Vector<double>, Variant::PACKED_FLOAT64_ARRAY)
-MAKE_TYPED_ARRAY_INFO(Vector<String>, Variant::PACKED_STRING_ARRAY)
-MAKE_TYPED_ARRAY_INFO(Vector<Vector2>, Variant::PACKED_VECTOR2_ARRAY)
-MAKE_TYPED_ARRAY_INFO(Vector<Vector3>, Variant::PACKED_VECTOR3_ARRAY)
-MAKE_TYPED_ARRAY_INFO(Vector<Color>, Variant::PACKED_COLOR_ARRAY)
+MAKE_TYPED_ARRAY_INFO(PackedByteArray, Variant::PACKED_BYTE_ARRAY)
+MAKE_TYPED_ARRAY_INFO(PackedInt32Array, Variant::PACKED_INT32_ARRAY)
+MAKE_TYPED_ARRAY_INFO(PackedInt64Array, Variant::PACKED_INT64_ARRAY)
+MAKE_TYPED_ARRAY_INFO(PackedFloat32Array, Variant::PACKED_FLOAT32_ARRAY)
+MAKE_TYPED_ARRAY_INFO(PackedFloat64Array, Variant::PACKED_FLOAT64_ARRAY)
+MAKE_TYPED_ARRAY_INFO(PackedStringArray, Variant::PACKED_STRING_ARRAY)
+MAKE_TYPED_ARRAY_INFO(PackedVector2Array, Variant::PACKED_VECTOR2_ARRAY)
+MAKE_TYPED_ARRAY_INFO(PackedVector3Array, Variant::PACKED_VECTOR3_ARRAY)
+MAKE_TYPED_ARRAY_INFO(PackedColorArray, Variant::PACKED_COLOR_ARRAY)
MAKE_TYPED_ARRAY_INFO(IPAddress, Variant::STRING)
#undef MAKE_TYPED_ARRAY
diff --git a/core/variant/variant.cpp b/core/variant/variant.cpp
index c352d800f9..67f2c10099 100644
--- a/core/variant/variant.cpp
+++ b/core/variant/variant.cpp
@@ -1246,53 +1246,53 @@ void Variant::zero() {
case NIL:
break;
case BOOL:
- this->_data._bool = false;
+ _data._bool = false;
break;
case INT:
- this->_data._int = 0;
+ _data._int = 0;
break;
case FLOAT:
- this->_data._float = 0;
+ _data._float = 0;
break;
case VECTOR2:
- *reinterpret_cast<Vector2 *>(this->_data._mem) = Vector2();
+ *reinterpret_cast<Vector2 *>(_data._mem) = Vector2();
break;
case VECTOR2I:
- *reinterpret_cast<Vector2i *>(this->_data._mem) = Vector2i();
+ *reinterpret_cast<Vector2i *>(_data._mem) = Vector2i();
break;
case RECT2:
- *reinterpret_cast<Rect2 *>(this->_data._mem) = Rect2();
+ *reinterpret_cast<Rect2 *>(_data._mem) = Rect2();
break;
case RECT2I:
- *reinterpret_cast<Rect2i *>(this->_data._mem) = Rect2i();
+ *reinterpret_cast<Rect2i *>(_data._mem) = Rect2i();
break;
case VECTOR3:
- *reinterpret_cast<Vector3 *>(this->_data._mem) = Vector3();
+ *reinterpret_cast<Vector3 *>(_data._mem) = Vector3();
break;
case VECTOR3I:
- *reinterpret_cast<Vector3i *>(this->_data._mem) = Vector3i();
+ *reinterpret_cast<Vector3i *>(_data._mem) = Vector3i();
break;
case VECTOR4:
- *reinterpret_cast<Vector4 *>(this->_data._mem) = Vector4();
+ *reinterpret_cast<Vector4 *>(_data._mem) = Vector4();
break;
case VECTOR4I:
- *reinterpret_cast<Vector4i *>(this->_data._mem) = Vector4i();
+ *reinterpret_cast<Vector4i *>(_data._mem) = Vector4i();
break;
case PLANE:
- *reinterpret_cast<Plane *>(this->_data._mem) = Plane();
+ *reinterpret_cast<Plane *>(_data._mem) = Plane();
break;
case QUATERNION:
- *reinterpret_cast<Quaternion *>(this->_data._mem) = Quaternion();
+ *reinterpret_cast<Quaternion *>(_data._mem) = Quaternion();
break;
case COLOR:
- *reinterpret_cast<Color *>(this->_data._mem) = Color();
+ *reinterpret_cast<Color *>(_data._mem) = Color();
break;
default:
Type prev_type = type;
- this->clear();
+ clear();
if (type != prev_type) {
// clear() changes type to NIL, so it needs to be restored.
Callable::CallError ce;
@@ -1793,31 +1793,31 @@ String Variant::stringify(int recursion_count) const {
}
// Packed arrays cannot contain recursive structures, the recursion_count increment is not needed.
case PACKED_VECTOR2_ARRAY: {
- return stringify_vector(operator Vector<Vector2>(), recursion_count);
+ return stringify_vector(operator PackedVector2Array(), recursion_count);
}
case PACKED_VECTOR3_ARRAY: {
- return stringify_vector(operator Vector<Vector3>(), recursion_count);
+ return stringify_vector(operator PackedVector3Array(), recursion_count);
}
case PACKED_COLOR_ARRAY: {
- return stringify_vector(operator Vector<Color>(), recursion_count);
+ return stringify_vector(operator PackedColorArray(), recursion_count);
}
case PACKED_STRING_ARRAY: {
- return stringify_vector(operator Vector<String>(), recursion_count);
+ return stringify_vector(operator PackedStringArray(), recursion_count);
}
case PACKED_BYTE_ARRAY: {
- return stringify_vector(operator Vector<uint8_t>(), recursion_count);
+ return stringify_vector(operator PackedByteArray(), recursion_count);
}
case PACKED_INT32_ARRAY: {
- return stringify_vector(operator Vector<int32_t>(), recursion_count);
+ return stringify_vector(operator PackedInt32Array(), recursion_count);
}
case PACKED_INT64_ARRAY: {
- return stringify_vector(operator Vector<int64_t>(), recursion_count);
+ return stringify_vector(operator PackedInt64Array(), recursion_count);
}
case PACKED_FLOAT32_ARRAY: {
- return stringify_vector(operator Vector<float>(), recursion_count);
+ return stringify_vector(operator PackedFloat32Array(), recursion_count);
}
case PACKED_FLOAT64_ARRAY: {
- return stringify_vector(operator Vector<double>(), recursion_count);
+ return stringify_vector(operator PackedFloat64Array(), recursion_count);
}
case ARRAY: {
ERR_FAIL_COND_V_MSG(recursion_count > MAX_RECURSION, "[...]", "Maximum array recursion reached!");
@@ -2207,31 +2207,31 @@ inline DA _convert_array_from_variant(const Variant &p_variant) {
return _convert_array<DA, Array>(p_variant.operator Array());
}
case Variant::PACKED_BYTE_ARRAY: {
- return _convert_array<DA, Vector<uint8_t>>(p_variant.operator Vector<uint8_t>());
+ return _convert_array<DA, PackedByteArray>(p_variant.operator PackedByteArray());
}
case Variant::PACKED_INT32_ARRAY: {
- return _convert_array<DA, Vector<int32_t>>(p_variant.operator Vector<int32_t>());
+ return _convert_array<DA, PackedInt32Array>(p_variant.operator PackedInt32Array());
}
case Variant::PACKED_INT64_ARRAY: {
- return _convert_array<DA, Vector<int64_t>>(p_variant.operator Vector<int64_t>());
+ return _convert_array<DA, PackedInt64Array>(p_variant.operator PackedInt64Array());
}
case Variant::PACKED_FLOAT32_ARRAY: {
- return _convert_array<DA, Vector<float>>(p_variant.operator Vector<float>());
+ return _convert_array<DA, PackedFloat32Array>(p_variant.operator PackedFloat32Array());
}
case Variant::PACKED_FLOAT64_ARRAY: {
- return _convert_array<DA, Vector<double>>(p_variant.operator Vector<double>());
+ return _convert_array<DA, PackedFloat64Array>(p_variant.operator PackedFloat64Array());
}
case Variant::PACKED_STRING_ARRAY: {
- return _convert_array<DA, Vector<String>>(p_variant.operator Vector<String>());
+ return _convert_array<DA, PackedStringArray>(p_variant.operator PackedStringArray());
}
case Variant::PACKED_VECTOR2_ARRAY: {
- return _convert_array<DA, Vector<Vector2>>(p_variant.operator Vector<Vector2>());
+ return _convert_array<DA, PackedVector2Array>(p_variant.operator PackedVector2Array());
}
case Variant::PACKED_VECTOR3_ARRAY: {
- return _convert_array<DA, Vector<Vector3>>(p_variant.operator Vector<Vector3>());
+ return _convert_array<DA, PackedVector3Array>(p_variant.operator PackedVector3Array());
}
case Variant::PACKED_COLOR_ARRAY: {
- return _convert_array<DA, Vector<Color>>(p_variant.operator Vector<Color>());
+ return _convert_array<DA, PackedColorArray>(p_variant.operator PackedColorArray());
}
default: {
return DA();
@@ -2247,75 +2247,75 @@ Variant::operator Array() const {
}
}
-Variant::operator Vector<uint8_t>() const {
+Variant::operator PackedByteArray() const {
if (type == PACKED_BYTE_ARRAY) {
return static_cast<PackedArrayRef<uint8_t> *>(_data.packed_array)->array;
} else {
- return _convert_array_from_variant<Vector<uint8_t>>(*this);
+ return _convert_array_from_variant<PackedByteArray>(*this);
}
}
-Variant::operator Vector<int32_t>() const {
+Variant::operator PackedInt32Array() const {
if (type == PACKED_INT32_ARRAY) {
return static_cast<PackedArrayRef<int32_t> *>(_data.packed_array)->array;
} else {
- return _convert_array_from_variant<Vector<int>>(*this);
+ return _convert_array_from_variant<PackedInt32Array>(*this);
}
}
-Variant::operator Vector<int64_t>() const {
+Variant::operator PackedInt64Array() const {
if (type == PACKED_INT64_ARRAY) {
return static_cast<PackedArrayRef<int64_t> *>(_data.packed_array)->array;
} else {
- return _convert_array_from_variant<Vector<int64_t>>(*this);
+ return _convert_array_from_variant<PackedInt64Array>(*this);
}
}
-Variant::operator Vector<float>() const {
+Variant::operator PackedFloat32Array() const {
if (type == PACKED_FLOAT32_ARRAY) {
return static_cast<PackedArrayRef<float> *>(_data.packed_array)->array;
} else {
- return _convert_array_from_variant<Vector<float>>(*this);
+ return _convert_array_from_variant<PackedFloat32Array>(*this);
}
}
-Variant::operator Vector<double>() const {
+Variant::operator PackedFloat64Array() const {
if (type == PACKED_FLOAT64_ARRAY) {
return static_cast<PackedArrayRef<double> *>(_data.packed_array)->array;
} else {
- return _convert_array_from_variant<Vector<double>>(*this);
+ return _convert_array_from_variant<PackedFloat64Array>(*this);
}
}
-Variant::operator Vector<String>() const {
+Variant::operator PackedStringArray() const {
if (type == PACKED_STRING_ARRAY) {
return static_cast<PackedArrayRef<String> *>(_data.packed_array)->array;
} else {
- return _convert_array_from_variant<Vector<String>>(*this);
+ return _convert_array_from_variant<PackedStringArray>(*this);
}
}
-Variant::operator Vector<Vector3>() const {
- if (type == PACKED_VECTOR3_ARRAY) {
- return static_cast<PackedArrayRef<Vector3> *>(_data.packed_array)->array;
+Variant::operator PackedVector2Array() const {
+ if (type == PACKED_VECTOR2_ARRAY) {
+ return static_cast<PackedArrayRef<Vector2> *>(_data.packed_array)->array;
} else {
- return _convert_array_from_variant<Vector<Vector3>>(*this);
+ return _convert_array_from_variant<PackedVector2Array>(*this);
}
}
-Variant::operator Vector<Vector2>() const {
- if (type == PACKED_VECTOR2_ARRAY) {
- return static_cast<PackedArrayRef<Vector2> *>(_data.packed_array)->array;
+Variant::operator PackedVector3Array() const {
+ if (type == PACKED_VECTOR3_ARRAY) {
+ return static_cast<PackedArrayRef<Vector3> *>(_data.packed_array)->array;
} else {
- return _convert_array_from_variant<Vector<Vector2>>(*this);
+ return _convert_array_from_variant<PackedVector3Array>(*this);
}
}
-Variant::operator Vector<Color>() const {
+Variant::operator PackedColorArray() const {
if (type == PACKED_COLOR_ARRAY) {
return static_cast<PackedArrayRef<Color> *>(_data.packed_array)->array;
} else {
- return _convert_array_from_variant<Vector<Color>>(*this);
+ return _convert_array_from_variant<PackedColorArray>(*this);
}
}
@@ -2350,7 +2350,7 @@ Variant::operator Vector<Plane>() const {
}
Variant::operator Vector<Face3>() const {
- Vector<Vector3> va = operator Vector<Vector3>();
+ PackedVector3Array va = operator PackedVector3Array();
Vector<Face3> faces;
int va_size = va.size();
if (va_size == 0) {
@@ -2386,7 +2386,7 @@ Variant::operator Vector<Variant>() const {
}
Variant::operator Vector<StringName>() const {
- Vector<String> from = operator Vector<String>();
+ PackedStringArray from = operator PackedStringArray();
Vector<StringName> to;
int len = from.size();
to.resize(len);
@@ -2646,78 +2646,79 @@ Variant::Variant(const Array &p_array) {
memnew_placement(_data._mem, Array(p_array));
}
-Variant::Variant(const Vector<Plane> &p_array) {
- type = ARRAY;
-
- Array *plane_array = memnew_placement(_data._mem, Array);
-
- plane_array->resize(p_array.size());
-
- for (int i = 0; i < p_array.size(); i++) {
- plane_array->operator[](i) = Variant(p_array[i]);
- }
-}
-
-Variant::Variant(const Vector<::RID> &p_array) {
- type = ARRAY;
-
- Array *rid_array = memnew_placement(_data._mem, Array);
-
- rid_array->resize(p_array.size());
-
- for (int i = 0; i < p_array.size(); i++) {
- rid_array->set(i, Variant(p_array[i]));
- }
-}
-
-Variant::Variant(const Vector<uint8_t> &p_byte_array) {
+Variant::Variant(const PackedByteArray &p_byte_array) {
type = PACKED_BYTE_ARRAY;
_data.packed_array = PackedArrayRef<uint8_t>::create(p_byte_array);
}
-Variant::Variant(const Vector<int32_t> &p_int32_array) {
+Variant::Variant(const PackedInt32Array &p_int32_array) {
type = PACKED_INT32_ARRAY;
_data.packed_array = PackedArrayRef<int32_t>::create(p_int32_array);
}
-Variant::Variant(const Vector<int64_t> &p_int64_array) {
+Variant::Variant(const PackedInt64Array &p_int64_array) {
type = PACKED_INT64_ARRAY;
_data.packed_array = PackedArrayRef<int64_t>::create(p_int64_array);
}
-Variant::Variant(const Vector<float> &p_float32_array) {
+Variant::Variant(const PackedFloat32Array &p_float32_array) {
type = PACKED_FLOAT32_ARRAY;
_data.packed_array = PackedArrayRef<float>::create(p_float32_array);
}
-Variant::Variant(const Vector<double> &p_float64_array) {
+Variant::Variant(const PackedFloat64Array &p_float64_array) {
type = PACKED_FLOAT64_ARRAY;
_data.packed_array = PackedArrayRef<double>::create(p_float64_array);
}
-Variant::Variant(const Vector<String> &p_string_array) {
+Variant::Variant(const PackedStringArray &p_string_array) {
type = PACKED_STRING_ARRAY;
_data.packed_array = PackedArrayRef<String>::create(p_string_array);
}
-Variant::Variant(const Vector<Vector3> &p_vector3_array) {
- type = PACKED_VECTOR3_ARRAY;
- _data.packed_array = PackedArrayRef<Vector3>::create(p_vector3_array);
-}
-
-Variant::Variant(const Vector<Vector2> &p_vector2_array) {
+Variant::Variant(const PackedVector2Array &p_vector2_array) {
type = PACKED_VECTOR2_ARRAY;
_data.packed_array = PackedArrayRef<Vector2>::create(p_vector2_array);
}
-Variant::Variant(const Vector<Color> &p_color_array) {
+Variant::Variant(const PackedVector3Array &p_vector3_array) {
+ type = PACKED_VECTOR3_ARRAY;
+ _data.packed_array = PackedArrayRef<Vector3>::create(p_vector3_array);
+}
+
+Variant::Variant(const PackedColorArray &p_color_array) {
type = PACKED_COLOR_ARRAY;
_data.packed_array = PackedArrayRef<Color>::create(p_color_array);
}
+/* helpers */
+Variant::Variant(const Vector<::RID> &p_array) {
+ type = ARRAY;
+
+ Array *rid_array = memnew_placement(_data._mem, Array);
+
+ rid_array->resize(p_array.size());
+
+ for (int i = 0; i < p_array.size(); i++) {
+ rid_array->set(i, Variant(p_array[i]));
+ }
+}
+
+Variant::Variant(const Vector<Plane> &p_array) {
+ type = ARRAY;
+
+ Array *plane_array = memnew_placement(_data._mem, Array);
+
+ plane_array->resize(p_array.size());
+
+ for (int i = 0; i < p_array.size(); i++) {
+ plane_array->operator[](i) = Variant(p_array[i]);
+ }
+}
+
Variant::Variant(const Vector<Face3> &p_face_array) {
- Vector<Vector3> vertices;
+ PackedVector3Array vertices;
int face_count = p_face_array.size();
vertices.resize(face_count * 3);
@@ -2737,7 +2738,6 @@ Variant::Variant(const Vector<Face3> &p_face_array) {
*this = vertices;
}
-/* helpers */
Variant::Variant(const Vector<Variant> &p_array) {
type = NIL;
Array arr;
@@ -2750,7 +2750,7 @@ Variant::Variant(const Vector<Variant> &p_array) {
Variant::Variant(const Vector<StringName> &p_array) {
type = NIL;
- Vector<String> v;
+ PackedStringArray v;
int len = p_array.size();
v.resize(len);
for (int i = 0; i < len; i++) {
@@ -3100,7 +3100,7 @@ uint32_t Variant::recursive_hash(int recursion_count) const {
} break;
case PACKED_BYTE_ARRAY: {
- const Vector<uint8_t> &arr = PackedArrayRef<uint8_t>::get_array(_data.packed_array);
+ const PackedByteArray &arr = PackedArrayRef<uint8_t>::get_array(_data.packed_array);
int len = arr.size();
if (likely(len)) {
const uint8_t *r = arr.ptr();
@@ -3111,7 +3111,7 @@ uint32_t Variant::recursive_hash(int recursion_count) const {
} break;
case PACKED_INT32_ARRAY: {
- const Vector<int32_t> &arr = PackedArrayRef<int32_t>::get_array(_data.packed_array);
+ const PackedInt32Array &arr = PackedArrayRef<int32_t>::get_array(_data.packed_array);
int len = arr.size();
if (likely(len)) {
const int32_t *r = arr.ptr();
@@ -3122,7 +3122,7 @@ uint32_t Variant::recursive_hash(int recursion_count) const {
} break;
case PACKED_INT64_ARRAY: {
- const Vector<int64_t> &arr = PackedArrayRef<int64_t>::get_array(_data.packed_array);
+ const PackedInt64Array &arr = PackedArrayRef<int64_t>::get_array(_data.packed_array);
int len = arr.size();
if (likely(len)) {
const int64_t *r = arr.ptr();
@@ -3133,7 +3133,7 @@ uint32_t Variant::recursive_hash(int recursion_count) const {
} break;
case PACKED_FLOAT32_ARRAY: {
- const Vector<float> &arr = PackedArrayRef<float>::get_array(_data.packed_array);
+ const PackedFloat32Array &arr = PackedArrayRef<float>::get_array(_data.packed_array);
int len = arr.size();
if (likely(len)) {
@@ -3149,7 +3149,7 @@ uint32_t Variant::recursive_hash(int recursion_count) const {
} break;
case PACKED_FLOAT64_ARRAY: {
- const Vector<double> &arr = PackedArrayRef<double>::get_array(_data.packed_array);
+ const PackedFloat64Array &arr = PackedArrayRef<double>::get_array(_data.packed_array);
int len = arr.size();
if (likely(len)) {
@@ -3166,7 +3166,7 @@ uint32_t Variant::recursive_hash(int recursion_count) const {
} break;
case PACKED_STRING_ARRAY: {
uint32_t hash = HASH_MURMUR3_SEED;
- const Vector<String> &arr = PackedArrayRef<String>::get_array(_data.packed_array);
+ const PackedStringArray &arr = PackedArrayRef<String>::get_array(_data.packed_array);
int len = arr.size();
if (likely(len)) {
@@ -3182,7 +3182,7 @@ uint32_t Variant::recursive_hash(int recursion_count) const {
} break;
case PACKED_VECTOR2_ARRAY: {
uint32_t hash = HASH_MURMUR3_SEED;
- const Vector<Vector2> &arr = PackedArrayRef<Vector2>::get_array(_data.packed_array);
+ const PackedVector2Array &arr = PackedArrayRef<Vector2>::get_array(_data.packed_array);
int len = arr.size();
if (likely(len)) {
@@ -3199,7 +3199,7 @@ uint32_t Variant::recursive_hash(int recursion_count) const {
} break;
case PACKED_VECTOR3_ARRAY: {
uint32_t hash = HASH_MURMUR3_SEED;
- const Vector<Vector3> &arr = PackedArrayRef<Vector3>::get_array(_data.packed_array);
+ const PackedVector3Array &arr = PackedArrayRef<Vector3>::get_array(_data.packed_array);
int len = arr.size();
if (likely(len)) {
@@ -3217,7 +3217,7 @@ uint32_t Variant::recursive_hash(int recursion_count) const {
} break;
case PACKED_COLOR_ARRAY: {
uint32_t hash = HASH_MURMUR3_SEED;
- const Vector<Color> &arr = PackedArrayRef<Color>::get_array(_data.packed_array);
+ const PackedColorArray &arr = PackedArrayRef<Color>::get_array(_data.packed_array);
int len = arr.size();
if (likely(len)) {
diff --git a/core/variant/variant.h b/core/variant/variant.h
index 602d287f22..d685444c30 100644
--- a/core/variant/variant.h
+++ b/core/variant/variant.h
@@ -176,7 +176,7 @@ private:
struct PackedArrayRefBase {
SafeRefCount refcount;
_FORCE_INLINE_ PackedArrayRefBase *reference() {
- if (this->refcount.ref()) {
+ if (refcount.ref()) {
return this;
} else {
return nullptr;
@@ -404,21 +404,21 @@ public:
operator Dictionary() const;
operator Array() const;
- operator Vector<uint8_t>() const;
- operator Vector<int32_t>() const;
- operator Vector<int64_t>() const;
- operator Vector<float>() const;
- operator Vector<double>() const;
- operator Vector<String>() const;
- operator Vector<Vector3>() const;
- operator Vector<Color>() const;
+ operator PackedByteArray() const;
+ operator PackedInt32Array() const;
+ operator PackedInt64Array() const;
+ operator PackedFloat32Array() const;
+ operator PackedFloat64Array() const;
+ operator PackedStringArray() const;
+ operator PackedVector3Array() const;
+ operator PackedVector2Array() const;
+ operator PackedColorArray() const;
+
+ operator Vector<::RID>() const;
operator Vector<Plane>() const;
operator Vector<Face3>() const;
-
operator Vector<Variant>() const;
operator Vector<StringName>() const;
- operator Vector<::RID>() const;
- operator Vector<Vector2>() const;
// some core type enums to convert to
operator Side() const;
@@ -473,21 +473,21 @@ public:
Variant(const Dictionary &p_dictionary);
Variant(const Array &p_array);
+ Variant(const PackedByteArray &p_byte_array);
+ Variant(const PackedInt32Array &p_int32_array);
+ Variant(const PackedInt64Array &p_int64_array);
+ Variant(const PackedFloat32Array &p_float32_array);
+ Variant(const PackedFloat64Array &p_float64_array);
+ Variant(const PackedStringArray &p_string_array);
+ Variant(const PackedVector2Array &p_vector2_array);
+ Variant(const PackedVector3Array &p_vector3_array);
+ Variant(const PackedColorArray &p_color_array);
+
+ Variant(const Vector<::RID> &p_array); // helper
Variant(const Vector<Plane> &p_array); // helper
- Variant(const Vector<uint8_t> &p_byte_array);
- Variant(const Vector<int32_t> &p_int32_array);
- Variant(const Vector<int64_t> &p_int64_array);
- Variant(const Vector<float> &p_float32_array);
- Variant(const Vector<double> &p_float64_array);
- Variant(const Vector<String> &p_string_array);
- Variant(const Vector<Vector3> &p_vector3_array);
- Variant(const Vector<Color> &p_color_array);
Variant(const Vector<Face3> &p_face_array);
-
Variant(const Vector<Variant> &p_array);
Variant(const Vector<StringName> &p_array);
- Variant(const Vector<::RID> &p_array); // helper
- Variant(const Vector<Vector2> &p_array); // helper
Variant(const IPAddress &p_address);
@@ -502,6 +502,7 @@ public:
VARIANT_ENUM_CLASS_CONSTRUCTOR(JoyAxis)
VARIANT_ENUM_CLASS_CONSTRUCTOR(JoyButton)
VARIANT_ENUM_CLASS_CONSTRUCTOR(Key)
+ VARIANT_ENUM_CLASS_CONSTRUCTOR(KeyLocation)
VARIANT_ENUM_CLASS_CONSTRUCTOR(MIDIMessage)
VARIANT_ENUM_CLASS_CONSTRUCTOR(MouseButton)
diff --git a/core/version.h b/core/version.h
index 5ddb09284e..abb81312ac 100644
--- a/core/version.h
+++ b/core/version.h
@@ -33,6 +33,12 @@
#include "core/version_generated.gen.h"
+// Copied from typedefs.h to stay lean.
+#ifndef _STR
+#define _STR(m_x) #m_x
+#define _MKSTR(m_x) _STR(m_x)
+#endif
+
// Godot versions are of the form <major>.<minor> for the initial release,
// and then <major>.<minor>.<patch> for subsequent bugfix releases where <patch> != 0
// That's arbitrary, but we find it pretty and it's the current policy.