diff options
Diffstat (limited to 'core')
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. |