diff options
Diffstat (limited to 'core')
65 files changed, 1435 insertions, 748 deletions
diff --git a/core/config/engine.cpp b/core/config/engine.cpp index ad31966a65..c03c872f17 100644 --- a/core/config/engine.cpp +++ b/core/config/engine.cpp @@ -214,8 +214,8 @@ bool Engine::has_singleton(const String &p_name) const { } void Engine::get_singletons(List<Singleton> *p_singletons) { - for (List<Singleton>::Element *E = singletons.front(); E; E = E->next()) { - p_singletons->push_back(E->get()); + for (Singleton &E : singletons) { + p_singletons->push_back(E); } } diff --git a/core/config/project_settings.cpp b/core/config/project_settings.cpp index 84860b648d..22acb23bce 100644 --- a/core/config/project_settings.cpp +++ b/core/config/project_settings.cpp @@ -700,9 +700,7 @@ Error ProjectSettings::_save_settings_binary(const String &p_file, const Map<Str int count = 0; for (Map<String, List<String>>::Element *E = props.front(); E; E = E->next()) { - for (List<String>::Element *F = E->get().front(); F; F = F->next()) { - count++; - } + count += E->get().size(); } if (p_custom_features != String()) { @@ -734,8 +732,7 @@ Error ProjectSettings::_save_settings_binary(const String &p_file, const Map<Str } for (Map<String, List<String>>::Element *E = props.front(); E; E = E->next()) { - for (List<String>::Element *F = E->get().front(); F; F = F->next()) { - String key = F->get(); + for (String &key : E->get()) { if (E->key() != "") { key = E->key() + "/" + key; } @@ -803,8 +800,8 @@ Error ProjectSettings::_save_settings_text(const String &p_file, const Map<Strin if (E->key() != "") { file->store_string("[" + E->key() + "]\n\n"); } - for (List<String>::Element *F = E->get().front(); F; F = F->next()) { - String key = F->get(); + for (String &F : E->get()) { + String key = F; if (E->key() != "") { key = E->key() + "/" + key; } @@ -817,7 +814,7 @@ Error ProjectSettings::_save_settings_text(const String &p_file, const Map<Strin String vstr; VariantWriter::write_to_string(value, vstr); - file->store_string(F->get().property_name_encode() + "=" + vstr + "\n"); + file->store_string(F.property_name_encode() + "=" + vstr + "\n"); } } @@ -931,11 +928,11 @@ Vector<String> ProjectSettings::get_optimizer_presets() const { ProjectSettings::get_singleton()->get_property_list(&pi); Vector<String> names; - for (List<PropertyInfo>::Element *E = pi.front(); E; E = E->next()) { - if (!E->get().name.begins_with("optimizer_presets/")) { + for (PropertyInfo &E : pi) { + if (!E.name.begins_with("optimizer_presets/")) { continue; } - names.push_back(E->get().name.get_slicec('/', 1)); + names.push_back(E.name.get_slicec('/', 1)); } names.sort(); diff --git a/core/core_bind.cpp b/core/core_bind.cpp index 9a58528bd7..7a1ba63233 100644 --- a/core/core_bind.cpp +++ b/core/core_bind.cpp @@ -75,8 +75,8 @@ Vector<String> _ResourceLoader::get_recognized_extensions_for_type(const String List<String> exts; ResourceLoader::get_recognized_extensions_for_type(p_type, &exts); Vector<String> ret; - for (List<String>::Element *E = exts.front(); E; E = E->next()) { - ret.push_back(E->get()); + for (String &E : exts) { + ret.push_back(E); } return ret; @@ -91,8 +91,8 @@ PackedStringArray _ResourceLoader::get_dependencies(const String &p_path) { ResourceLoader::get_dependencies(p_path, &deps); PackedStringArray ret; - for (List<String>::Element *E = deps.front(); E; E = E->next()) { - ret.push_back(E->get()); + for (String &E : deps) { + ret.push_back(E); } return ret; @@ -141,8 +141,8 @@ Vector<String> _ResourceSaver::get_recognized_extensions(const RES &p_resource) List<String> exts; ResourceSaver::get_recognized_extensions(p_resource, &exts); Vector<String> ret; - for (List<String>::Element *E = exts.front(); E; E = E->next()) { - ret.push_back(E->get()); + for (String &E : exts) { + ret.push_back(E); } return ret; } @@ -196,6 +196,10 @@ int _OS::get_low_processor_usage_mode_sleep_usec() const { return OS::get_singleton()->get_low_processor_usage_mode_sleep_usec(); } +void _OS::alert(const String &p_alert, const String &p_title) { + OS::get_singleton()->alert(p_alert, p_title); +} + String _OS::get_executable_path() const { return OS::get_singleton()->get_executable_path(); } @@ -264,8 +268,8 @@ String _OS::get_name() const { Vector<String> _OS::get_cmdline_args() { List<String> cmdline = OS::get_singleton()->get_cmdline_args(); Vector<String> cmdlinev; - for (List<String>::Element *E = cmdline.front(); E; E = E->next()) { - cmdlinev.push_back(E->get()); + for (String &E : cmdline) { + cmdlinev.push_back(E); } return cmdlinev; @@ -351,20 +355,20 @@ void _OS::print_all_textures_by_size() { List<Ref<Resource>> rsrc; ResourceCache::get_cached_resources(&rsrc); - for (List<Ref<Resource>>::Element *E = rsrc.front(); E; E = E->next()) { - if (!E->get()->is_class("ImageTexture")) { + for (Ref<Resource> E : rsrc) { + if (!E->is_class("ImageTexture")) { continue; } - Size2 size = E->get()->call("get_size"); - int fmt = E->get()->call("get_format"); + Size2 size = E->call("get_size"); + int fmt = E->call("get_format"); _OSCoreBindImg img; img.size = size; img.fmt = fmt; - img.path = E->get()->get_path(); + img.path = E->get_path(); img.vram = Image::get_image_data_size(img.size.width, img.size.height, Image::Format(img.fmt)); - img.id = E->get()->get_instance_id(); + img.id = E->get_instance_id(); total += img.vram; imgs.push_back(img); } @@ -372,8 +376,8 @@ void _OS::print_all_textures_by_size() { imgs.sort(); - for (List<_OSCoreBindImg>::Element *E = imgs.front(); E; E = E->next()) { - total -= E->get().vram; + for (_OSCoreBindImg &E : imgs) { + total -= E.vram; } } @@ -383,9 +387,7 @@ void _OS::print_resources_by_type(const Vector<String> &p_types) { List<Ref<Resource>> resources; ResourceCache::get_cached_resources(&resources); - for (List<Ref<Resource>>::Element *E = resources.front(); E; E = E->next()) { - Ref<Resource> r = E->get(); - + for (Ref<Resource> r : resources) { bool found = false; for (int i = 0; i < p_types.size(); i++) { @@ -487,6 +489,8 @@ void _OS::_bind_methods() { ClassDB::bind_method(D_METHOD("open_midi_inputs"), &_OS::open_midi_inputs); ClassDB::bind_method(D_METHOD("close_midi_inputs"), &_OS::close_midi_inputs); + ClassDB::bind_method(D_METHOD("alert", "text", "title"), &_OS::alert, DEFVAL("Alert!")); + ClassDB::bind_method(D_METHOD("set_low_processor_usage_mode", "enable"), &_OS::set_low_processor_usage_mode); ClassDB::bind_method(D_METHOD("is_in_low_processor_usage_mode"), &_OS::is_in_low_processor_usage_mode); @@ -1818,8 +1822,8 @@ PackedStringArray _ClassDB::get_class_list() const { PackedStringArray ret; ret.resize(classes.size()); int idx = 0; - for (List<StringName>::Element *E = classes.front(); E; E = E->next()) { - ret.set(idx++, E->get()); + for (StringName &E : classes) { + ret.set(idx++, E); } return ret; @@ -1832,8 +1836,8 @@ PackedStringArray _ClassDB::get_inheriters_from_class(const StringName &p_class) PackedStringArray ret; ret.resize(classes.size()); int idx = 0; - for (List<StringName>::Element *E = classes.front(); E; E = E->next()) { - ret.set(idx++, E->get()); + for (StringName &E : classes) { + ret.set(idx++, E); } return ret; @@ -1887,8 +1891,8 @@ Array _ClassDB::get_signal_list(StringName p_class, bool p_no_inheritance) const ClassDB::get_signal_list(p_class, &signals, p_no_inheritance); Array ret; - for (List<MethodInfo>::Element *E = signals.front(); E; E = E->next()) { - ret.push_back(E->get().operator Dictionary()); + for (MethodInfo &E : signals) { + ret.push_back(E.operator Dictionary()); } return ret; @@ -1898,8 +1902,8 @@ Array _ClassDB::get_property_list(StringName p_class, bool p_no_inheritance) con List<PropertyInfo> plist; ClassDB::get_property_list(p_class, &plist, p_no_inheritance); Array ret; - for (List<PropertyInfo>::Element *E = plist.front(); E; E = E->next()) { - ret.push_back(E->get().operator Dictionary()); + for (PropertyInfo &E : plist) { + ret.push_back(E.operator Dictionary()); } return ret; @@ -1931,12 +1935,12 @@ Array _ClassDB::get_method_list(StringName p_class, bool p_no_inheritance) const ClassDB::get_method_list(p_class, &methods, p_no_inheritance); Array ret; - for (List<MethodInfo>::Element *E = methods.front(); E; E = E->next()) { + for (MethodInfo &E : methods) { #ifdef DEBUG_METHODS_ENABLED - ret.push_back(E->get().operator Dictionary()); + ret.push_back(E.operator Dictionary()); #else Dictionary dict; - dict["name"] = E->get().name; + dict["name"] = E.name; ret.push_back(dict); #endif } @@ -1951,8 +1955,8 @@ PackedStringArray _ClassDB::get_integer_constant_list(const StringName &p_class, PackedStringArray ret; ret.resize(constants.size()); int idx = 0; - for (List<String>::Element *E = constants.front(); E; E = E->next()) { - ret.set(idx++, E->get()); + for (String &E : constants) { + ret.set(idx++, E); } return ret; diff --git a/core/core_bind.h b/core/core_bind.h index 673dbe32c4..43f74dc9bd 100644 --- a/core/core_bind.h +++ b/core/core_bind.h @@ -162,6 +162,8 @@ public: void set_low_processor_usage_mode_sleep_usec(int p_usec); int get_low_processor_usage_mode_sleep_usec() const; + void alert(const String &p_alert, const String &p_title = "ALERT!"); + String get_executable_path() const; int execute(const String &p_path, const Vector<String> &p_arguments, Array r_output = Array(), bool p_read_stderr = false); int create_process(const String &p_path, const Vector<String> &p_arguments); diff --git a/core/debugger/debugger_marshalls.cpp b/core/debugger/debugger_marshalls.cpp index 26f82c2658..b832dd58d5 100644 --- a/core/debugger/debugger_marshalls.cpp +++ b/core/debugger/debugger_marshalls.cpp @@ -40,11 +40,11 @@ Array DebuggerMarshalls::ResourceUsage::serialize() { Array arr; arr.push_back(infos.size() * 4); - for (List<ResourceInfo>::Element *E = infos.front(); E; E = E->next()) { - arr.push_back(E->get().path); - arr.push_back(E->get().format); - arr.push_back(E->get().type); - arr.push_back(E->get().vram); + for (ResourceInfo &E : infos) { + arr.push_back(E.path); + arr.push_back(E.format); + arr.push_back(E.type); + arr.push_back(E.vram); } return arr; } diff --git a/core/debugger/local_debugger.cpp b/core/debugger/local_debugger.cpp index ab368471e4..24833711d5 100644 --- a/core/debugger/local_debugger.cpp +++ b/core/debugger/local_debugger.cpp @@ -320,13 +320,13 @@ void LocalDebugger::print_variables(const List<String> &names, const List<Varian String value; Vector<String> value_lines; const List<Variant>::Element *V = values.front(); - for (const List<String>::Element *E = names.front(); E; E = E->next()) { + for (const String &E : names) { value = String(V->get()); if (variable_prefix.is_empty()) { - print_line(E->get() + ": " + String(V->get())); + print_line(E + ": " + String(V->get())); } else { - print_line(E->get() + ":"); + print_line(E + ":"); value_lines = value.split("\n"); for (int i = 0; i < value_lines.size(); ++i) { print_line(variable_prefix + value_lines[i]); diff --git a/core/debugger/remote_debugger.cpp b/core/debugger/remote_debugger.cpp index bdbb7766fa..7d3abc9b46 100644 --- a/core/debugger/remote_debugger.cpp +++ b/core/debugger/remote_debugger.cpp @@ -427,16 +427,16 @@ void RemoteDebugger::_send_resource_usage() { List<RS::TextureInfo> tinfo; RS::get_singleton()->texture_debug_usage(&tinfo); - for (List<RS::TextureInfo>::Element *E = tinfo.front(); E; E = E->next()) { + for (RS::TextureInfo &E : tinfo) { DebuggerMarshalls::ResourceInfo info; - info.path = E->get().path; - info.vram = E->get().bytes; - info.id = E->get().texture; + info.path = E.path; + info.vram = E.bytes; + info.id = E.texture; info.type = "Texture"; - if (E->get().depth == 0) { - info.format = itos(E->get().width) + "x" + itos(E->get().height) + " " + Image::get_format_name(E->get().format); + if (E.depth == 0) { + info.format = itos(E.width) + "x" + itos(E.height) + " " + Image::get_format_name(E.format); } else { - info.format = itos(E->get().width) + "x" + itos(E->get().height) + "x" + itos(E->get().depth) + " " + Image::get_format_name(E->get().format); + info.format = itos(E.width) + "x" + itos(E.height) + "x" + itos(E.depth) + " " + Image::get_format_name(E.format); } usage.infos.push_back(info); } diff --git a/core/extension/extension_api_dump.cpp b/core/extension/extension_api_dump.cpp index 3c132a619d..cc2974cbdb 100644 --- a/core/extension/extension_api_dump.cpp +++ b/core/extension/extension_api_dump.cpp @@ -276,10 +276,10 @@ Dictionary NativeExtensionAPIDump::generate_extension_api() { Dictionary d1; d1["name"] = E->key(); Array values; - for (List<Pair<String, int>>::Element *F = E->get().front(); F; F = F->next()) { + for (Pair<String, int> &F : E->get()) { Dictionary d2; - d2["name"] = F->get().first; - d2["value"] = F->get().second; + d2["name"] = F.first; + d2["value"] = F.second; values.push_back(d2); } d1["values"] = values; @@ -294,8 +294,7 @@ Dictionary NativeExtensionAPIDump::generate_extension_api() { List<StringName> utility_func_names; Variant::get_utility_function_list(&utility_func_names); - for (List<StringName>::Element *E = utility_func_names.front(); E; E = E->next()) { - StringName name = E->get(); + for (StringName &name : utility_func_names) { Dictionary func; func["name"] = String(name); if (Variant::has_utility_function_return_value(name)) { @@ -363,8 +362,7 @@ Dictionary NativeExtensionAPIDump::generate_extension_api() { List<StringName> member_names; Variant::get_member_list(type, &member_names); - for (List<StringName>::Element *E = member_names.front(); E; E = E->next()) { - StringName member_name = E->get(); + for (StringName &member_name : member_names) { Dictionary d2; d2["name"] = String(member_name); d2["type"] = Variant::get_type_name(Variant::get_member_type(type, member_name)); @@ -380,8 +378,7 @@ Dictionary NativeExtensionAPIDump::generate_extension_api() { List<StringName> constant_names; Variant::get_constants_for_type(type, &constant_names); - for (List<StringName>::Element *E = constant_names.front(); E; E = E->next()) { - StringName constant_name = E->get(); + for (StringName &constant_name : constant_names) { Dictionary d2; d2["name"] = String(constant_name); Variant constant = Variant::get_constant_value(type, constant_name); @@ -420,8 +417,7 @@ Dictionary NativeExtensionAPIDump::generate_extension_api() { List<StringName> method_names; Variant::get_builtin_method_list(type, &method_names); - for (List<StringName>::Element *E = method_names.front(); E; E = E->next()) { - StringName method_name = E->get(); + for (StringName &method_name : method_names) { Dictionary d2; d2["name"] = String(method_name); if (Variant::has_builtin_method_return_value(type, method_name)) { @@ -503,9 +499,8 @@ Dictionary NativeExtensionAPIDump::generate_extension_api() { class_list.sort_custom<StringName::AlphCompare>(); - for (List<StringName>::Element *E = class_list.front(); E; E = E->next()) { + for (StringName &class_name : class_list) { Dictionary d; - StringName class_name = E->get(); d["name"] = String(class_name); d["is_refcounted"] = ClassDB::is_parent_class(class_name, "RefCounted"); d["is_instantiable"] = ClassDB::can_instantiate(class_name); @@ -525,15 +520,15 @@ Dictionary NativeExtensionAPIDump::generate_extension_api() { Array constants; List<String> constant_list; ClassDB::get_integer_constant_list(class_name, &constant_list, true); - for (List<String>::Element *F = constant_list.front(); F; F = F->next()) { - StringName enum_name = ClassDB::get_integer_constant_enum(class_name, F->get()); + for (String &F : constant_list) { + StringName enum_name = ClassDB::get_integer_constant_enum(class_name, F); if (enum_name != StringName()) { continue; //enums will be handled on their own } Dictionary d2; - d2["name"] = String(F->get()); - d2["value"] = ClassDB::get_integer_constant(class_name, F->get()); + d2["name"] = String(F); + d2["value"] = ClassDB::get_integer_constant(class_name, F); constants.push_back(d2); } @@ -547,13 +542,13 @@ Dictionary NativeExtensionAPIDump::generate_extension_api() { Array enums; List<StringName> enum_list; ClassDB::get_enum_list(class_name, &enum_list, true); - for (List<StringName>::Element *F = enum_list.front(); F; F = F->next()) { + for (StringName &F : enum_list) { Dictionary d2; - d2["name"] = String(F->get()); + d2["name"] = String(F); Array values; List<StringName> enum_constant_list; - ClassDB::get_enum_constants(class_name, F->get(), &enum_constant_list, true); + ClassDB::get_enum_constants(class_name, F, &enum_constant_list, true); for (List<StringName>::Element *G = enum_constant_list.front(); G; G = G->next()) { Dictionary d3; d3["name"] = String(G->get()); @@ -575,14 +570,14 @@ Dictionary NativeExtensionAPIDump::generate_extension_api() { Array methods; List<MethodInfo> method_list; ClassDB::get_method_list(class_name, &method_list, true); - for (List<MethodInfo>::Element *F = method_list.front(); F; F = F->next()) { - StringName method_name = F->get().name; - if (F->get().flags & METHOD_FLAG_VIRTUAL) { + for (MethodInfo &F : method_list) { + StringName method_name = F.name; + if (F.flags & METHOD_FLAG_VIRTUAL) { //virtual method - const MethodInfo &mi = F->get(); + const MethodInfo &mi = F; Dictionary d2; d2["name"] = String(method_name); - d2["is_const"] = (F->get().flags & METHOD_FLAG_CONST) ? true : false; + d2["is_const"] = (F.flags & METHOD_FLAG_CONST) ? true : false; d2["is_vararg"] = false; d2["is_virtual"] = true; // virtual functions have no hash since no MethodBind is involved @@ -619,7 +614,7 @@ Dictionary NativeExtensionAPIDump::generate_extension_api() { methods.push_back(d2); - } else if (F->get().name.begins_with("_")) { + } else if (F.name.begins_with("_")) { //hidden method, ignore } else { @@ -692,19 +687,19 @@ Dictionary NativeExtensionAPIDump::generate_extension_api() { Array signals; List<MethodInfo> signal_list; ClassDB::get_signal_list(class_name, &signal_list, true); - for (List<MethodInfo>::Element *F = signal_list.front(); F; F = F->next()) { - StringName signal_name = F->get().name; + for (MethodInfo &F : signal_list) { + StringName signal_name = F.name; Dictionary d2; d2["name"] = String(signal_name); Array arguments; - for (int i = 0; i < F->get().arguments.size(); i++) { + for (int i = 0; i < F.arguments.size(); i++) { Dictionary d3; - d3["name"] = F->get().arguments[i].name; - Variant::Type type = F->get().arguments[i].type; - if (F->get().arguments[i].class_name != StringName()) { - d3["type"] = String(F->get().arguments[i].class_name); + d3["name"] = F.arguments[i].name; + Variant::Type type = F.arguments[i].type; + if (F.arguments[i].class_name != StringName()) { + d3["type"] = String(F.arguments[i].class_name); } else if (type == Variant::NIL) { d3["type"] = "Variant"; } else { @@ -728,28 +723,28 @@ Dictionary NativeExtensionAPIDump::generate_extension_api() { Array properties; List<PropertyInfo> property_list; ClassDB::get_property_list(class_name, &property_list, true); - for (List<PropertyInfo>::Element *F = property_list.front(); F; F = F->next()) { - if (F->get().usage & PROPERTY_USAGE_CATEGORY || F->get().usage & PROPERTY_USAGE_GROUP || F->get().usage & PROPERTY_USAGE_SUBGROUP) { + for (PropertyInfo &F : property_list) { + if (F.usage & PROPERTY_USAGE_CATEGORY || F.usage & PROPERTY_USAGE_GROUP || F.usage & PROPERTY_USAGE_SUBGROUP) { continue; //not real properties } - if (F->get().name.begins_with("_")) { + if (F.name.begins_with("_")) { continue; //hidden property } - StringName property_name = F->get().name; + StringName property_name = F.name; Dictionary d2; d2["name"] = String(property_name); - if (F->get().class_name != StringName()) { - d2["type"] = String(F->get().class_name); - } else if (F->get().type == Variant::NIL && F->get().usage & PROPERTY_USAGE_NIL_IS_VARIANT) { + if (F.class_name != StringName()) { + d2["type"] = String(F.class_name); + } else if (F.type == Variant::NIL && F.usage & PROPERTY_USAGE_NIL_IS_VARIANT) { d2["type"] = "Variant"; } else { - d2["type"] = Variant::get_type_name(F->get().type); + d2["type"] = Variant::get_type_name(F.type); } - d2["setter"] = ClassDB::get_property_setter(class_name, F->get().name); - d2["getter"] = ClassDB::get_property_getter(class_name, F->get().name); - d2["index"] = ClassDB::get_property_index(class_name, F->get().name); + d2["setter"] = ClassDB::get_property_setter(class_name, F.name); + d2["getter"] = ClassDB::get_property_getter(class_name, F.name); + d2["index"] = ClassDB::get_property_index(class_name, F.name); properties.push_back(d2); } @@ -771,8 +766,7 @@ Dictionary NativeExtensionAPIDump::generate_extension_api() { List<Engine::Singleton> singleton_list; Engine::get_singleton()->get_singletons(&singleton_list); - for (List<Engine::Singleton>::Element *E = singleton_list.front(); E; E = E->next()) { - const Engine::Singleton &s = E->get(); + for (Engine::Singleton &s : singleton_list) { Dictionary d; d["name"] = s.name; if (s.class_name != StringName()) { diff --git a/core/extension/native_extension.cpp b/core/extension/native_extension.cpp index 65718a7507..5f91e61102 100644 --- a/core/extension/native_extension.cpp +++ b/core/extension/native_extension.cpp @@ -351,8 +351,8 @@ RES NativeExtensionResourceLoader::load(const String &p_path, const String &p_or String library_path; - for (List<String>::Element *E = libraries.front(); E; E = E->next()) { - Vector<String> tags = E->get().split("."); + for (String &E : libraries) { + Vector<String> tags = E.split("."); bool all_tags_met = true; for (int i = 0; i < tags.size(); i++) { String tag = tags[i].strip_edges(); @@ -363,7 +363,7 @@ RES NativeExtensionResourceLoader::load(const String &p_path, const String &p_or } if (all_tags_met) { - library_path = config->get_value("libraries", E->get()); + library_path = config->get_value("libraries", E); break; } } diff --git a/core/input/gamecontrollerdb.txt b/core/input/gamecontrollerdb.txt index 884fb9550c..f136d83496 100644 --- a/core/input/gamecontrollerdb.txt +++ b/core/input/gamecontrollerdb.txt @@ -4,19 +4,24 @@ # Windows 03000000fa2d00000100000000000000,3DRUDDER,leftx:a0,lefty:a1,rightx:a5,righty:a2,platform:Windows, 03000000c82d00002038000000000000,8bitdo,a:b1,b:b0,back:b10,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b2,leftshoulder:b6,leftstick:b13,lefttrigger:b8,leftx:a0,lefty:a1,rightshoulder:b7,rightstick:b14,righttrigger:b9,rightx:a3,righty:a4,start:b11,x:b4,y:b3,platform:Windows, +03000000c82d00000951000000000000,8BitDo Dogbone Modkit,a:b1,b:b0,back:b10,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,start:b11,platform:Windows, 03000000c82d000011ab000000000000,8BitDo F30,a:b1,b:b0,back:b10,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b2,leftshoulder:b6,leftstick:b13,lefttrigger:b8,leftx:a0,lefty:a1,rightshoulder:b7,rightstick:b14,righttrigger:b9,rightx:a3,righty:a4,start:b11,x:b4,y:b3,platform:Windows, 03000000c82d00001038000000000000,8BitDo F30 Pro,a:b1,b:b0,back:b10,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b2,leftshoulder:b6,leftstick:b13,lefttrigger:b8,leftx:a0,lefty:a1,rightshoulder:b7,rightstick:b14,righttrigger:b9,rightx:a2,righty:a5,start:b11,x:b4,y:b3,platform:Windows, 03000000c82d00000090000000000000,8BitDo FC30 Pro,a:b1,b:b0,back:b10,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b2,leftshoulder:b6,leftstick:b13,lefttrigger:b8,leftx:a0,lefty:a1,rightshoulder:b7,rightstick:b14,righttrigger:b9,rightx:a3,righty:a4,start:b11,x:b4,y:b3,platform:Windows, 03000000c82d00000650000000000000,8BitDo M30,a:b0,b:b1,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:a4,lefttrigger:a5,leftx:a0,lefty:a1,rightshoulder:b6,righttrigger:b7,start:b11,x:b3,y:b4,platform:Windows, 03000000c82d00005106000000000000,8BitDo M30 Gamepad,a:b1,b:b0,back:b10,guide:b2,leftshoulder:b6,lefttrigger:b8,leftx:a0,lefty:a1,rightshoulder:b7,righttrigger:b9,start:b11,x:b4,y:b3,platform:Windows, +03000000c82d00000151000000000000,8BitDo M30 ModKit,a:b0,b:b1,back:b10,dpdown:+a2,dpleft:-a0,dpright:+a0,dpup:-a2,rightshoulder:b6,righttrigger:b7,start:b11,x:b3,y:b4,platform:Windows, 03000000c82d00000310000000000000,8BitDo N30,a:b0,b:b1,back:b10,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b6,leftx:a0,lefty:a1,rightshoulder:b7,start:b11,x:b3,y:b4,platform:Windows, 03000000c82d00002028000000000000,8BitDo N30,a:b1,b:b0,back:b10,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b2,leftshoulder:b6,leftstick:b13,lefttrigger:b8,leftx:a0,lefty:a1,rightshoulder:b7,rightstick:b14,righttrigger:b9,rightx:a2,righty:a5,start:b11,x:b4,y:b3,platform:Windows, 03000000c82d00008010000000000000,8BitDo N30,a:b0,b:b1,back:b10,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b6,leftx:a0,lefty:a1,rightshoulder:b7,start:b11,x:b3,y:b4,platform:Windows, +03000000c82d00000451000000000000,8BitDo N30 Modkit,a:b1,b:b0,back:b10,dpdown:+a2,dpleft:-a0,dpright:+a0,dpup:-a2,start:b11,platform:Windows, 03000000c82d00000190000000000000,8BitDo N30 Pro,a:b1,b:b0,back:b10,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b2,leftshoulder:b6,leftstick:b13,lefttrigger:b8,leftx:a0,lefty:a1,rightshoulder:b7,rightstick:b14,righttrigger:b9,rightx:a3,righty:a4,start:b11,x:b4,y:b3,platform:Windows, 03000000c82d00001590000000000000,8BitDo N30 Pro 2,a:b1,b:b0,back:b10,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b2,leftshoulder:b6,leftstick:b13,lefttrigger:b8,leftx:a0,lefty:a1,rightshoulder:b7,rightstick:b14,righttrigger:b9,rightx:a2,righty:a5,start:b11,x:b4,y:b3,platform:Windows, 03000000c82d00006528000000000000,8BitDo N30 Pro 2,a:b1,b:b0,back:b10,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b2,leftshoulder:b6,leftstick:b13,lefttrigger:b8,leftx:a0,lefty:a1,rightshoulder:b7,rightstick:b14,righttrigger:b9,rightx:a3,righty:a4,start:b11,x:b4,y:b3,platform:Windows, 03000000022000000090000000000000,8Bitdo NES30 Pro,a:b1,b:b0,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:a3,righty:a4,start:b11,x:b4,y:b3,platform:Windows, 03000000203800000900000000000000,8Bitdo NES30 Pro,a:b1,b:b0,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:a3,righty:a4,start:b11,x:b4,y:b3,platform:Windows, +03000000c82d00000360000000000000,8BitDo Pro 2,a:b1,b:b0,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:a3,righty:a4,start:b11,x:b4,y:b3,platform:Windows, +03000000c82d00002867000000000000,8BitDo S30 Modkit,a:b0,b:b1,dpdown:+a2,dpleft:-a0,dpright:+a0,dpup:-a2,leftshoulder:b8,lefttrigger:b9,rightshoulder:b6,righttrigger:b7,start:b11,x:b3,y:b4,platform:Windows, 03000000c82d00000130000000000000,8BitDo SF30,a:b1,b:b0,back:b10,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b2,leftshoulder:b6,leftstick:b13,lefttrigger:b8,leftx:a0,lefty:a1,rightshoulder:b7,rightstick:b14,righttrigger:b9,rightx:a2,righty:a5,start:b11,x:b4,y:b3,platform:Windows, 03000000c82d00000060000000000000,8Bitdo SF30 Pro,a:b1,b:b0,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:b4,y:b3,platform:Windows, 03000000c82d00000061000000000000,8Bitdo SF30 Pro,a:b1,b:b0,back:b10,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b2,leftshoulder:b6,leftstick:b13,lefttrigger:b8,leftx:a0,lefty:a1,rightshoulder:b7,rightstick:b14,righttrigger:b9,rightx:a2,righty:a3,start:b11,x:b4,y:b3,platform:Windows, @@ -24,19 +29,22 @@ 03000000102800000900000000000000,8Bitdo SFC30 GamePad,a:b1,b:b0,back:b10,leftshoulder:b6,leftx:a0,lefty:a1,rightshoulder:b7,start:b11,x:b4,y:b3,platform:Windows, 03000000c82d00003028000000000000,8Bitdo SFC30 GamePad,a:b1,b:b0,back:b10,leftshoulder:b6,leftx:a0,lefty:a1,rightshoulder:b7,start:b11,x:b4,y:b3,platform:Windows, 03000000c82d00000030000000000000,8BitDo SN30,a:b1,b:b0,back:b10,leftshoulder:b6,leftx:a0,lefty:a1,rightshoulder:b7,start:b11,x:b4,y:b3,platform:Windows, -03000000c82d00000351000000000000,8BitDo SN30,a:b1,b:b0,back:b10,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b2,leftshoulder:b6,leftstick:b13,lefttrigger:b8,leftx:a0,lefty:a1,rightshoulder:b7,rightstick:b14,righttrigger:b9,rightx:a2,righty:a5,start:b11,x:b4,y:b3,platform:Windows, 03000000c82d00001290000000000000,8BitDo SN30,a:b1,b:b0,back:b10,dpdown:+a1,dpleft:-a0,dpright:+a0,dpup:-a1,leftshoulder:b6,rightshoulder:b7,start:b11,x:b4,y:b3,platform:Windows, 03000000c82d000020ab000000000000,8BitDo SN30,a:b1,b:b0,back:b10,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b2,leftshoulder:b6,leftstick:b13,lefttrigger:b8,leftx:a0,lefty:a1,rightshoulder:b7,rightstick:b14,righttrigger:b9,rightx:a2,righty:a5,start:b11,x:b4,y:b3,platform:Windows, 03000000c82d00004028000000000000,8BitDo SN30,a:b1,b:b0,back:b10,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b2,leftshoulder:b6,leftstick:b13,lefttrigger:b8,leftx:a0,lefty:a1,rightshoulder:b7,rightstick:b14,righttrigger:b9,rightx:a2,righty:a5,start:b11,x:b4,y:b3,platform:Windows, 03000000c82d00006228000000000000,8BitDo SN30,a:b1,b:b0,back:b10,dpdown:+a1,dpleft:-a0,dpright:+a0,dpup:-a1,leftshoulder:b6,rightshoulder:b7,start:b11,x:b4,y:b3,platform:Windows, +03000000c82d00000351000000000000,8BitDo SN30 Modkit,a:b1,b:b0,back:b10,dpdown:+a2,dpleft:-a0,dpright:+a0,dpup:-a2,leftshoulder:b6,rightshoulder:b7,start:b11,x:b4,y:b3,platform:Windows, 03000000c82d00000160000000000000,8BitDo SN30 Pro,a:b1,b:b0,back:b10,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b2,leftshoulder:b6,leftstick:b13,lefttrigger:b8,leftx:a0,lefty:a1,rightshoulder:b7,rightstick:b14,righttrigger:b9,rightx:a2,righty:a3,start:b11,x:b4,y:b3,platform:Windows, 03000000c82d00000161000000000000,8BitDo SN30 Pro,a:b1,b:b0,back:b10,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b2,leftshoulder:b6,leftstick:b13,lefttrigger:b8,leftx:a0,lefty:a1,rightshoulder:b7,rightstick:b14,righttrigger:b9,rightx:a2,righty:a3,start:b11,x:b4,y:b3,platform:Windows, +03000000c82d00000121000000000000,8BitDo SN30 Pro for Android,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:a3,righty:a4,start:b11,x:b3,y:b4,platform:Windows, 03000000c82d00000260000000000000,8BitDo SN30 Pro+,a:b1,b:b0,back:b10,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b2,leftshoulder:b6,leftstick:b13,lefttrigger:b8,leftx:a0,lefty:a1,rightshoulder:b7,rightstick:b14,righttrigger:b9,rightx:a2,righty:a3,start:b11,x:b4,y:b3,platform:Windows, 03000000c82d00000261000000000000,8BitDo SN30 Pro+,a:b1,b:b0,back:b10,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b2,leftshoulder:b6,leftstick:b13,lefttrigger:b8,leftx:a0,lefty:a1,rightshoulder:b7,rightstick:b14,righttrigger:b9,rightx:a2,righty:a3,start:b11,x:b4,y:b3,platform:Windows, 03000000c82d00000031000000000000,8BitDo Wireless Adapter,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:a3,righty:a4,start:b11,x:b3,y:b4,platform:Windows, 03000000c82d00001890000000000000,8BitDo Zero 2,a:b1,b:b0,back:b10,leftshoulder:b6,leftx:a0,lefty:a1,rightshoulder:b7,start:b11,x:b4,y:b3,platform:Windows, 03000000c82d00003032000000000000,8BitDo Zero 2,a:b1,b:b0,back:b10,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b6,leftx:a0,lefty:a1,rightshoulder:b7,rightx:a2,righty:a3,start:b11,x:b4,y:b3,platform:Windows, 03000000a00500003232000000000000,8Bitdo Zero GamePad,a:b0,b:b1,back:b10,dpdown:+a2,dpleft:-a0,dpright:+a0,dpup:-a2,leftshoulder:b6,rightshoulder:b7,start:b11,x:b3,y:b4,platform:Windows, +03000000a30c00002700000000000000,Astro City Mini,a:b2,b:b1,back:b8,leftx:a3,lefty:a4,rightshoulder:b4,righttrigger:b5,start:b9,x:b3,y:b0,platform:Windows, +03000000a30c00002800000000000000,Astro City Mini,a:b2,b:b1,back:b8,leftx:a3,lefty:a4,rightshoulder:b4,righttrigger:b5,start:b9,x:b3,y:b0,platform:Windows, 030000008f0e00001200000000000000,Acme GA-02,a:b0,b:b1,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:b2,y:b3,platform:Windows, 03000000c01100000355000011010000,ACRUX USB GAME PAD,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, 03000000fa190000f0ff000000000000,Acteck AGJ-3200,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, @@ -49,7 +57,9 @@ 030000006f0e00001901000000000000,Afterglow 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, 030000006f0e00001a01000000000000,Afterglow 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, 03000000d62000001d57000000000000,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, -03000000869800002400000000007801,Astro C40 TR,a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b10,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, +03000000491900001904000000000000,Amazon Luna Controller,a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b8,leftshoulder:b4,leftstick:b10,lefttrigger:a3,leftx:a0,lefty:a1,misc1:b9,rightshoulder:b5,rightstick:b11,righttrigger:a4,rightx:a2,righty:a5,start:b7,x:b2,y:b3,platform:Windows, +03000000710100001904000000000000,Amazon Luna Controller,a:b1,b:b0,back:b10,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b11,leftshoulder:b5,leftstick:b8,leftx:a0,lefty:a1,misc1:b9,rightshoulder:b4,rightstick:b7,rightx:a3,righty:a4,start:b6,x:b3,y:b2,platform:Windows, +03000000ef0500000300000000000000,AxisPad,a:b2,b:b3,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:a3,righty:a2,start:b11,x:b0,y:b1,platform:Windows, 03000000d6200000e557000000000000,Batarang,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, 03000000c01100001352000000000000,Battalife Joystick,a:b6,b:b7,back:b2,leftshoulder:b0,leftx:a0,lefty:a1,rightshoulder:b1,start:b3,x:b4,y:b5,platform:Windows, 030000006f0e00003201000000000000,Battlefield 4 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, @@ -65,7 +75,7 @@ 03000000808300000300000000000000,Betop 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:a4,start:b9,x:b3,y:b0,platform:Windows, 030000006b1400000055000000000000,Bigben PS3 Controller,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, 030000006b1400000103000000000000,Bigben PS3 Controller,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:b3,y:b2,platform:Windows, -03000000120c0000210e000000000000,Brook Mars,a:b1,b:b2,x:b0,y:b3,back:b8,guide:b12,start:b9,leftstick:b10,rightstick:b11,leftshoulder:b4,rightshoulder:b5,dpup:h0.1,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,leftx:a0,lefty:a1,rightx:a2,righty:a3,lefttrigger:b6,righttrigger:b7,platform:Windows, +03000000120c0000210e000000000000,Brook Mars,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, 0300000066f700000500000000000000,BrutalLegendTest,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:a2,start:b9,x:b0,y:b3,platform:Windows, 03000000d81d00000b00000000000000,BUFFALO BSGP1601 Series ,a:b5,b:b3,back:b12,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b8,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b9,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b13,x:b4,y:b2,platform:Windows, 03000000e82000006058000000000000,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:Windows, @@ -106,7 +116,6 @@ 03000000ac0500004d04000000000000,GameSir,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:a3,righty:a4,start:b11,x:b3,y:b4,platform:Windows, 03000000ffff00000000000000000000,GameStop 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:Windows, 03000000c01100000140000000000000,GameStop PS4 Fun 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, -030000006f0e00000102000000007801,GameStop Xbox 360 Wired Controller,a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b10,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, 030000009b2800003200000000000000,GC/N64 to USB v3.4,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,GC/N64 to USB v3.6,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, 030000008305000009a0000000000000,Genius,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:Windows, @@ -157,6 +166,7 @@ 030000007e0500000620000001000000,Joy-Con (L),+leftx:h0.2,+lefty:h0.4,-leftx:h0.8,-lefty:h0.1,a:b0,b:b1,back:b13,leftshoulder:b4,leftstick:b10,rightshoulder:b5,start:b8,x:b2,y:b3,platform:Windows, 030000007e0500000720000000000000,Joy-Con (R),+leftx:h0.2,+lefty:h0.4,-leftx:h0.8,-lefty:h0.1,a:b0,b:b1,back:b12,leftshoulder:b4,leftstick:b11,rightshoulder:b5,start:b9,x:b2,y:b3,platform:Windows, 030000007e0500000720000001000000,Joy-Con (R),+leftx:h0.2,+lefty:h0.4,-leftx:h0.8,-lefty:h0.1,a:b0,b:b1,back:b12,leftshoulder:b4,leftstick:b11,rightshoulder:b5,start:b9,x:b2,y:b3,platform:Windows, +03000000bd12000003c0000010010000,Joypad Alpha Shock,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, 03000000bd12000003c0000000000000,JY-P70UR,a:b1,b:b0,back:b5,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b6,leftstick:b10,lefttrigger:b7,leftx:a0,lefty:a1,rightshoulder:b8,rightstick:b11,righttrigger:b9,rightx:a3,righty:a2,start:b4,x:b3,y:b2,platform:Windows, 03000000242f00002d00000000000000,JYS Wireless Adapter,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:Windows, 03000000242f00008a00000000000000,JYS Wireless Adapter,a:b1,b:b4,back:b10,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b6,leftstick:b13,lefttrigger:b8,rightshoulder:b7,rightstick:b14,righttrigger:b9,rightx:a3,righty:a4,start:b11,x:b0,y:b3,platform:Windows, @@ -184,6 +194,7 @@ 03000000380700001888000000000000,MadCatz SFIV FightStick PS3,a:b0,b:b1,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b5,lefttrigger:b7,leftx:a0,lefty:a1,rightshoulder:b4,righttrigger:b6,rightx:a2,righty:a3,start:b9,x:b2,y:b3,platform:Windows, 03000000380700008081000000000000,MADCATZ SFV Arcade FightStick Alpha PS4,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,righttrigger:b7,rightx:a2,righty:a5,start:b9,x:b0,y:b3,platform:Windows, 030000002a0600001024000000000000,Matricom,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:a3,righty:a4,start:b9,x:b2,y:b3,platform:Windows, +030000009f000000adbb000000000000,MaxJoypad Virtual Controller,a:b1,b:b2,back:b9,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,righttrigger:b7,rightx:a2,righty:a3,start:b8,x:b3,y:b0,platform:Windows, 03000000250900000128000000000000,Mayflash Arcade Stick,a:b1,b:b2,back:b8,leftshoulder:b0,lefttrigger:b4,leftx:a0,lefty:a1,rightshoulder:b3,righttrigger:b7,start:b9,x:b5,y:b6,platform:Windows, 03000000790000004418000000000000,Mayflash GameCube Controller,a:b1,b:b2,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,lefttrigger:a3,leftx:a0,lefty:a1,rightshoulder:b7,righttrigger:a4,rightx:a5,righty:a2,start:b9,x:b0,y:b3,platform:Windows, 03000000790000004318000000000000,Mayflash GameCube Controller Adapter,a:b1,b:b2,back:b0,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b0,leftshoulder:b4,leftstick:b0,lefttrigger:a3,leftx:a0,lefty:a1,rightshoulder:b7,rightstick:b0,righttrigger:a4,rightx:a5,righty:a2,start:b9,x:b0,y:b3,platform:Windows, @@ -202,6 +213,8 @@ 03000000efbe0000edfe000000000000,Monect Virtual Controller,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:a2,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:a5,rightx:a3,righty:a4,start:b9,x:b3,y:b0,platform:Windows, 03000000250900006688000000000000,MP-8866 Super Dual Box,a:b2,b:b1,back:b9,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:b8,x:b3,y:b0,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, +03000000921200004b46000000000000,NES 2-port Adapter,a:b1,b:b0,back:b10,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,start:b11,platform:Windows, +03000000790000004518000000000000,NEXILUX GAMECUBE Controller Adapter,platform:Windows,a:b1,b:b0,x:b2,y:b3,start:b9,rightshoulder:b7,dpup:h0.1,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,leftx:a0,lefty:a1,rightx:a5,righty:a2,lefttrigger:a3,righttrigger:a4, 030000001008000001e5000000000000,NEXT SNES Controller,a:b2,b:b1,back:b8,dpdown:+a1,dpleft:-a0,dpright:+a0,dpup:-a1,leftshoulder:b4,rightshoulder:b5,righttrigger:b6,start:b9,x:b3,y:b0,platform:Windows, 03000000152000000182000000000000,NGDS,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:a3,righty:a4,start:b9,x:b3,y:b0,platform:Windows, 03000000bd12000015d0000000000000,Nintendo Retrolink USB Super SNES Classic Controller,a:b2,b:b1,back:b8,leftshoulder:b4,leftx:a0,lefty:a1,rightshoulder:b5,start:b9,x:b3,y:b0,platform:Windows, @@ -217,6 +230,7 @@ 030000006f0e00000901000000000000,PDP Versus Fighting Pad,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:Windows, 030000008f0e00000300000000000000,Piranha xtreme,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:a3,righty:a2,start:b9,x:b3,y:b0,platform:Windows, 030000004c050000da0c000000000000,PlayStation Classic Controller,a:b2,b:b1,back:b8,dpdown:+a1,dpleft:-a0,dpright:+a0,dpup:-a1,leftshoulder:b6,lefttrigger:b4,rightshoulder:b7,righttrigger:b5,start:b9,x:b3,y:b0,platform:Windows, +030000004c0500003713000000000000,PlayStation Vita,a:b1,b:b2,back:b8,dpdown:b13,dpleft:b15,dpright:b14,dpup:b12,leftshoulder:b4,leftx:a0,lefty:a1,rightshoulder:b5,rightx:a3,righty:a4,start:b9,x:b0,y:b3,platform:Windows, 03000000d62000006dca000000000000,PowerA Pro Ex,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, 03000000d62000009557000000000000,Pro Elite 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, 03000000d62000009f31000000000000,Pro Ex mini 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, @@ -241,6 +255,7 @@ 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: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, 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:b13,rightshoulder:b5,rightstick:b11,righttrigger:a4,rightx:a2,righty:a5,start:b9,x:b0,y:b3,platform:Windows, +03000000ff000000cb01000000000000,PSP,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:Windows, 03000000300f00000011000000000000,QanBa Arcade JoyStick 1008,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,righttrigger:b7,start:b10,x:b0,y:b3,platform:Windows, 03000000300f00001611000000000000,QanBa Arcade JoyStick 4018,a:b1,b:b2,back:b10,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b9,leftshoulder:b4,lefttrigger:b6,rightshoulder:b5,righttrigger:b7,start:b8,x:b0,y:b3,platform:Windows, 03000000222c00000020000000000000,QANBA DRONE ARCADE JOYSTICK,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,lefttrigger:a3,rightshoulder:b5,righttrigger:a4,start:b9,x:b0,y:b3,platform:Windows, @@ -292,7 +307,6 @@ 030000009b2800000500000000000000,Saturn_Adapter_2.0,a:b1,b:b2,leftshoulder:b6,lefttrigger:b4,leftx:a0,lefty:a1,rightshoulder:b7,righttrigger:b5,start:b9,x:b0,y:b3,platform:Windows, 03000000a30c00002500000000000000,Sega Genesis Mini 3B controller,a:b2,b:b1,dpdown:+a4,dpleft:-a3,dpright:+a3,dpup:-a4,righttrigger:b5,start:b9,platform:Windows, 03000000a30c00002400000000000000,Sega Mega Drive Mini 6B controller,a:b2,b:b1,dpdown:+a4,dpleft:-a3,dpright:+a3,dpup:-a4,rightshoulder:b4,righttrigger:b5,start:b9,x:b3,y:b0,platform:Windows, -030000005e0400008e02000000007801,ShanWan PS3/PC Wired GamePad,a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b10,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, 03000000341a00000208000000000000,SL-6555-SBK,a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b8,lefttrigger:-a4,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b9,righttrigger:a4,rightx:a3,righty:a2,start:b7,x:b2,y:b3,platform:Windows, 03000000341a00000908000000000000,SL-6566,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:Windows, 030000008f0e00000800000000000000,SpeedLink Strike FX,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, @@ -337,8 +351,7 @@ 030000006f0e00000702000000000000,Victrix Pro Fight Stick for PS4,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,righttrigger:b7,start:b9,x:b0,y:b3,platform:Windows, 0300000034120000adbe000000000000,vJoy Device,a:b0,b:b1,back:b15,dpdown:b6,dpleft:b7,dpright:b8,dpup:b5,guide:b16,leftshoulder:b9,leftstick:b13,lefttrigger:b11,leftx:a0,lefty:a1,rightshoulder:b10,rightstick:b14,righttrigger:b12,rightx:a3,righty:a4,start:b4,x:b2,y:b3,platform:Windows, 030000005e0400000a0b000000000000,Xbox Adaptive Controller,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, -030000005e040000ff02000000007801,Xbox One Elite Controller,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, -030000005e040000130b000000000000,Xbox Series Controller,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, +030000005e040000130b000000000000,Xbox Series Controller,a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b10,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, 03000000341a00000608000000000000,Xeox,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, 03000000450c00002043000000000000,XEOX Gamepad SL-6556-BK,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:Windows, 03000000ac0500005b05000000000000,Xiaoji Gamesir-G3w,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:Windows, @@ -362,6 +375,7 @@ xinput,XInput Controller,a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2, 03000000c82d00000190000001000000,8Bitdo NES30 Pro,a:b1,b:b0,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:b4,y:b3,platform:Mac OS X, 03000000102800000900000000000000,8Bitdo SFC30 GamePad Joystick,a:b1,b:b0,back:b10,leftshoulder:b6,leftx:a0,lefty:a1,rightshoulder:b7,start:b11,x:b4,y:b3,platform:Mac OS X, 03000000c82d00001290000001000000,8BitDo SN30 Gamepad,a:b1,b:b0,back:b10,leftshoulder:b6,leftx:a0,lefty:a1,rightshoulder:b7,start:b11,x:b4,y:b3,platform:Mac OS X, +03000000c82d00004028000000010000,8Bitdo SN30 GamePad,a:b1,b:b0,x:b4,y:b3,back:b10,start:b11,leftshoulder:b6,rightshoulder:b7,dpup:-a1,dpdown:+a1,dpleft:-a0,dpright:+a0,platform:Mac OS X, 03000000c82d00000160000001000000,8BitDo SN30 Pro,a:b1,b:b0,back:b10,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b6,leftstick:b13,lefttrigger:a4,leftx:a0,lefty:a1,rightshoulder:b7,rightstick:b14,righttrigger:a5,rightx:a2,righty:a3,start:b11,x:b4,y:b3,platform:Mac OS X, 03000000c82d00000161000000010000,8BitDo SN30 Pro,a:b1,b:b0,back:b10,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b2,leftshoulder:b6,leftstick:b13,lefttrigger:b8,leftx:a0,lefty:a1,rightshoulder:b7,rightstick:b14,righttrigger:b9,rightx:a2,righty:a5,start:b11,x:b4,y:b3,platform:Mac OS X, 03000000c82d00000260000001000000,8BitDo SN30 Pro+,a:b1,b:b0,back:b10,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b2,leftshoulder:b6,leftstick:b13,lefttrigger:b8,leftx:a0,lefty:a1,rightshoulder:b7,rightstick:b14,righttrigger:b9,rightx:a2,righty:a3,start:b11,x:b4,y:b3,platform:Mac OS X, @@ -371,21 +385,28 @@ xinput,XInput Controller,a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2, 03000000c82d00003032000000010000,8BitDo Zero 2,a:b1,b:b0,back:b10,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b6,leftx:a0,lefty:a1,rightshoulder:b7,rightx:a2,righty:a31,start:b11,x:b4,y:b3,platform:Mac OS X, 03000000a00500003232000008010000,8Bitdo Zero GamePad,a:b0,b:b1,back:b10,dpdown:+a1,dpleft:-a0,dpright:+a0,dpup:-a1,leftshoulder:b6,rightshoulder:b7,start:b11,x:b3,y:b4,platform:Mac OS X, 03000000a00500003232000009010000,8Bitdo Zero GamePad,a:b0,b:b1,back:b10,dpdown:+a1,dpleft:-a0,dpright:+a0,dpup:-a1,leftshoulder:b6,rightshoulder:b7,start:b11,x:b3,y:b4,platform:Mac OS X, +03000000a30c00002700000003030000,Astro City Mini,a:b2,b:b1,back:b8,leftx:a3,lefty:a4,rightshoulder:b4,righttrigger:b5,start:b9,x:b3,y:b0,platform:Mac OS X, +03000000a30c00002800000003030000,Astro City Mini,a:b2,b:b1,back:b8,leftx:a3,lefty:a4,rightshoulder:b4,righttrigger:b5,start:b9,x:b3,y:b0,platform:Mac OS X, 03000000050b00000045000031000000,ASUS Gamepad,a:b0,b:b1,back:b10,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b7,lefttrigger:a5,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b8,righttrigger:a4,rightx:a2,righty:a3,start:b9,x:b2,y:b3,platform:Mac OS X, +03000000ef0500000300000000020000,AxisPad,a:b2,b:b3,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:a3,righty:a2,start:b11,x:b0,y:b1,platform:Mac OS X, +03000000491900001904000001010000,Amazon Luna Controller,a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b8,leftshoulder:b4,leftstick:b10,lefttrigger:a3,leftx:a0,lefty:a1,misc1:b9,rightshoulder:b5,rightstick:b11,righttrigger:a4,rightx:a2,righty:a5,start:b7,x:b2,y:b3,platform:Mac OS X, +03000000710100001904000000010000,Amazon Luna Controller,a:b0,b:b1,back:b11,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b10,leftshoulder:b4,leftstick:b7,lefttrigger:a5,leftx:a0,lefty:a1,misc1:b9,rightshoulder:b5,rightstick:b8,righttrigger:a4,rightx:a2,righty:a3,start:b6,x:b2,y:b3,platform:Mac OS X, 03000000c62400001a89000000010000,BDA MOGA XP5-X Plus,a:b0,b:b1,back:b12,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b14,leftshoulder:b6,leftstick:b15,lefttrigger:a5,leftx:a0,lefty:a1,rightshoulder:b7,rightstick:b16,righttrigger:a4,rightx:a2,righty:a3,start:b13,x:b3,y:b4,platform:Mac OS X, 03000000c62400001b89000000010000,BDA MOGA XP5-X Plus,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:Mac OS X, 03000000d62000002a79000000010000,BDA PS4 Fightpad,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, -03000000120c0000200e000000010000,Brook Mars,a:b1,b:b2,x:b0,y:b3,back:b8,guide:b12,start:b9,leftstick:b10,rightstick:b11,leftshoulder:b4,rightshoulder:b5,dpup:h0.1,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,leftx:a0,lefty:a1,rightx:a2,righty:a5,lefttrigger:a3,righttrigger:a4,platform:Mac OS X, -03000000120c0000210e000000010000,Brook Mars,a:b1,b:b2,x:b0,y:b3,back:b8,guide:b12,start:b9,leftstick:b10,rightstick:b11,leftshoulder:b4,rightshoulder:b5,dpup:h0.1,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,leftx:a0,lefty:a1,rightx:a2,righty:a3,lefttrigger:b6,righttrigger:b7,platform:Mac OS X, +03000000120c0000200e000000010000,Brook Mars,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, +03000000120c0000210e000000010000,Brook Mars,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, 030000008305000031b0000000000000,Cideko AK08b,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:Mac OS X, 03000000260900008888000088020000,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:Mac OS X, 03000000a306000022f6000001030000,Cyborg V.3 Rumble Pad,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:Mac OS X, +03000000790000004618000000010000,GameCube Controller Adapter,a:b4,b:b0,dpdown:b56,dpleft:b60,dpright:b52,dpup:b48,lefttrigger:a12,leftx:a0,lefty:a4,rightshoulder:b28,righttrigger:a16,rightx:a20,righty:a8,start:b36,x:b8,y:b12,platform:Mac OS X, 03000000ad1b000001f9000000000000,Gamestop BB-070 X360 Controller,a:b0,b:b1,back:b9,dpdown:b12,dpleft:b13,dpright:b14,dpup:b11,guide:b10,leftshoulder:b4,leftstick:b6,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b7,righttrigger:a5,rightx:a3,righty:a4,start:b8,x:b2,y:b3,platform:Mac OS X, 0500000047532047616d657061640000,GameStop 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:Mac OS X, 03000000c01100000140000000010000,GameStop PS4 Fun 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, 030000006f0e00000102000000000000,GameStop Xbox 360 Wired Controller,a:b0,b:b1,back:b9,dpdown:b12,dpleft:b13,dpright:b14,dpup:b11,guide:b10,leftshoulder:b4,leftstick:b6,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b7,righttrigger:a5,rightx:a3,righty:a4,start:b8,x:b2,y:b3,platform:Mac OS X, 030000007d0400000540000001010000,Gravis Eliminator GamePad Pro,a:b1,b:b2,back:b8,leftshoulder:b4,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,righttrigger:b7,start:b9,x:b0,y:b3,platform:Mac OS X, -030000008f0e00000300000007010000,GreenAsia Inc. USB Joystick,a:b2,b:b3,x:b0,y:b1,back:b8,start:b9,leftshoulder:b4,rightshoulder:b6,dpup:h0.1,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,leftx:a0,lefty:a1,rightx:a3,righty:a2,lefttrigger:b5,righttrigger:b7,platform:Mac OS X, +03000000280400000140000000020000,Gravis Gamepad Pro,a:b1,b:b2,back:b8,dpdown:+a1,dpleft:-a0,dpright:+a0,dpup:-a1,leftshoulder:b4,lefttrigger:b6,rightshoulder:b5,righttrigger:b7,start:b9,x:b0,y:b3,platform:Mac OS X, +030000008f0e00000300000007010000,GreenAsia Inc. USB Joystick,a:b2,b:b3,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,lefttrigger:b5,leftx:a0,lefty:a1,rightshoulder:b6,righttrigger:b7,rightx:a3,righty:a2,start:b9,x:b0,y:b1,platform:Mac OS X, 030000000d0f00002d00000000100000,Hori Fighting Commander 3 Pro,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b0,y:b3,platform:Mac OS X, 030000000d0f00005f00000000010000,Hori Fighting Commander 4 (PS3),a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b0,y:b3,platform:Mac OS X, 030000000d0f00005e00000000010000,Hori Fighting Commander 4 (PS4),a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,lefttrigger:a3,leftx:a0,lefty:a1,rightshoulder:b5,righttrigger:a4,rightx:a2,righty:a5,start:b9,x:b0,y:b3,platform:Mac OS X, @@ -416,11 +437,13 @@ xinput,XInput Controller,a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2, 03000000380700005082000000010000,Mad Catz FightPad PRO (PS4),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, 03000000380700008433000000010000,Mad Catz FightStick TE S+ (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:Mac OS X, 03000000380700008483000000010000,Mad Catz FightStick TE S+ (PS4),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, +03000000790000000600000007010000,Marvo GT-004,a:b2,b:b1,x:b3,y:b0,back:b8,start:b9,leftstick:b10,rightstick:b11,leftshoulder:b4,rightshoulder:b5,dpup:h0.1,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,leftx:a0,lefty:a1,rightx:a2,righty:a3,lefttrigger:b6,righttrigger:b7,platform:Mac OS X, 03000000790000004418000000010000,Mayflash GameCube Controller,a:b1,b:b2,dpdown:b14,dpleft:b15,dpright:b13,dpup:b12,lefttrigger:a3,leftx:a0,lefty:a1,rightshoulder:b7,righttrigger:a4,rightx:a5,righty:a2,start:b9,x:b0,y:b3,platform:Mac OS X, 03000000242f00007300000000020000,Mayflash Magic NS,a:b1,b:b4,back:b10,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b6,leftstick:b13,lefttrigger:b8,rightshoulder:b7,rightstick:b14,righttrigger:b9,rightx:a2,righty:a3,start:b11,x:b0,y:b3,platform:Mac OS X, 0300000079000000d218000026010000,Mayflash Magic NS,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:Mac OS X, 03000000d620000010a7000003010000,Mayflash Magic NS,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, 0300000025090000e803000000000000,Mayflash Wii Classic Controller,a:b1,b:b0,back:b8,dpdown:b13,dpleft:b12,dpright:b14,dpup:b11,guide:b10,leftshoulder:b4,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b3,y:b2,platform:Mac OS X, +03000000790000000018000000010000,Mayflash Wii U Pro Controller Adapter,a:b4,b:b8,back:b32,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b16,leftstick:b40,lefttrigger:b24,leftx:a0,lefty:a4,rightshoulder:b20,rightstick:b44,righttrigger:b28,rightx:a8,righty:a12,start:b36,x:b0,y:b12,platform:Mac OS X, 03000000790000000018000000000000,Mayflash WiiU Pro Game Controller Adapter (DInput),a:b4,b:b8,back:b32,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b16,leftstick:b40,lefttrigger:b24,leftx:a0,lefty:a4,rightshoulder:b20,rightstick:b44,righttrigger:b28,rightx:a8,righty:a12,start:b36,x:b0,y:b12,platform:Mac OS X, 03000000d8140000cecf000000000000,MC Cthulhu,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,lefttrigger:b6,rightshoulder:b5,righttrigger:b7,start:b9,x:b0,y:b3,platform:Mac OS X, 030000005e0400002700000001010000,Microsoft SideWinder Plug & Play Game Pad,a:b0,b:b1,dpdown:+a1,dpleft:-a0,dpright:+a0,dpup:-a1,lefttrigger:b4,leftx:a0,lefty:a1,righttrigger:b5,x:b2,y:b3,platform:Mac OS X, @@ -428,15 +451,19 @@ xinput,XInput Controller,a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2, 03000000c62400002a89000000010000,MOGA XP5-A Plus,a:b0,b:b1,back:b10,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b21,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, 03000000c62400002b89000000010000,MOGA XP5-A Plus,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:Mac OS X, 03000000632500007505000000020000,NEOGEO mini PAD Controller,a:b1,b:b0,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,start:b9,x:b2,y:b3,platform:Mac OS X, +03000000921200004b46000003020000,NES 2-port Adapter,a:b1,b:b0,back:b10,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,start:b11,platform:Mac OS X, 030000001008000001e5000006010000,NEXT SNES Controller,a:b2,b:b1,back:b8,dpdown:+a1,dpleft:-a0,dpright:+a0,dpup:-a1,leftshoulder:b4,rightshoulder:b5,righttrigger:b6,start:b9,x:b3,y:b0,platform:Mac OS X, 03000000d620000011a7000000020000,Nintendo Switch Core (Plus) 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: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, +03000000d620000011a7000010050000,Nintendo Switch PowerA 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: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, 030000007e0500000920000000000000,Nintendo Switch Pro Controller,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:Mac OS X, 030000007e0500000920000001000000,Nintendo Switch Pro Controller,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:Mac OS X, 03000000550900001472000025050000,NVIDIA Controller v01.04,a:b0,b:b1,back:b17,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b15,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:Mac OS X, 030000006f0e00000901000002010000,PDP Versus Fighting Pad,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:Mac OS X, 030000008f0e00000300000000000000,Piranha xtreme,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:a3,righty:a2,start:b9,x:b3,y:b0,platform:Mac OS X, 030000004c050000da0c000000010000,Playstation Classic Controller,a:b2,b:b1,back:b8,leftshoulder:b6,lefttrigger:b4,leftx:a0,lefty:a1,rightshoulder:b7,righttrigger:b5,start:b9,x:b3,y:b0,platform:Mac OS X, +030000004c0500003713000000010000,PlayStation Vita,a:b1,b:b2,back:b8,dpdown:b13,dpleft:b15,dpright:b14,dpup:b12,leftshoulder:b4,leftx:a0,lefty:a1,rightshoulder:b5,rightx:a3,righty:a4,start:b9,x:b0,y:b3,platform:Mac OS X, 03000000d62000006dca000000010000,PowerA Pro Ex,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, +03000000100800000300000006010000,PS2 Adapter,a:b2,b:b1,back:b8,leftshoulder:b6,leftstick:b10,lefttrigger:b4,leftx:a0,lefty:a1,rightshoulder:b7,rightstick:b11,righttrigger:b5,rightx:a4,righty:a3,start:b9,x:b3,y:b0,platform:Mac OS X, 030000004c0500006802000000000000,PS3 Controller,a:b14,b:b13,back:b0,dpdown:b6,dpleft:b7,dpright:b5,dpup:b4,guide:b16,leftshoulder:b10,leftstick:b1,lefttrigger:b8,leftx:a0,lefty:a1,rightshoulder:b11,rightstick:b2,righttrigger:b9,rightx:a2,righty:a3,start:b3,x:b15,y:b12,platform:Mac OS X, 030000004c0500006802000000010000,PS3 Controller,a:b14,b:b13,back:b0,dpdown:b6,dpleft:b7,dpright:b5,dpup:b4,guide:b16,leftshoulder:b10,leftstick:b1,lefttrigger:b8,leftx:a0,lefty:a1,rightshoulder:b11,rightstick:b2,righttrigger:b9,rightx:a2,righty:a3,start:b3,x:b15,y:b12,platform:Mac OS X, 030000004c050000a00b000000010000,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, @@ -487,9 +514,11 @@ xinput,XInput Controller,a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2, 050000005769696d6f74652028303000,Wii Remote,a:b4,b:b5,back:b7,dpdown:b3,dpleft:b0,dpright:b1,dpup:b2,guide:b8,leftshoulder:b11,lefttrigger:b12,leftx:a0,lefty:a1,start:b6,x:b10,y:b9,platform:Mac OS X, 050000005769696d6f74652028313800,Wii U Pro Controller,a:b16,b:b15,back:b7,dpdown:b12,dpleft:b13,dpright:b14,dpup:b11,guide:b8,leftshoulder:b19,leftstick:b23,lefttrigger:b21,leftx:a0,lefty:a1,rightshoulder:b20,rightstick:b24,righttrigger:b22,rightx:a2,righty:a3,start:b6,x:b18,y:b17,platform:Mac OS X, 030000005e0400008e02000000000000,X360 Controller,a:b0,b:b1,back:b9,dpdown:b12,dpleft:b13,dpright:b14,dpup:b11,guide:b10,leftshoulder:b4,leftstick:b6,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b7,righttrigger:a5,rightx:a3,righty:a4,start:b8,x:b2,y:b3,platform:Mac OS X, +030000006f0e00000104000000000000,Xbox 360 Wired Controller,a:b0,b:b1,back:b9,dpdown:b12,dpleft:b13,dpright:b14,dpup:b11,guide:b10,leftshoulder:b4,leftstick:b6,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b7,righttrigger:a5,rightx:a3,righty:a4,start:b8,x:b2,y:b3,platform:Mac OS X, 03000000c6240000045d000000000000,Xbox 360 Wired Controller,a:b0,b:b1,back:b9,dpdown:b12,dpleft:b13,dpright:b14,dpup:b11,guide:b10,leftshoulder:b4,leftstick:b6,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b7,righttrigger:a5,rightx:a3,righty:a4,start:b8,x:b2,y:b3,platform:Mac OS X, 030000005e0400000a0b000000000000,Xbox Adaptive Controller,a:b0,b:b1,back:b9,dpdown:b12,dpleft:b13,dpright:b14,dpup:b11,guide:b10,leftshoulder:b4,leftstick:b6,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b7,righttrigger:a5,rightx:a3,righty:a4,start:b8,x:b2,y:b3,platform:Mac OS X, 030000005e040000050b000003090000,Xbox Elite Wireless Controller Series 2,a:b0,b:b1,back:b31,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b53,leftshoulder:b6,leftstick:b13,lefttrigger:a6,leftx:a0,lefty:a1,rightshoulder:b7,rightstick:b14,righttrigger:a5,rightx:a2,righty:a3,start:b11,x:b3,y:b4,platform:Mac OS X, +03000000c62400003a54000000000000,Xbox One PowerA Wired Controller,a:b0,b:b1,back:b9,dpdown:b12,dpleft:b13,dpright:b14,dpup:b11,guide:b10,leftshoulder:b4,leftstick:b6,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b7,righttrigger:a5,rightx:a3,righty:a4,start:b8,x:b2,y:b3,platform:Mac OS X, 030000005e040000d102000000000000,Xbox One Wired Controller,a:b0,b:b1,back:b9,dpdown:b12,dpleft:b13,dpright:b14,dpup:b11,guide:b10,leftshoulder:b4,leftstick:b6,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b7,righttrigger:a5,rightx:a3,righty:a4,start:b8,x:b2,y:b3,platform:Mac OS X, 030000005e040000dd02000000000000,Xbox One Wired Controller,a:b0,b:b1,back:b9,dpdown:b12,dpleft:b13,dpright:b14,dpup:b11,guide:b10,leftshoulder:b4,leftstick:b6,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b7,righttrigger:a5,rightx:a3,righty:a4,start:b8,x:b2,y:b3,platform:Mac OS X, 030000005e040000e302000000000000,Xbox One Wired Controller,a:b0,b:b1,back:b9,dpdown:b12,dpleft:b13,dpright:b14,dpup:b11,guide:b10,leftshoulder:b4,leftstick:b6,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b7,righttrigger:a5,rightx:a3,righty:a4,start:b8,x:b2,y:b3,platform:Mac OS X, @@ -545,18 +574,28 @@ xinput,XInput Controller,a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2, 03000000100000008200000011010000,Akishop Customs PS360+ v1.66,a:b1,b:b2,back:b12,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b8,leftshoulder:b4,lefttrigger:b6,rightshoulder:b5,righttrigger:b7,start:b9,x:b0,y:b3,platform:Linux, 030000007c1800000006000010010000,Alienware Dual Compatible Game Pad,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:a2,start:b9,x:b0,y:b3,platform:Linux, 05000000491900000204000021000000,Amazon Fire Game Controller,a:b0,b:b1,back:b10,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b17,leftshoulder:b6,leftstick:b13,lefttrigger:a5,leftx:a0,lefty:a1,misc1:b12,rightshoulder:b7,rightstick:b14,righttrigger:a4,rightx:a2,righty:a3,start:b11,x:b3,y:b4,platform:Linux, +03000000491900001904000011010000,Amazon Luna Controller,a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b8,leftshoulder:b4,leftstick:b10,lefttrigger:a3,leftx:a0,lefty:a1,misc1:b9,rightshoulder:b5,rightstick:b11,righttrigger:a4,rightx:a2,righty:a5,start:b7,x:b2,y:b3,platform:Linux, +05000000710100001904000000010000,Amazon Luna Controller,a:b0,b:b1,back:b9,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b10,leftshoulder:b4,leftstick:b7,lefttrigger:a5,leftx:a0,lefty:a1,misc1:b11,rightshoulder:b5,rightstick:b8,righttrigger:a4,rightx:a2,righty:a3,start:b6,x:b2,y:b3,platform:Linux, 03000000790000003018000011010000,Arcade Fightstick F300,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,righttrigger:b7,start:b9,x:b0,y:b3,platform:Linux, +03000000a30c00002700000011010000,Astro City Mini,a:b2,b:b1,back:b8,leftx:a0,lefty:a1,rightshoulder:b4,righttrigger:b5,start:b9,x:b3,y:b0,platform:Linux, +03000000a30c00002800000011010000,Astro City Mini,a:b2,b:b1,back:b8,leftx:a0,lefty:a1,rightshoulder:b4,righttrigger:b5,start:b9,x:b3,y:b0,platform:Linux, 05000000050b00000045000031000000,ASUS Gamepad,a:b0,b:b1,back:b9,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b6,leftshoulder:b4,leftstick:b7,lefttrigger:a5,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b8,righttrigger:a4,rightx:a2,righty:a3,start:b10,x:b2,y:b3,platform:Linux, 05000000050b00000045000040000000,ASUS Gamepad,a:b0,b:b1,back:b9,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b6,leftshoulder:b4,leftstick:b7,lefttrigger:a5,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b8,righttrigger:a4,rightx:a2,righty:a3,start:b10,x:b2,y:b3,platform:Linux, +03000000503200000110000000000000,Atari Classic Controller,a:b0,back:b2,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b4,start:b3,x:b1,platform:Linux, +05000000503200000110000000000000,Atari Classic Controller,a:b0,back:b2,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b4,start:b3,x:b1,platform:Linux, +03000000503200000210000000000000,Atari Game 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:b3,y:b2,platform:Linux, +05000000503200000210000000000000,Atari Game 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:b3,y:b2,platform:Linux, 03000000120c00000500000010010000,AxisPad,a:b2,b:b3,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:a3,righty:a2,start:b11,x:b0,y:b1,platform:Linux, +03000000ef0500000300000000010000,AxisPad,a:b2,b:b3,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:a3,righty:a2,start:b11,x:b0,y:b1,platform:Linux, 03000000c62400001b89000011010000,BDA MOGA XP5-X Plus,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, 03000000d62000002a79000011010000,BDA PS4 Fightpad,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, 03000000c21100000791000011010000,Be1 GC101 Controller 1.03 mode,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 GAMEPAD 1.03 mode,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 Controller mode,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, 03000000666600006706000000010000,boom PSX to PC Converter,a:b2,b:b1,back:b8,dpdown:b14,dpleft:b15,dpright:b13,dpup:b12,leftshoulder:b6,leftstick:b9,lefttrigger:b4,leftx:a0,lefty:a1,rightshoulder:b7,rightstick:b10,righttrigger:b5,rightx:a2,righty:a3,start:b11,x:b3,y:b0,platform:Linux, -03000000120c0000200e000011010000,Brook Mars,a:b1,b:b2,x:b0,y:b3,back:b8,guide:b12,start:b9,leftstick:b10,rightstick:b11,leftshoulder:b4,rightshoulder:b5,dpup:h0.1,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,leftx:a0,lefty:a1,rightx:a2,righty:a5,lefttrigger:a3,righttrigger:a4,platform:Linux, -03000000120c0000210e000011010000,Brook Mars,a:b1,b:b2,x:b0,y:b3,back:b8,guide:b12,start:b9,leftstick:b10,rightstick:b11,leftshoulder:b4,rightshoulder:b5,dpup:h0.1,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,leftx:a0,lefty:a1,rightx:a2,righty:a3,lefttrigger:b6,righttrigger:b7,platform:Linux, +03000000120c0000200e000011010000,Brook Mars,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,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, 03000000ffff0000ffff000000010000,Chinese-made Xbox Controller,a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b5,leftstick:b8,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b2,rightstick:b9,righttrigger:a5,rightx:a3,righty:a4,start:b7,x:b3,y:b4,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, 030000000b0400003365000000010000,Competition Pro,a:b0,b:b1,back:b2,leftx:a0,lefty:a1,start:b3,platform:Linux, @@ -621,6 +660,7 @@ xinput,XInput Controller,a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2, 050000007e0500000620000001000000,Joy-Con (L),+leftx:h0.2,+lefty:h0.4,-leftx:h0.8,-lefty:h0.1,a:b0,b:b1,back:b13,leftshoulder:b4,leftstick:b10,rightshoulder:b5,start:b8,x:b2,y:b3,platform:Linux, 030000007e0500000720000001000000,Joy-Con (R),+leftx:h0.2,+lefty:h0.4,-leftx:h0.8,-lefty:h0.1,a:b0,b:b1,back:b12,leftshoulder:b4,leftstick:b11,rightshoulder:b5,start:b9,x:b2,y:b3,platform:Linux, 050000007e0500000720000001000000,Joy-Con (R),+leftx:h0.2,+lefty:h0.4,-leftx:h0.8,-lefty:h0.1,a:b0,b:b1,back:b12,leftshoulder:b4,leftstick:b11,rightshoulder:b5,start:b9,x:b2,y:b3,platform:Linux, +03000000bd12000003c0000010010000,Joypad Alpha Shock,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, 03000000242f00002d00000011010000,JYS Wireless Adapter,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, 03000000242f00008a00000011010000,JYS Wireless Adapter,a:b1,b:b4,back:b10,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b6,leftstick:b13,lefttrigger:b8,rightshoulder:b7,rightstick:b14,righttrigger:b9,rightx:a2,righty:a3,start:b11,x:b0,y:b3,platform:Linux, 030000006f0e00000103000000020000,Logic3 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, @@ -650,8 +690,9 @@ xinput,XInput Controller,a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2, 03000000ad1b000016f0000090040000,Mad Catz Xbox 360 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, 03000000380700001888000010010000,MadCatz PC USB Wired Stick 8818,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b0,y:b3,platform:Linux, 03000000380700003888000010010000,MadCatz PC USB Wired Stick 8838,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:a0,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b0,y:b3,platform:Linux, +03000000242f0000f700000001010000,Magic-S Pro,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, 03000000120c00000500000000010000,Manta Dualshock 2,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:a3,righty:a2,start:b9,x:b2,y:b3,platform:Linux, -03000000790000004418000010010000,Mayflash GameCube Controller,a:b1,b:b2,dpdown:b14,dpleft:b15,dpright:b13,dpup:b12,lefttrigger:a3,leftx:a0,lefty:a1,rightshoulder:b7,righttrigger:a4,rightx:a5,righty:a2,start:b9,x:b0,y:b3,platform:Linux, +03000000790000004418000010010000,Mayflash GameCube Controller,a:b1,b:b0,dpdown:b14,dpleft:b15,dpright:b13,dpup:b12,lefttrigger:a3,leftx:a0,lefty:a1,rightshoulder:b7,righttrigger:a4,rightx:a5,righty:a2,start:b9,x:b2,y:b3,platform:Linux, 03000000790000004318000010010000,Mayflash GameCube Controller Adapter,a:b1,b:b2,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,lefttrigger:a3,leftx:a0,lefty:a1,rightshoulder:b7,righttrigger:a4,rightx:a5,righty:a2,start:b9,x:b0,y:b3,platform:Linux, 03000000242f00007300000011010000,Mayflash Magic NS,a:b1,b:b4,back:b10,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b6,leftstick:b13,lefttrigger:b8,rightshoulder:b7,rightstick:b14,righttrigger:b9,rightx:a2,righty:a3,start:b11,x:b0,y:b3,platform:Linux, 0300000079000000d218000011010000,Mayflash Magic NS,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, @@ -681,15 +722,18 @@ xinput,XInput Controller,a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2, 03000000250900006688000000010000,MP-8866 Super Dual Box,a:b2,b:b1,back:b9,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:b8,x:b3,y:b0,platform:Linux, 030000006b140000010c000010010000,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:Linux, 030000000d0f00000900000010010000,Natec Genesis P44,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, +03000000790000004518000010010000,NEXILUX GAMECUBE Controller Adapter,a:b1,b:b0,x:b2,y:b3,start:b9,rightshoulder:b7,dpup:h0.1,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,leftx:a0,lefty:a1,rightx:a5,righty:a2,lefttrigger:a3,righttrigger:a4,platform:Linux, 030000001008000001e5000010010000,NEXT SNES Controller,a:b2,b:b1,back:b8,dpdown:+a1,dpleft:-a0,dpright:+a0,dpup:-a1,leftshoulder:b4,rightshoulder:b5,righttrigger:b6,start:b9,x:b3,y:b0,platform:Linux, +060000007e0500003713000000000000,Nintendo 3DS,a:b0,b:b1,back:b8,dpdown:b11,dpleft:b12,dpright:b13,dpup:b10,leftshoulder:b4,leftx:a0,lefty:a1,rightshoulder:b5,rightx:a2,righty:a3,start:b9,x:b3,y:b2,platform:Linux, 060000007e0500000820000000000000,Nintendo Combined Joy-Cons (joycond),a:b0,b:b1,back:b9,dpdown:b15,dpleft:b16,dpright:b17,dpup:b14,guide:b11,leftshoulder:b5,leftstick:b12,lefttrigger:b7,leftx:a0,lefty:a1,rightshoulder:b6,rightstick:b13,righttrigger:b8,rightx:a2,righty:a3,start:b10,x:b3,y:b2,platform:Linux, 030000007e0500003703000000016800,Nintendo GameCube Controller,a:b0,b:b2,dpdown:b6,dpleft:b4,dpright:b5,dpup:b7,lefttrigger:a4,leftx:a0,lefty:a1~,rightshoulder:b9,righttrigger:a5,rightx:a2,righty:a3~,start:b8,x:b1,y:b3,platform:Linux, -03000000790000004618000010010000,Nintendo GameCube Controller Adapter,a:b1,b:b2,dpdown:b14,dpleft:b15,dpright:b13,dpup:b12,lefttrigger:b4,leftx:a0,lefty:a1,rightshoulder:b7,righttrigger:b5,rightx:a5~,righty:a2~,start:b9,x:b0,y:b3,platform:Linux, -050000007e0500000620000001800000,Nintendo Switch Left Joy-Con,a:b9,b:b8,x:b7,y:b10,back:b5,start:b0,leftstick:b6,leftshoulder:b2,rightshoulder:b4,leftx:a1,lefty:a0~,platform:Linux, -050000007e0500000720000001800000,Nintendo Switch Right Joy-Con,a:b1,b:b2,x:b0,y:b3,back:b9,start:b8,leftstick:b10,leftshoulder:b4,rightshoulder:b6,leftx:a1~,lefty:a0~,platform:Linux, +03000000790000004618000010010000,Nintendo GameCube Controller Adapter,a:b1,b:b0,dpdown:b14,dpleft:b15,dpright:b13,dpup:b12,lefttrigger:b4,leftx:a0,lefty:a1,rightshoulder:b7,righttrigger:b5,rightx:a5~,righty:a2~,start:b9,x:b2,y:b3,platform:Linux, +050000007e0500000620000001800000,Nintendo Switch Left Joy-Con,a:b9,b:b8,back:b5,leftshoulder:b2,leftstick:b6,leftx:a1,lefty:a0~,rightshoulder:b4,start:b0,x:b7,y:b10,platform:Linux, +030000007e0500000920000011810000,Nintendo Switch Pro Controller,a:b0,b:b1,back:b9,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b11,leftshoulder:b5,leftstick:b12,lefttrigger:b7,leftx:a0,lefty:a1,rightshoulder:b6,rightstick:b13,righttrigger:b8,rightx:a2,righty:a3,start:b10,x:b3,y:b2,platform:Linux, 050000007e0500000920000001000000,Nintendo Switch Pro Controller,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:Linux, 050000007e0500000920000001800000,Nintendo Switch Pro Controller,a:b0,b:b1,back:b9,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b11,leftshoulder:b5,leftstick:b12,lefttrigger:b7,leftx:a0,lefty:a1,rightshoulder:b6,rightstick:b13,righttrigger:b8,rightx:a2,righty:a3,start:b10,x:b3,y:b2,platform:Linux, -030000007e0500000920000011810000,Nintendo Switch Pro Controller,a:b0,b:b1,back:b9,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b11,leftshoulder:b5,leftstick:b12,lefttrigger:b7,leftx:a0,lefty:a1,rightshoulder:b6,rightstick:b13,righttrigger:b8,rightx:a2,righty:a3,start:b10,x:b3,y:b2,platform:Linux, +050000007e0500000720000001800000,Nintendo Switch Right Joy-Con,a:b1,b:b2,back:b9,leftshoulder:b4,leftstick:b10,leftx:a1~,lefty:a0~,rightshoulder:b6,start:b8,x:b0,y:b3,platform:Linux, +050000007e0500001720000001000000,Nintendo Switch SNES Controller,a:b0,b:b1,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,rightshoulder:b5,start:b9,x:b2,y:b3,platform:Linux, 050000007e0500003003000001000000,Nintendo Wii Remote Pro Controller,a:b0,b:b1,back:b8,dpdown:b14,dpleft:b15,dpright:b16,dpup:b13,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:b3,y:b2,platform:Linux, 05000000010000000100000003000000,Nintendo Wiimote,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, 030000000d0500000308000010010000,Nostromo n45 Dual Analog Gamepad,a:b0,b:b1,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b9,leftshoulder:b4,leftstick:b12,lefttrigger:b5,leftx:a0,lefty:a1,rightshoulder:b6,rightstick:b11,righttrigger:b7,rightx:a3,righty:a2,start:b10,x:b2,y:b3,platform:Linux, @@ -717,8 +761,9 @@ xinput,XInput Controller,a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2, 030000006f0e0000a802000023020000,PDP Wired Controller for Xbox One,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, 030000006f0e00008501000011010000,PDP Wired Fight Pad Pro for Nintendo Switch,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, 0500000049190000030400001b010000,PG-9099,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, -05000000491900000204000000000000,PG-9118,a:b73,b:b74,back:b83,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b79,leftstick:b86,lefttrigger:b81,leftx:a0,lefty:a1,rightshoulder:b80,rightstick:b87,righttrigger:b82,rightx:a2,righty:a3,start:b84,x:b76,y:b77,platform:Linux, +05000000491900000204000000000000,PG-9118,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, 030000004c050000da0c000011010000,Playstation Controller,a:b2,b:b1,back:b8,leftshoulder:b6,lefttrigger:b4,leftx:a0,lefty:a1,rightshoulder:b7,righttrigger:b5,start:b9,x:b3,y:b0,platform:Linux, +030000004c0500003713000011010000,PlayStation Vita,a:b1,b:b2,back:b8,dpdown:b13,dpleft:b15,dpright:b14,dpup:b12,leftshoulder:b4,leftx:a0,lefty:a1,rightshoulder:b5,rightx:a3,righty:a4,start:b9,x:b0,y:b3,platform:Linux, 03000000c62400000053000000010000,PowerA,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, 03000000c62400003a54000001010000,PowerA 1428124-01,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, 03000000d62000006dca000011010000,PowerA Pro Ex,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, @@ -734,6 +779,7 @@ xinput,XInput Controller,a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2, 030000004c0500006802000011810000,PS3 Controller,a:b0,b:b1,back:b8,dpdown:b14,dpleft:b15,dpright:b16,dpup:b13,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, 030000006f0e00001402000011010000,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, 030000008f0e00000300000010010000,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, +050000004c0500006802000000000000,PS3 Controller,a:b14,b:b13,back:b0,dpdown:b6,dpleft:b7,dpright:b5,dpup:b4,guide:b16,leftshoulder:b10,leftstick:b1,lefttrigger:b8,leftx:a0,lefty:a1,rightshoulder:b11,rightstick:b2,righttrigger:b9,rightx:a2,righty:a3,start:b3,x:b15,y:b12,platform:Linux, 050000004c0500006802000000010000,PS3 Controller,a:b14,b:b13,back:b0,dpdown:b6,dpleft:b7,dpright:b5,dpup:b4,guide:b16,leftshoulder:b10,leftstick:b1,lefttrigger:a12,leftx:a0,lefty:a1,rightshoulder:b11,rightstick:b2,righttrigger:a13,rightx:a2,righty:a3,start:b3,x:b15,y:b12,platform:Linux, 050000004c0500006802000000800000,PS3 Controller,a:b0,b:b1,back:b8,dpdown:b14,dpleft:b15,dpright:b16,dpup:b13,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, 050000004c0500006802000000810000,PS3 Controller,a:b0,b:b1,back:b8,dpdown:b14,dpleft:b15,dpright:b16,dpup:b13,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, @@ -755,7 +801,9 @@ xinput,XInput Controller,a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2, 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, 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:b13,rightshoulder:b5,rightstick:b11,righttrigger:a4,rightx:a2,righty:a5,start:b9,x:b0,y:b3,platform:Linux, 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,misc1:b13,rightshoulder:b5,rightstick:b11,righttrigger:a4,rightx:a2,righty:a5,start:b9,x:b0,y:b3,platform:Linux, +03000000ff000000cb01000010010000,PSP,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, 03000000300f00001211000011010000,QanBa Arcade JoyStick,a:b2,b:b0,back:b10,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b8,leftshoulder:b5,lefttrigger:b4,leftx:a0,lefty:a1,rightshoulder:b7,righttrigger:b6,start:b9,x:b1,y:b3,platform:Linux, +030000009b2800004200000001010000,Raphnet Technologies Dual NES to USB v2.0,a:b0,b:b1,back:b2,dpdown:+a1,dpleft:-a0,dpright:+a0,dpup:-a1,start:b3,platform:Linux, 030000009b2800003200000001010000,Raphnet Technologies GC/N64 to USB v3.4,a:b0,b:b7,dpdown:b11,dpleft:b12,dpright:b13,dpup:b10,lefttrigger:b4,leftx:a0,lefty:a1,rightshoulder:b2,righttrigger:b5,rightx:a3,righty:a4,start:b3,x:b1,y:b8,platform:Linux, 030000009b2800006000000001010000,Raphnet Technologies GC/N64 to USB v3.6,a:b0,b:b7,dpdown:b11,dpleft:b12,dpright:b13,dpup:b10,lefttrigger:b4,leftx:a0,lefty:a1,rightshoulder:b2,righttrigger:b5,rightx:a3,righty:a4,start:b3,x:b1,y:b8,platform:Linux, 030000009b2800000300000001010000,raphnet.net 4nes4snes v1.5,a:b0,b:b4,back:b2,leftshoulder:b6,leftx:a0,lefty:a1,rightshoulder:b7,start:b3,x:b1,y:b5,platform:Linux, @@ -792,7 +840,6 @@ xinput,XInput Controller,a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2, 03000000a306000018f5000010010000,Saitek PLC Saitek P3200 Rumble Pad,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b10,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a3,righty:a4,start:b9,x:b0,y:b3,platform:Linux, 03000000a306000020f6000011010000,Saitek PS2700 Rumble Pad,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:a4,start:b9,x:b0,y:b3,platform:Linux, 03000000d81d00000e00000010010000,Savior,a:b0,b:b1,back:b8,leftshoulder:b6,leftstick:b10,lefttrigger:b7,leftx:a0,lefty:a1,rightshoulder:b2,rightstick:b11,righttrigger:b3,start:b9,x:b4,y:b5,platform:Linux, -03000000c01600008704000011010000,Serial/Keyboard/Mouse/Joystick,a:b12,b:b10,back:b4,dpdown:b2,dpleft:b3,dpright:b1,dpup:b0,leftshoulder:b9,leftstick:b14,lefttrigger:b6,leftx:a1,lefty:a0,rightshoulder:b8,rightstick:b15,righttrigger:b7,rightx:a2,righty:a3,start:b5,x:b13,y:b11,platform:Linux, 03000000f025000021c1000010010000,ShanWan Gioteck PS3 Wired 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 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 PS3/PC Wired 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, @@ -800,17 +847,15 @@ xinput,XInput Controller,a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2, 03000000632500002305000010010000,ShanWan USB 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, 03000000341a00000908000010010000,SL-6566,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, 030000004c050000e60c000011810000,Sony DualSense,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, -030000004c050000e60c000000006800,Sony DualSense,a:b0,b:b1,x:b2,y:b3,back:b4,guide:b5,start:b6,leftstick:b7,rightstick:b8,leftshoulder:b9,rightshoulder:b10,dpup:b11,dpdown:b12,dpleft:b13,dpright:b14,leftx:a0,lefty:a1,rightx:a2,righty:a3,lefttrigger:a4,righttrigger:a5,platform:Linux, 050000004c050000e60c000000810000,Sony DualSense ,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, -030000004c050000e60c000000016800,Sony DualSense ,a:b0,b:b1,x:b2,y:b3,back:b4,guide:b5,start:b6,leftstick:b7,rightstick:b8,leftshoulder:b9,rightshoulder:b10,dpup:b11,dpdown:b12,dpleft:b13,dpright:b14,leftx:a0,lefty:a1,rightx:a2,righty:a3,lefttrigger:a4,righttrigger:a5,platform:Linux, 03000000250900000500000000010000,Sony PS2 pad with SmartJoy adapter,a:b2,b:b1,back:b9,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:b8,x:b3,y:b0,platform:Linux, 030000005e0400008e02000073050000,Speedlink TORID Wireless Gamepad,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, 030000005e0400008e02000020200000,SpeedLink XEOX Pro Analog Gamepad pad,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, 03000000d11800000094000011010000,Stadia 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:a5,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b10,righttrigger:a4,rightx:a2,righty:a3,start:b7,x:b2,y:b3,platform:Linux, 03000000de2800000112000001000000,Steam Controller,a:b0,b:b1,back:b6,dpdown:b14,dpleft:b15,dpright:b13,dpup:b12,guide:b8,leftshoulder:b4,leftstick:b9,lefttrigger:a2,leftx:a0,lefty:a1,paddle1:b11,paddle2:b10,rightshoulder:b5,righttrigger:a3,start:b7,x:b2,y:b3,platform:Linux, 03000000de2800000211000001000000,Steam Controller,a:b0,b:b1,back:b6,dpdown:b14,dpleft:b15,dpright:b13,dpup:b12,guide:b8,leftshoulder:b4,leftstick:b9,lefttrigger:a2,leftx:a0,lefty:a1,paddle1:b11,paddle2:b10,rightshoulder:b5,righttrigger:a3,start:b7,x:b2,y:b3,platform:Linux, -03000000de2800004211000001000000,Steam Controller,a:b0,b:b1,back:b6,dpdown:b14,dpleft:b15,dpright:b13,dpup:b12,guide:b8,leftshoulder:b4,leftstick:b9,lefttrigger:a2,leftx:a0,lefty:a1,paddle1:b11,paddle2:b10,rightshoulder:b5,righttrigger:a3,start:b7,x:b2,y:b3,platform:Linux, 03000000de2800000211000011010000,Steam Controller,a:b2,b:b3,back:b10,dpdown:b18,dpleft:b19,dpright:b20,dpup:b17,guide:b12,leftshoulder:b6,leftstick:b13,lefttrigger:b8,leftx:a0,lefty:a1,paddle1:b15,paddle2:b16,rightshoulder:b7,righttrigger:b9,rightx:a2,righty:a3,start:b11,x:b4,y:b5,platform:Linux, +03000000de2800004211000001000000,Steam Controller,a:b0,b:b1,back:b6,dpdown:b14,dpleft:b15,dpright:b13,dpup:b12,guide:b8,leftshoulder:b4,leftstick:b9,lefttrigger:a2,leftx:a0,lefty:a1,paddle1:b11,paddle2:b10,rightshoulder:b5,righttrigger:a3,start:b7,x:b2,y:b3,platform:Linux, 03000000de2800004211000011010000,Steam Controller,a:b2,b:b3,back:b10,dpdown:b18,dpleft:b19,dpright:b20,dpup:b17,guide:b12,leftshoulder:b6,leftstick:b13,lefttrigger:b8,leftx:a0,lefty:a1,paddle1:b15,paddle2:b16,rightshoulder:b7,righttrigger:b9,rightx:a2,righty:a3,start:b11,x:b4,y:b5,platform:Linux, 03000000de280000fc11000001000000,Steam Controller,a:b0,b:b1,back:b6,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, 05000000de2800000212000001000000,Steam Controller,a:b0,b:b1,back:b6,dpdown:b14,dpleft:b15,dpright:b13,dpup:b12,guide:b8,leftshoulder:b4,leftstick:b9,lefttrigger:a2,leftx:a0,lefty:a1,paddle1:b11,paddle2:b10,rightshoulder:b5,righttrigger:a3,start:b7,x:b2,y:b3,platform:Linux, @@ -874,6 +919,7 @@ xinput,XInput Controller,a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2, 030000005e040000130b000005050000,Xbox Series Controller,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, 050000005e040000130b000001050000,Xbox Series Controller,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, 050000005e040000130b000005050000,Xbox Series Controller,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, +030000005e040000120b000005050000,XBox Series pad,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, 030000005e0400008e02000000010000,xbox360 Wireless EasySMX,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, 03000000450c00002043000010010000,XEOX Gamepad SL-6556-BK,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, 03000000ac0500005b05000010010000,Xiaoji Gamesir-G3w,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, @@ -900,7 +946,7 @@ xinput,XInput Controller,a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2, 050000003512000020ab000000780f00,8BitDo SNES30 Gamepad,a:b21,b:b20,back:b30,dpdown:+a1,dpleft:-a0,dpright:+a0,dpup:-a1,leftshoulder:b26,rightshoulder:b27,start:b31,x:b24,y:b23,platform:Android, 05000000c82d000018900000ffff0f00,8BitDo Zero 2,a:b1,b:b0,back:b4,leftshoulder:b9,leftx:a0,lefty:a1,rightshoulder:b10,start:b6,x:b3,y:b2,platform:Android, 05000000c82d000030320000ffff0f00,8BitDo Zero 2,a:b1,b:b0,back:b4,leftshoulder:b9,leftx:a0,lefty:a1,rightshoulder:b10,start:b6,x:b3,y:b2,platform:Android, -38383337343564366131323064613561,Brook Mars,a:b1,b:b19,x:b0,y:b2,leftshoulder:b3,rightshoulder:b20,lefttrigger:b9,righttrigger:b10,back:b17,start:b18,leftx:a0,lefty:a1,rightx:a2,righty:a3,leftstick:b15,rightstick:b6,platform:Android, +38383337343564366131323064613561,Brook Mars,a:b1,b:b19,back:b17,leftshoulder:b3,leftstick:b15,lefttrigger:b9,leftx:a0,lefty:a1,rightshoulder:b20,rightstick:b6,righttrigger:b10,rightx:a2,righty:a3,start:b18,x:b0,y:b2,platform:Android, 05000000bc20000000550000ffff3f00,GameSir G3w,a:b0,b:b1,back:b4,dpdown:b12,dpleft:b13,dpright:b14,dpup:b11,leftshoulder:b9,leftstick:b7,lefttrigger:a5,leftx:a0,lefty:a1,rightshoulder:b10,rightstick:b8,righttrigger:a4,rightx:a2,righty:a3,start:b6,x:b2,y:b3,platform:Android, 05000000d6020000e5890000dfff3f00,GPD XD Plus,a:b0,b:b1,back:b4,dpdown:b12,dpleft:b13,dpright:b14,dpup:b11,leftshoulder:b9,leftstick:b7,lefttrigger:a3,leftx:a0,lefty:a1,rightshoulder:b10,rightstick:b8,righttrigger:a4,rightx:a2,righty:a5,start:b6,x:b2,y:b3,platform:Android, 0500000031366332860c44aadfff0f00,GS Gamepad,a:b0,b:b1,back:b4,dpdown:b12,dpleft:b13,dpright:b14,dpup:b11,leftshoulder:b9,leftstick:b7,lefttrigger:b15,leftx:a0,lefty:a1,rightshoulder:b10,rightstick:b8,righttrigger:b16,rightx:a2,righty:a3,start:b6,x:b2,y:b3,platform:Android, @@ -916,9 +962,10 @@ xinput,XInput Controller,a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2, 050000005509000014720000df7f3f00,NVIDIA Controller v01.04,a:b0,b:b1,back:b4,dpdown:b12,dpleft:b13,dpright:b14,dpup:b11,leftshoulder:b9,leftstick:b7,lefttrigger:a3,leftx:a0,lefty:a1,rightshoulder:b10,rightstick:b8,righttrigger:a4,rightx:a2,righty:a5,start:b6,x:b2,y:b3,platform:Android, 050000004c05000068020000dfff3f00,PS3 Controller,a:b0,b:b1,back:b4,dpdown:b12,dpleft:b13,dpright:b14,dpup:b11,leftshoulder:b9,leftstick:b7,lefttrigger:a4,leftx:a0,lefty:a1,rightshoulder:b10,rightstick:b8,righttrigger:a5,rightx:a2,righty:a3,start:b6,x:b2,y:b3,platform:Android, 030000004c050000cc09000000006800,PS4 Controller,a:b0,b:b1,back:b4,dpdown:b12,dpleft:b13,dpright:b14,dpup:b11,guide:b5,leftshoulder:b9,leftstick:b7,lefttrigger:a4,leftx:a0,lefty:a1,rightshoulder:b10,rightstick:b8,righttrigger:a5,rightx:a2,righty:a3,start:b6,x:b2,y:b3,platform:Android, +050000004c050000c405000000783f00,PS4 Controller,a:b0,b:b1,back:b4,dpdown:b12,dpleft:b13,dpright:b14,dpup:b11,guide:b5,leftshoulder:b9,leftstick:b7,lefttrigger:a4,leftx:a0,lefty:a1,rightshoulder:b10,rightstick:b8,righttrigger:a5,rightx:a2,righty:a3,start:b6,x:b2,y:b3,platform:Android, 050000004c050000c4050000fffe3f00,PS4 Controller,a:b1,b:b17,back:b15,dpdown:b12,dpleft:b13,dpright:b14,dpup:b11,guide:b5,leftshoulder:b3,leftstick:b4,lefttrigger:+a3,leftx:a0,lefty:a1,rightshoulder:b18,rightstick:b6,righttrigger:+a4,rightx:a2,righty:a5,start:b16,x:b0,y:b2,platform:Android, 050000004c050000c4050000ffff3f00,PS4 Controller,a:b0,b:b1,back:b4,dpdown:b12,dpleft:b13,dpright:b14,dpup:b11,guide:b5,leftshoulder:b9,leftstick:b7,lefttrigger:a4,leftx:a0,lefty:a1,rightshoulder:b10,rightstick:b8,righttrigger:a5,rightx:a2,righty:a3,start:b6,x:b2,y:b3,platform:Android, -050000004c050000cc090000fffe3f00,PS4 Controller,a:b1,b:b17,back:b15,dpdown:b12,dpleft:b13,dpright:b14,dpup:b11,guide:b5,leftshoulder:b3,leftstick:b4,lefttrigger:a3,leftx:a0,lefty:a1,rightshoulder:b18,rightstick:b6,righttrigger:a4,rightx:a2,righty:a5,start:b16,x:b0,y:b2,platform:Android, +050000004c050000cc090000fffe3f00,PS4 Controller,a:b0,b:b1,back:b4,dpdown:b12,dpleft:b13,dpright:b14,dpup:b11,guide:b5,leftshoulder:b9,leftstick:b7,lefttrigger:a4,leftx:a0,lefty:a1,rightshoulder:b10,rightstick:b8,righttrigger:a5,rightx:a2,righty:a3,start:b6,x:b2,y:b3,platform:Android, 050000004c050000cc090000ffff3f00,PS4 Controller,a:b0,b:b1,back:b4,dpdown:b12,dpleft:b13,dpright:b14,dpup:b11,guide:b5,leftshoulder:b9,leftstick:b7,lefttrigger:a4,leftx:a0,lefty:a1,rightshoulder:b10,rightstick:b8,righttrigger:a5,rightx:a2,righty:a3,start:b6,x:b2,y:b3,platform:Android, 35643031303033326130316330353564,PS4 Controller,a:b1,b:b17,back:b15,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b5,leftshoulder:b3,leftstick:b4,lefttrigger:+a3,leftx:a0,lefty:a1,rightshoulder:b18,rightstick:b6,righttrigger:+a4,rightx:a2,righty:a5,start:b16,x:b0,y:b2,platform:Android, 050000004c050000e60c0000fffe3f00,PS5 Controller,a:b1,b:b17,back:b15,dpdown:b12,dpleft:b13,dpright:b14,dpup:b11,guide:b5,leftshoulder:b3,leftstick:b4,lefttrigger:a3,leftx:a0,lefty:a1,rightshoulder:b18,rightstick:b6,righttrigger:a4,rightx:a2,righty:a5,start:b16,x:b0,y:b2,platform:Android, @@ -933,9 +980,14 @@ xinput,XInput Controller,a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2, 050000004f0400000ed00000fffe3f00,ThrustMaster eSwap PRO Controller,a:b0,b:b1,back:b4,dpdown:b12,dpleft:b13,dpright:b14,dpup:b11,leftshoulder:b9,leftstick:b7,lefttrigger:a4,leftx:a0,lefty:a1,rightshoulder:b10,righttrigger:a5,rightx:a2,righty:a3,start:b6,x:b2,y:b3,platform:Android, 5477696e20555342204a6f7973746963,Twin USB Joystick,a:b22,b:b21,back:b28,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b26,leftstick:b30,lefttrigger:b24,leftx:a0,lefty:a1,rightshoulder:b27,rightstick:b31,righttrigger:b25,rightx:a3,righty:a2,start:b29,x:b23,y:b20,platform:Android, 30306539356238653637313730656134,Wireless HORIPAD Switch Pro Controller,a:b0,b:b1,back:b17,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b5,leftshoulder:b3,leftstick:b15,lefttrigger:b9,leftx:a0,lefty:a1,rightshoulder:b20,rightstick:b6,righttrigger:b10,rightx:a2,righty:a3,start:b18,x:b19,y:b2,platform:Android, +050000005e0400008e02000000783f00,Xbox 360 Controller,a:b0,b:b1,back:b4,dpdown:b12,dpleft:b13,dpright:b14,dpup:b11,guide:b5,leftshoulder:b9,leftstick:b7,lefttrigger:a4,leftx:a0,lefty:a1,rightshoulder:b10,rightstick:b8,righttrigger:a5,rightx:a2,righty:a3,start:b6,x:b2,y:b3,platform:Android, +050000005e040000000b000000783f00,Xbox One Elite 2 Controller,a:b0,b:b1,back:b4,dpdown:b12,dpleft:b13,dpright:b14,dpup:b11,guide:b5,leftshoulder:b9,leftstick:b7,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b10,rightstick:b8,righttrigger:a5,rightx:a3,righty:a4,start:b6,x:b2,y:b3,platform:Android, +050000005e040000e002000000783f00,Xbox One S Controller,a:b0,b:b1,back:b4,dpdown:b12,dpleft:b13,dpright:b14,dpup:b11,guide:b5,leftshoulder:b9,leftstick:b7,lefttrigger:a4,leftx:a0,lefty:a1,rightshoulder:b10,rightstick:b8,righttrigger:a5,rightx:a2,righty:a3,start:b6,x:b2,y:b3,platform:Android, +050000005e040000ea02000000783f00,Xbox One S Controller,a:b0,b:b1,back:b4,dpdown:b12,dpleft:b13,dpright:b14,dpup:b11,guide:b5,leftshoulder:b9,leftstick:b7,lefttrigger:a4,leftx:a0,lefty:a1,rightshoulder:b10,rightstick:b8,righttrigger:a5,rightx:a2,righty:a3,start:b6,x:b2,y:b3,platform:Android, 050000005e040000fd020000ff7f3f00,Xbox One S Controller,a:b0,b:b1,back:b4,dpdown:b12,dpleft:b13,dpright:b14,dpup:b11,guide:b5,leftshoulder:b9,leftstick:b7,lefttrigger:a4,leftx:a0,lefty:a1,rightshoulder:b10,rightstick:b8,righttrigger:a5,rightx:a2,righty:a3,start:b6,x:b2,y:b3,platform:Android, 050000005e040000e00200000ffe3f00,Xbox One Wireless Controller,a:b0,b:b1,back:b9,dpdown:b12,dpleft:b13,dpright:b14,dpup:b11,leftshoulder:b3,leftstick:b15,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b18,rightstick:b16,righttrigger:a5,rightx:a3,righty:a4,start:b10,x:b17,y:b2,platform:Android, 050000005e040000fd020000ffff3f00,Xbox One Wireless Controller,a:b0,b:b1,back:b4,dpdown:b12,dpleft:b13,dpright:b14,dpup:b11,leftshoulder:b9,leftstick:b7,lefttrigger:a5,leftx:a0,lefty:a1,rightshoulder:b10,rightstick:b8,righttrigger:a4,rightx:a2,righty:a3,start:b6,x:b2,y:b3,platform:Android, +050000005e040000120b000000783f00,Xbox Series Controller,a:b0,b:b1,back:b4,dpdown:b12,dpleft:b13,dpright:b14,dpup:b11,guide:b5,leftshoulder:b9,leftstick:b7,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b10,rightstick:b8,righttrigger:a5,rightx:a3,righty:a4,start:b6,x:b2,y:b3,platform:Android, 050000005e040000130b0000ffff3f00,Xbox Series Controller,a:b0,b:b1,back:b4,dpdown:b12,dpleft:b13,dpright:b14,dpup:b11,guide:b5,leftshoulder:b9,leftstick:b7,lefttrigger:a4,leftx:a0,lefty:a1,rightshoulder:b10,rightstick:b8,righttrigger:a5,rightx:a2,righty:a3,start:b6,x:b2,y:b3,platform:Android, 65633038363832353634653836396239,Xbox Series Controller,a:b0,b:b1,back:b15,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b5,leftshoulder:b9,leftstick:b7,lefttrigger:a4,leftx:a0,lefty:a1,rightshoulder:b10,rightstick:b8,righttrigger:a5,rightx:a2,righty:a3,start:b6,x:b2,y:b3,platform:Android, 050000005e04000091020000ff073f00,Xbox Wireless Controller,a:b0,b:b1,back:b4,guide:b5,leftshoulder:b9,leftstick:b7,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b10,rightstick:b8,righttrigger:a5,rightx:a3,righty:a4,start:b6,x:b2,y:b3,platform:Android, @@ -953,13 +1005,17 @@ xinput,XInput Controller,a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2, 4d466947616d65706164010000000000,MFi Extended Gamepad,a:b0,b:b1,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b5,righttrigger:a5,rightx:a3,righty:a4,start:b6,x:b2,y:b3,platform:iOS, 4d466947616d65706164020000000000,MFi Gamepad,a:b0,b:b1,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,rightshoulder:b5,start:b6,x:b2,y:b3,platform:iOS, 050000004c050000cc090000df070000,PS4 Controller,a:b0,b:b1,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b6,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b7,righttrigger:a5,rightx:a3,righty:a4,start:b9,x:b2,y:b3,platform:iOS, +050000004c050000cc090000df870001,PS4 Controller,a:b0,b:b1,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b6,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b7,righttrigger:a5,rightx:a3,righty:a4,start:b9,x:b2,y:b3,platform:iOS, 050000004c050000cc090000ff070000,PS4 Controller,a:b0,b:b1,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b9,leftshoulder:b4,leftstick:b6,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b7,righttrigger:a5,rightx:a3,righty:a4,start:b10,x:b2,y:b3,platform:iOS, 050000004c050000cc090000ff870001,PS4 Controller,a:b0,b:b1,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b9,leftshoulder:b4,leftstick:b6,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b7,righttrigger:a5,rightx:a3,righty:a4,start:b10,touchpad:b11,x:b2,y:b3,platform:iOS, 050000004c050000cc090000ff876d01,PS4 Controller,a:b0,b:b1,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b9,leftshoulder:b4,leftstick:b6,lefttrigger:a2,leftx:a0,lefty:a1,misc1:b11,rightshoulder:b5,rightstick:b7,righttrigger:a5,rightx:a3,righty:a4,start:b10,x:b2,y:b3,platform:iOS, +050000004c050000e60c0000df870000,PS5 Controller,a:b0,b:b1,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b6,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b7,righttrigger:a5,rightx:a3,righty:a4,start:b9,touchpad:b10,x:b2,y:b3,platform:iOS, +050000004c050000e60c0000ff870000,PS5 Controller,a:b0,b:b1,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b9,leftshoulder:b4,leftstick:b6,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b7,righttrigger:a5,rightx:a3,righty:a4,start:b10,touchpad:b11,x:b2,y:b3,platform:iOS, 05000000ac0500000300000000006d03,Remote,a:b0,b:b2,leftx:a0,lefty:a1,platform:iOS, 05000000ac0500000300000043006d03,Remote,a:b0,b:b2,leftx:a0,lefty:a1,platform:iOS, 05000000de2800000511000001000000,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:iOS, 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:iOS, +050000005e040000050b0000df070001,Xbox Elite Wireless Controller,a:b0,b:b1,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b6,lefttrigger:a2,leftx:a0,lefty:a1,paddle1:b10,paddle2:b12,paddle3:b11,paddle4:b13,rightshoulder:b5,rightstick:b7,righttrigger:a5,rightx:a3,righty:a4,start:b9,x:b2,y:b3,platform:iOS, 050000005e040000050b0000ff070001,Xbox Elite Wireless Controller,a:b0,b:b1,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b9,leftshoulder:b4,leftstick:b6,lefttrigger:a2,leftx:a0,lefty:a1,paddle1:b11,paddle2:b13,paddle3:b12,paddle4:b14,rightshoulder:b5,rightstick:b7,righttrigger:a5,rightx:a3,righty:a4,start:b10,x:b2,y:b3,platform:iOS, 050000005e040000e0020000df070000,Xbox Wireless Controller,a:b0,b:b1,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b6,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b7,righttrigger:a5,rightx:a3,righty:a4,start:b9,x:b2,y:b3,platform:iOS, 050000005e040000e0020000ff070000,Xbox Wireless Controller,a:b0,b:b1,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b9,leftshoulder:b4,leftstick:b6,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b7,righttrigger:a5,rightx:a3,righty:a4,start:b10,x:b2,y:b3,platform:iOS, diff --git a/core/input/input.cpp b/core/input/input.cpp index a712394b35..e30e7c814f 100644 --- a/core/input/input.cpp +++ b/core/input/input.cpp @@ -101,7 +101,7 @@ void Input::_bind_methods() { ClassDB::bind_method(D_METHOD("is_action_just_pressed", "action", "exact_match"), &Input::is_action_just_pressed, DEFVAL(false)); ClassDB::bind_method(D_METHOD("is_action_just_released", "action", "exact_match"), &Input::is_action_just_released, DEFVAL(false)); ClassDB::bind_method(D_METHOD("get_action_strength", "action", "exact_match"), &Input::get_action_strength, DEFVAL(false)); - ClassDB::bind_method(D_METHOD("get_action_raw_strength", "action", "exact_match"), &Input::get_action_strength, DEFVAL(false)); + ClassDB::bind_method(D_METHOD("get_action_raw_strength", "action", "exact_match"), &Input::get_action_raw_strength, DEFVAL(false)); ClassDB::bind_method(D_METHOD("get_axis", "negative_action", "positive_action"), &Input::get_axis); ClassDB::bind_method(D_METHOD("get_vector", "negative_x", "positive_x", "negative_y", "positive_y", "deadzone"), &Input::get_vector, DEFVAL(-1.0f)); ClassDB::bind_method(D_METHOD("add_joy_mapping", "mapping", "update_existing"), &Input::add_joy_mapping, DEFVAL(false)); @@ -169,13 +169,12 @@ void Input::get_argument_options(const StringName &p_function, int p_idx, List<S String pf = p_function; if (p_idx == 0 && (pf == "is_action_pressed" || pf == "action_press" || pf == "action_release" || pf == "is_action_just_pressed" || pf == "is_action_just_released" || - pf == "get_action_strength" || pf == "get_axis" || pf == "get_vector")) { + pf == "get_action_strength" || pf == "get_action_raw_strength" || + pf == "get_axis" || pf == "get_vector")) { List<PropertyInfo> pinfo; ProjectSettings::get_singleton()->get_property_list(&pinfo); - for (List<PropertyInfo>::Element *E = pinfo.front(); E; E = E->next()) { - const PropertyInfo &pi = E->get(); - + for (PropertyInfo &pi : pinfo) { if (!pi.name.begins_with("input/")) { continue; } @@ -438,7 +437,7 @@ void Input::joy_connection_changed(int p_idx, bool p_connected, String p_name, S } joy_names[p_idx] = js; - emit_signal("joy_connection_changed", p_idx, p_connected); + emit_signal(SNAME("joy_connection_changed"), p_idx, p_connected); } Vector3 Input::get_gravity() const { diff --git a/core/input/input_map.cpp b/core/input/input_map.cpp index b5f067d499..0c8705b263 100644 --- a/core/input/input_map.cpp +++ b/core/input/input_map.cpp @@ -65,11 +65,11 @@ String InputMap::_suggest_actions(const StringName &p_action) const { float closest_similarity = 0.0; // Find the most action with the most similar name. - for (List<StringName>::Element *E = actions.front(); E; E = E->next()) { - const float similarity = String(E->get()).similarity(p_action); + for (StringName &action : actions) { + const float similarity = String(action).similarity(p_action); if (similarity > closest_similarity) { - closest_action = E->get(); + closest_action = action; closest_similarity = similarity; } } @@ -105,8 +105,8 @@ Array InputMap::_get_actions() { return ret; } - for (const List<StringName>::Element *E = actions.front(); E; E = E->next()) { - ret.push_back(E->get()); + for (const StringName &E : actions) { + ret.push_back(E); } return ret; @@ -129,13 +129,11 @@ List<Ref<InputEvent>>::Element *InputMap::_find_event(Action &p_action, const Re ERR_FAIL_COND_V(!p_event.is_valid(), nullptr); for (List<Ref<InputEvent>>::Element *E = p_action.inputs.front(); E; E = E->next()) { - const Ref<InputEvent> e = E->get(); - - int device = e->get_device(); + int device = E->get()->get_device(); if (device == ALL_DEVICES || device == p_event->get_device()) { - if (p_exact_match && e->is_match(p_event, true)) { + if (p_exact_match && E->get()->is_match(p_event, true)) { return E; - } else if (!p_exact_match && e->action_match(p_event, p_pressed, p_strength, p_raw_strength, p_action.deadzone)) { + } else if (!p_exact_match && E->get()->action_match(p_event, p_pressed, p_strength, p_raw_strength, p_action.deadzone)) { return E; } } @@ -198,7 +196,7 @@ Array InputMap::_action_get_events(const StringName &p_action) { const List<Ref<InputEvent>> *al = action_get_events(p_action); if (al) { for (const List<Ref<InputEvent>>::Element *E = al->front(); E; E = E->next()) { - ret.push_back(E->get()); + ret.push_back(E); } } @@ -263,9 +261,7 @@ void InputMap::load_from_project_settings() { List<PropertyInfo> pinfo; ProjectSettings::get_singleton()->get_property_list(&pinfo); - for (List<PropertyInfo>::Element *E = pinfo.front(); E; E = E->next()) { - const PropertyInfo &pi = E->get(); - + for (PropertyInfo &pi : pinfo) { if (!pi.name.begins_with("input/")) { continue; } diff --git a/core/io/config_file.cpp b/core/io/config_file.cpp index 10f68f3cef..aeaf25f321 100644 --- a/core/io/config_file.cpp +++ b/core/io/config_file.cpp @@ -40,8 +40,8 @@ PackedStringArray ConfigFile::_get_sections() const { PackedStringArray arr; arr.resize(s.size()); int idx = 0; - for (const List<String>::Element *E = s.front(); E; E = E->next()) { - arr.set(idx++, E->get()); + for (const String &E : s) { + arr.set(idx++, E); } return arr; @@ -53,8 +53,8 @@ PackedStringArray ConfigFile::_get_section_keys(const String &p_section) const { PackedStringArray arr; arr.resize(s.size()); int idx = 0; - for (const List<String>::Element *E = s.front(); E; E = E->next()) { - arr.set(idx++, E->get()); + for (const String &E : s) { + arr.set(idx++, E); } return arr; diff --git a/core/io/dir_access.cpp b/core/io/dir_access.cpp index dfba00067f..e30a8dfdd0 100644 --- a/core/io/dir_access.cpp +++ b/core/io/dir_access.cpp @@ -93,8 +93,8 @@ static Error _erase_recursive(DirAccess *da) { da->list_dir_end(); - for (List<String>::Element *E = dirs.front(); E; E = E->next()) { - Error err = da->change_dir(E->get()); + for (String &E : dirs) { + Error err = da->change_dir(E); if (err == OK) { err = _erase_recursive(da); if (err) { @@ -105,7 +105,7 @@ static Error _erase_recursive(DirAccess *da) { if (err) { return err; } - err = da->remove(da->get_current_dir().plus_file(E->get())); + err = da->remove(da->get_current_dir().plus_file(E)); if (err) { return err; } @@ -114,8 +114,8 @@ static Error _erase_recursive(DirAccess *da) { } } - for (List<String>::Element *E = files.front(); E; E = E->next()) { - Error err = da->remove(da->get_current_dir().plus_file(E->get())); + for (String &E : files) { + Error err = da->remove(da->get_current_dir().plus_file(E)); if (err) { return err; } @@ -362,16 +362,15 @@ Error DirAccess::_copy_dir(DirAccess *p_target_da, String p_to, int p_chmod_flag list_dir_end(); - for (List<String>::Element *E = dirs.front(); E; E = E->next()) { - String rel_path = E->get(); + for (String &rel_path : dirs) { String target_dir = p_to + rel_path; if (!p_target_da->dir_exists(target_dir)) { Error err = p_target_da->make_dir(target_dir); ERR_FAIL_COND_V_MSG(err != OK, err, "Cannot create directory '" + target_dir + "'."); } - Error err = change_dir(E->get()); - ERR_FAIL_COND_V_MSG(err != OK, err, "Cannot change current directory to '" + E->get() + "'."); + Error err = change_dir(rel_path); + ERR_FAIL_COND_V_MSG(err != OK, err, "Cannot change current directory to '" + rel_path + "'."); err = _copy_dir(p_target_da, p_to + rel_path + "/", p_chmod_flags, p_copy_links); if (err) { diff --git a/core/io/http_client.cpp b/core/io/http_client.cpp index 8000dd4290..5c1352c1b6 100644 --- a/core/io/http_client.cpp +++ b/core/io/http_client.cpp @@ -93,8 +93,7 @@ Dictionary HTTPClient::_get_response_headers_as_dictionary() { List<String> rh; get_response_headers(&rh); Dictionary ret; - for (const List<String>::Element *E = rh.front(); E; E = E->next()) { - const String &s = E->get(); + for (const String &s : rh) { int sp = s.find(":"); if (sp == -1) { continue; @@ -113,8 +112,8 @@ PackedStringArray HTTPClient::_get_response_headers() { PackedStringArray ret; ret.resize(rh.size()); int idx = 0; - for (const List<String>::Element *E = rh.front(); E; E = E->next()) { - ret.set(idx++, E->get()); + for (const String &E : rh) { + ret.set(idx++, E); } return ret; diff --git a/core/io/image_loader.cpp b/core/io/image_loader.cpp index b45e9d26b1..b0bd328d21 100644 --- a/core/io/image_loader.cpp +++ b/core/io/image_loader.cpp @@ -35,8 +35,8 @@ bool ImageFormatLoader::recognize(const String &p_extension) const { List<String> extensions; get_recognized_extensions(&extensions); - for (List<String>::Element *E = extensions.front(); E; E = E->next()) { - if (E->get().nocasecmp_to(p_extension) == 0) { + for (String &E : extensions) { + if (E.nocasecmp_to(p_extension) == 0) { return true; } } diff --git a/core/io/ip.cpp b/core/io/ip.cpp index 001b1c4757..132c69b7da 100644 --- a/core/io/ip.cpp +++ b/core/io/ip.cpp @@ -252,8 +252,8 @@ Array IP::_get_local_addresses() const { Array addresses; List<IPAddress> ip_addresses; get_local_addresses(&ip_addresses); - for (List<IPAddress>::Element *E = ip_addresses.front(); E; E = E->next()) { - addresses.push_back(E->get()); + for (IPAddress &E : ip_addresses) { + addresses.push_back(E); } return addresses; @@ -271,8 +271,8 @@ Array IP::_get_local_interfaces() const { rc["index"] = c.index; Array ips; - for (const List<IPAddress>::Element *F = c.ip_addresses.front(); F; F = F->next()) { - ips.push_front(F->get()); + for (const IPAddress &F : c.ip_addresses) { + ips.push_front(F); } rc["addresses"] = ips; @@ -286,8 +286,8 @@ void IP::get_local_addresses(List<IPAddress> *r_addresses) const { Map<String, Interface_Info> interfaces; get_local_interfaces(&interfaces); for (Map<String, Interface_Info>::Element *E = interfaces.front(); E; E = E->next()) { - for (const List<IPAddress>::Element *F = E->get().ip_addresses.front(); F; F = F->next()) { - r_addresses->push_front(F->get()); + for (const IPAddress &F : E->get().ip_addresses) { + r_addresses->push_front(F); } } } diff --git a/core/io/json.cpp b/core/io/json.cpp index b3a2498212..0381b78172 100644 --- a/core/io/json.cpp +++ b/core/io/json.cpp @@ -121,14 +121,17 @@ String JSON::_stringify(const Variant &p_var, const String &p_indent, int p_cur_ keys.sort(); } - for (List<Variant>::Element *E = keys.front(); E; E = E->next()) { - if (E != keys.front()) { + bool first_key = true; + for (Variant &E : keys) { + if (first_key) { + first_key = false; + } else { s += ","; s += end_statement; } - s += _make_indent(p_indent, p_cur_indent + 1) + _stringify(String(E->get()), p_indent, p_cur_indent + 1, p_sort_keys, p_markers); + s += _make_indent(p_indent, p_cur_indent + 1) + _stringify(String(E), p_indent, p_cur_indent + 1, p_sort_keys, p_markers); s += colon; - s += _stringify(d[E->get()], p_indent, p_cur_indent + 1, p_sort_keys, p_markers); + s += _stringify(d[E], p_indent, p_cur_indent + 1, p_sort_keys, p_markers); } s += end_statement + _make_indent(p_indent, p_cur_indent) + "}"; diff --git a/core/io/marshalls.cpp b/core/io/marshalls.cpp index f342db2dad..34d37dc99b 100644 --- a/core/io/marshalls.cpp +++ b/core/io/marshalls.cpp @@ -1358,8 +1358,8 @@ Error encode_variant(const Variant &p_variant, uint8_t *r_buffer, int &r_len, bo obj->get_property_list(&props); int pc = 0; - for (List<PropertyInfo>::Element *E = props.front(); E; E = E->next()) { - if (!(E->get().usage & PROPERTY_USAGE_STORAGE)) { + for (PropertyInfo &E : props) { + if (!(E.usage & PROPERTY_USAGE_STORAGE)) { continue; } pc++; @@ -1372,15 +1372,15 @@ Error encode_variant(const Variant &p_variant, uint8_t *r_buffer, int &r_len, bo r_len += 4; - for (List<PropertyInfo>::Element *E = props.front(); E; E = E->next()) { - if (!(E->get().usage & PROPERTY_USAGE_STORAGE)) { + for (PropertyInfo &E : props) { + if (!(E.usage & PROPERTY_USAGE_STORAGE)) { continue; } - _encode_string(E->get().name, buf, r_len); + _encode_string(E.name, buf, r_len); int len; - Error err = encode_variant(obj->get(E->get().name), buf, len, p_full_objects); + Error err = encode_variant(obj->get(E.name), buf, len, p_full_objects); if (err) { return err; } @@ -1418,7 +1418,7 @@ Error encode_variant(const Variant &p_variant, uint8_t *r_buffer, int &r_len, bo List<Variant> keys; d.get_key_list(&keys); - for (List<Variant>::Element *E = keys.front(); E; E = E->next()) { + for (Variant &E : keys) { /* CharString utf8 = E->->utf8(); @@ -1433,13 +1433,13 @@ Error encode_variant(const Variant &p_variant, uint8_t *r_buffer, int &r_len, bo r_len++; //pad */ int len; - encode_variant(E->get(), buf, len, p_full_objects); + encode_variant(E, buf, len, p_full_objects); ERR_FAIL_COND_V(len % 4, ERR_BUG); r_len += len; if (buf) { buf += len; } - Variant *v = d.getptr(E->get()); + Variant *v = d.getptr(E); ERR_FAIL_COND_V(!v, ERR_BUG); encode_variant(*v, buf, len, p_full_objects); ERR_FAIL_COND_V(len % 4, ERR_BUG); diff --git a/core/io/multiplayer_api.cpp b/core/io/multiplayer_api.cpp index 9f92388196..ee49335f55 100644 --- a/core/io/multiplayer_api.cpp +++ b/core/io/multiplayer_api.cpp @@ -94,52 +94,17 @@ const MultiplayerAPI::RPCConfig _get_rpc_config_by_id(Node *p_node, uint16_t p_i return MultiplayerAPI::RPCConfig(); } -_FORCE_INLINE_ bool _should_call_local(MultiplayerAPI::RPCMode mode, bool is_master, bool &r_skip_rpc) { - switch (mode) { - case MultiplayerAPI::RPC_MODE_DISABLED: { - // Do nothing. - } break; - case MultiplayerAPI::RPC_MODE_REMOTE: { - // Do nothing. Remote cannot produce a local call. - } break; - case MultiplayerAPI::RPC_MODE_MASTERSYNC: { - if (is_master) { - r_skip_rpc = true; // I am the master, so skip remote call. - } - [[fallthrough]]; - } - case MultiplayerAPI::RPC_MODE_REMOTESYNC: - case MultiplayerAPI::RPC_MODE_PUPPETSYNC: { - // Call it, sync always results in a local call. - return true; - } break; - case MultiplayerAPI::RPC_MODE_MASTER: { - if (is_master) { - r_skip_rpc = true; // I am the master, so skip remote call. - } - return is_master; - } break; - case MultiplayerAPI::RPC_MODE_PUPPET: { - return !is_master; - } break; - } - return false; -} - _FORCE_INLINE_ bool _can_call_mode(Node *p_node, MultiplayerAPI::RPCMode mode, int p_remote_id) { switch (mode) { case MultiplayerAPI::RPC_MODE_DISABLED: { return false; } break; - case MultiplayerAPI::RPC_MODE_REMOTE: - case MultiplayerAPI::RPC_MODE_REMOTESYNC: { + case MultiplayerAPI::RPC_MODE_REMOTE: { return true; } break; - case MultiplayerAPI::RPC_MODE_MASTERSYNC: case MultiplayerAPI::RPC_MODE_MASTER: { return p_node->is_network_master(); } break; - case MultiplayerAPI::RPC_MODE_PUPPETSYNC: case MultiplayerAPI::RPC_MODE_PUPPET: { return !p_node->is_network_master() && p_remote_id == p_node->get_network_master(); } break; @@ -590,12 +555,12 @@ bool MultiplayerAPI::_send_confirm_path(Node *p_node, NodePath p_path, PathSentC ofs += encode_cstring(path.get_data(), &packet.write[ofs]); - for (List<int>::Element *E = peers_to_add.front(); E; E = E->next()) { - network_peer->set_target_peer(E->get()); // To all of you. + for (int &E : peers_to_add) { + network_peer->set_target_peer(E); // To all of you. network_peer->set_transfer_mode(MultiplayerPeer::TRANSFER_MODE_RELIABLE); network_peer->put_packet(packet.ptr(), packet.size()); - psc->confirmed_peers.insert(E->get(), false); // Insert into confirmed, but as false since it was not confirmed. + psc->confirmed_peers.insert(E, false); // Insert into confirmed, but as false since it was not confirmed. } } @@ -941,7 +906,7 @@ void MultiplayerAPI::_send_rpc(Node *p_from, int p_to, uint16_t p_rpc_id, const void MultiplayerAPI::_add_peer(int p_id) { connected_peers.insert(p_id); path_get_cache.insert(p_id, PathGetCache()); - emit_signal("network_peer_connected", p_id); + emit_signal(SNAME("network_peer_connected"), p_id); } void MultiplayerAPI::_del_peer(int p_id) { @@ -952,23 +917,23 @@ void MultiplayerAPI::_del_peer(int p_id) { // Some refactoring is needed to make this faster and do paths GC. List<NodePath> keys; path_send_cache.get_key_list(&keys); - for (List<NodePath>::Element *E = keys.front(); E; E = E->next()) { - PathSentCache *psc = path_send_cache.getptr(E->get()); + for (NodePath &E : keys) { + PathSentCache *psc = path_send_cache.getptr(E); psc->confirmed_peers.erase(p_id); } - emit_signal("network_peer_disconnected", p_id); + emit_signal(SNAME("network_peer_disconnected"), p_id); } void MultiplayerAPI::_connected_to_server() { - emit_signal("connected_to_server"); + emit_signal(SNAME("connected_to_server")); } void MultiplayerAPI::_connection_failed() { - emit_signal("connection_failed"); + emit_signal(SNAME("connection_failed")); } void MultiplayerAPI::_server_disconnected() { - emit_signal("server_disconnected"); + emit_signal(SNAME("server_disconnected")); } void MultiplayerAPI::rpcp(Node *p_node, int p_peer_id, bool p_unreliable, const StringName &p_method, const Variant **p_arg, int p_argcount) { @@ -977,23 +942,21 @@ void MultiplayerAPI::rpcp(Node *p_node, int p_peer_id, bool p_unreliable, const ERR_FAIL_COND_MSG(network_peer->get_connection_status() != MultiplayerPeer::CONNECTION_CONNECTED, "Trying to call an RPC via a network peer which is not connected."); int node_id = network_peer->get_unique_id(); - bool skip_rpc = node_id == p_peer_id; bool call_local_native = false; bool call_local_script = false; - bool is_master = p_node->is_network_master(); uint16_t rpc_id = UINT16_MAX; const RPCConfig config = _get_rpc_config(p_node, p_method, rpc_id); ERR_FAIL_COND_MSG(config.name == StringName(), vformat("Unable to get the RPC configuration for the function \"%s\" at path: \"%s\". This happens when the method is not marked for RPCs.", p_method, p_node->get_path())); if (p_peer_id == 0 || p_peer_id == node_id || (p_peer_id < 0 && p_peer_id != -node_id)) { if (rpc_id & (1 << 15)) { - call_local_native = _should_call_local(config.rpc_mode, is_master, skip_rpc); + call_local_native = config.sync; } else { - call_local_script = _should_call_local(config.rpc_mode, is_master, skip_rpc); + call_local_script = config.sync; } } - if (!skip_rpc) { + if (p_peer_id != node_id) { #ifdef DEBUG_ENABLED _profile_node_data("out_rpc", p_node->get_instance_id()); #endif @@ -1030,7 +993,7 @@ void MultiplayerAPI::rpcp(Node *p_node, int p_peer_id, bool p_unreliable, const } } - ERR_FAIL_COND_MSG(skip_rpc && !(call_local_native || call_local_script), "RPC '" + p_method + "' on yourself is not allowed by selected mode."); + ERR_FAIL_COND_MSG(p_peer_id == node_id && !config.sync, "RPC '" + p_method + "' on yourself is not allowed by selected mode."); } Error MultiplayerAPI::send_bytes(Vector<uint8_t> p_data, int p_to, MultiplayerPeer::TransferMode p_mode) { @@ -1059,7 +1022,7 @@ void MultiplayerAPI::_process_raw(int p_from, const uint8_t *p_packet, int p_pac uint8_t *w = out.ptrw(); memcpy(&w[0], &p_packet[1], len); } - emit_signal("network_peer_packet", p_from, out); + emit_signal(SNAME("network_peer_packet"), p_from, out); } int MultiplayerAPI::get_network_unique_id() const { @@ -1136,9 +1099,6 @@ void MultiplayerAPI::_bind_methods() { BIND_ENUM_CONSTANT(RPC_MODE_REMOTE); BIND_ENUM_CONSTANT(RPC_MODE_MASTER); BIND_ENUM_CONSTANT(RPC_MODE_PUPPET); - BIND_ENUM_CONSTANT(RPC_MODE_REMOTESYNC); - BIND_ENUM_CONSTANT(RPC_MODE_MASTERSYNC); - BIND_ENUM_CONSTANT(RPC_MODE_PUPPETSYNC); } MultiplayerAPI::MultiplayerAPI() { diff --git a/core/io/multiplayer_api.h b/core/io/multiplayer_api.h index e9f96383c9..cc994a9852 100644 --- a/core/io/multiplayer_api.h +++ b/core/io/multiplayer_api.h @@ -43,14 +43,12 @@ public: RPC_MODE_REMOTE, // Using rpc() on it will call method in all remote peers RPC_MODE_MASTER, // Using rpc() on it will call method on wherever the master is, be it local or remote RPC_MODE_PUPPET, // Using rpc() on it will call method for all puppets - RPC_MODE_REMOTESYNC, // Using rpc() on it will call method in all remote peers and locally - RPC_MODE_MASTERSYNC, // Using rpc() on it will call method in the master peer and locally - RPC_MODE_PUPPETSYNC, // Using rpc() on it will call method in all puppets peers and locally }; struct RPCConfig { StringName name; RPCMode rpc_mode = RPC_MODE_DISABLED; + bool sync = false; MultiplayerPeer::TransferMode transfer_mode = MultiplayerPeer::TRANSFER_MODE_RELIABLE; int channel = 0; diff --git a/core/io/packed_data_container.cpp b/core/io/packed_data_container.cpp index cf6a0b6027..ec43ea9311 100644 --- a/core/io/packed_data_container.cpp +++ b/core/io/packed_data_container.cpp @@ -268,21 +268,21 @@ uint32_t PackedDataContainer::_pack(const Variant &p_data, Vector<uint8_t> &tmpd d.get_key_list(&keys); List<DictKey> sortk; - for (List<Variant>::Element *E = keys.front(); E; E = E->next()) { + for (Variant &key : keys) { DictKey dk; - dk.hash = E->get().hash(); - dk.key = E->get(); + dk.hash = key.hash(); + dk.key = key; sortk.push_back(dk); } sortk.sort(); int idx = 0; - for (List<DictKey>::Element *E = sortk.front(); E; E = E->next()) { - encode_uint32(E->get().hash, &tmpdata.write[pos + 8 + idx * 12 + 0]); - uint32_t ofs = _pack(E->get().key, tmpdata, string_cache); + for (DictKey &E : sortk) { + encode_uint32(E.hash, &tmpdata.write[pos + 8 + idx * 12 + 0]); + uint32_t ofs = _pack(E.key, tmpdata, string_cache); encode_uint32(ofs, &tmpdata.write[pos + 8 + idx * 12 + 4]); - ofs = _pack(d[E->get().key], tmpdata, string_cache); + ofs = _pack(d[E.key], tmpdata, string_cache); encode_uint32(ofs, &tmpdata.write[pos + 8 + idx * 12 + 8]); idx++; } diff --git a/core/io/resource.cpp b/core/io/resource.cpp index efa622d976..695988bd71 100644 --- a/core/io/resource.cpp +++ b/core/io/resource.cpp @@ -33,6 +33,7 @@ #include "core/core_string_names.h" #include "core/io/file_access.h" #include "core/io/resource_loader.h" +#include "core/math/math_funcs.h" #include "core/object/script_language.h" #include "core/os/os.h" #include "scene/main/node.h" //only so casting works @@ -94,12 +95,43 @@ String Resource::get_path() const { return path_cache; } -void Resource::set_subindex(int p_sub_index) { - subindex = p_sub_index; +String Resource::generate_scene_unique_id() { + // Generate a unique enough hash, but still user-readable. + // If it's not unique it does not matter because the saver will try again. + OS::Date date = OS::get_singleton()->get_date(); + OS::Time time = OS::get_singleton()->get_time(); + uint32_t hash = hash_djb2_one_32(OS::get_singleton()->get_ticks_usec()); + hash = hash_djb2_one_32(date.year, hash); + hash = hash_djb2_one_32(date.month, hash); + hash = hash_djb2_one_32(date.day, hash); + hash = hash_djb2_one_32(time.hour, hash); + hash = hash_djb2_one_32(time.minute, hash); + hash = hash_djb2_one_32(time.second, hash); + hash = hash_djb2_one_32(Math::rand(), hash); + + static constexpr uint32_t characters = 5; + static constexpr uint32_t char_count = ('z' - 'a'); + static constexpr uint32_t base = char_count + ('9' - '0'); + String id; + for (uint32_t i = 0; i < characters; i++) { + uint32_t c = hash % base; + if (c < char_count) { + id += String::chr('a' + c); + } else { + id += String::chr('0' + (c - char_count)); + } + hash /= base; + } + + return id; +} + +void Resource::set_scene_unique_id(const String &p_id) { + scene_unique_id = p_id; } -int Resource::get_subindex() const { - return subindex; +String Resource::get_scene_unique_id() const { + return scene_unique_id; } void Resource::set_name(const String &p_name) { @@ -133,15 +165,15 @@ Error Resource::copy_from(const Ref<Resource> &p_resource) { List<PropertyInfo> pi; p_resource->get_property_list(&pi); - for (List<PropertyInfo>::Element *E = pi.front(); E; E = E->next()) { - if (!(E->get().usage & PROPERTY_USAGE_STORAGE)) { + for (PropertyInfo &E : pi) { + if (!(E.usage & PROPERTY_USAGE_STORAGE)) { continue; } - if (E->get().name == "resource_path") { + if (E.name == "resource_path") { continue; //do not change path } - set(E->get().name, p_resource->get(E->get().name)); + set(E.name, p_resource->get(E.name)); } return OK; } @@ -169,11 +201,11 @@ Ref<Resource> Resource::duplicate_for_local_scene(Node *p_for_scene, Map<Ref<Res r->local_scene = p_for_scene; - for (List<PropertyInfo>::Element *E = plist.front(); E; E = E->next()) { - if (!(E->get().usage & PROPERTY_USAGE_STORAGE)) { + for (PropertyInfo &E : plist) { + if (!(E.usage & PROPERTY_USAGE_STORAGE)) { continue; } - Variant p = get(E->get().name); + Variant p = get(E.name); if (p.get_type() == Variant::OBJECT) { RES sr = p; if (sr.is_valid()) { @@ -189,7 +221,7 @@ Ref<Resource> Resource::duplicate_for_local_scene(Node *p_for_scene, Map<Ref<Res } } - r->set(E->get().name, p); + r->set(E.name, p); } return r; @@ -201,11 +233,11 @@ void Resource::configure_for_local_scene(Node *p_for_scene, Map<Ref<Resource>, R local_scene = p_for_scene; - for (List<PropertyInfo>::Element *E = plist.front(); E; E = E->next()) { - if (!(E->get().usage & PROPERTY_USAGE_STORAGE)) { + for (PropertyInfo &E : plist) { + if (!(E.usage & PROPERTY_USAGE_STORAGE)) { continue; } - Variant p = get(E->get().name); + Variant p = get(E.name); if (p.get_type() == Variant::OBJECT) { RES sr = p; if (sr.is_valid()) { @@ -227,21 +259,21 @@ Ref<Resource> Resource::duplicate(bool p_subresources) const { Ref<Resource> r = (Resource *)ClassDB::instantiate(get_class()); ERR_FAIL_COND_V(r.is_null(), Ref<Resource>()); - for (List<PropertyInfo>::Element *E = plist.front(); E; E = E->next()) { - if (!(E->get().usage & PROPERTY_USAGE_STORAGE)) { + for (PropertyInfo &E : plist) { + if (!(E.usage & PROPERTY_USAGE_STORAGE)) { continue; } - Variant p = get(E->get().name); + Variant p = get(E.name); if ((p.get_type() == Variant::DICTIONARY || p.get_type() == Variant::ARRAY)) { - r->set(E->get().name, p.duplicate(p_subresources)); - } else if (p.get_type() == Variant::OBJECT && (p_subresources || (E->get().usage & PROPERTY_USAGE_DO_NOT_SHARE_ON_DUPLICATE))) { + r->set(E.name, p.duplicate(p_subresources)); + } else if (p.get_type() == Variant::OBJECT && (p_subresources || (E.usage & PROPERTY_USAGE_DO_NOT_SHARE_ON_DUPLICATE))) { RES sr = p; if (sr.is_valid()) { - r->set(E->get().name, sr->duplicate(p_subresources)); + r->set(E.name, sr->duplicate(p_subresources)); } } else { - r->set(E->get().name, p); + r->set(E.name, p); } } @@ -285,9 +317,9 @@ uint32_t Resource::hash_edited_version() const { List<PropertyInfo> plist; get_property_list(&plist); - for (List<PropertyInfo>::Element *E = plist.front(); E; E = E->next()) { - if (E->get().usage & PROPERTY_USAGE_STORAGE && E->get().type == Variant::OBJECT && E->get().hint == PROPERTY_HINT_RESOURCE_TYPE) { - RES res = get(E->get().name); + for (PropertyInfo &E : plist) { + if (E.usage & PROPERTY_USAGE_STORAGE && E.type == Variant::OBJECT && E.hint == PROPERTY_HINT_RESOURCE_TYPE) { + RES res = get(E.name); if (res.is_valid()) { hash = hash_djb2_one_32(res->hash_edited_version(), hash); } @@ -350,8 +382,8 @@ bool Resource::is_translation_remapped() const { #ifdef TOOLS_ENABLED //helps keep IDs same number when loading/saving scenes. -1 clears ID and it Returns -1 when no id stored -void Resource::set_id_for_path(const String &p_path, int p_id) { - if (p_id == -1) { +void Resource::set_id_for_path(const String &p_path, const String &p_id) { + if (p_id == "") { ResourceCache::path_cache_lock.write_lock(); ResourceCache::resource_path_cache[p_path].erase(get_path()); ResourceCache::path_cache_lock.write_unlock(); @@ -362,15 +394,15 @@ void Resource::set_id_for_path(const String &p_path, int p_id) { } } -int Resource::get_id_for_path(const String &p_path) const { +String Resource::get_id_for_path(const String &p_path) const { ResourceCache::path_cache_lock.read_lock(); if (ResourceCache::resource_path_cache[p_path].has(get_path())) { - int result = ResourceCache::resource_path_cache[p_path][get_path()]; + String result = ResourceCache::resource_path_cache[p_path][get_path()]; ResourceCache::path_cache_lock.read_unlock(); return result; } else { ResourceCache::path_cache_lock.read_unlock(); - return -1; + return ""; } } #endif @@ -414,7 +446,7 @@ Resource::~Resource() { HashMap<String, Resource *> ResourceCache::resources; #ifdef TOOLS_ENABLED -HashMap<String, HashMap<String, int>> ResourceCache::resource_path_cache; +HashMap<String, HashMap<String, String>> ResourceCache::resource_path_cache; #endif RWLock ResourceCache::lock; diff --git a/core/io/resource.h b/core/io/resource.h index 028fed1c6e..e864b371ad 100644 --- a/core/io/resource.h +++ b/core/io/resource.h @@ -31,6 +31,7 @@ #ifndef RESOURCE_H #define RESOURCE_H +#include "core/io/resource_uid.h" #include "core/object/class_db.h" #include "core/object/ref_counted.h" #include "core/templates/safe_refcount.h" @@ -59,7 +60,7 @@ private: String name; String path_cache; - int subindex = 0; + String scene_unique_id; virtual bool _use_builtin_script() const { return true; } @@ -105,8 +106,9 @@ public: virtual void set_path(const String &p_path, bool p_take_over = false); String get_path() const; - void set_subindex(int p_sub_index); - int get_subindex() const; + static String generate_scene_unique_id(); + void set_scene_unique_id(const String &p_id); + String get_scene_unique_id() const; virtual Ref<Resource> duplicate(bool p_subresources = false) const; Ref<Resource> duplicate_for_local_scene(Node *p_for_scene, Map<Ref<Resource>, Ref<Resource>> &remap_cache); @@ -140,8 +142,8 @@ public: #ifdef TOOLS_ENABLED //helps keep IDs same number when loading/saving scenes. -1 clears ID and it Returns -1 when no id stored - void set_id_for_path(const String &p_path, int p_id); - int get_id_for_path(const String &p_path) const; + void set_id_for_path(const String &p_path, const String &p_id); + String get_id_for_path(const String &p_path) const; #endif Resource(); @@ -156,7 +158,7 @@ class ResourceCache { static RWLock lock; static HashMap<String, Resource *> resources; #ifdef TOOLS_ENABLED - static HashMap<String, HashMap<String, int>> resource_path_cache; // each tscn has a set of resource paths and IDs + static HashMap<String, HashMap<String, String>> resource_path_cache; // Each tscn has a set of resource paths and IDs. static RWLock path_cache_lock; #endif // TOOLS_ENABLED friend void unregister_core_types(); diff --git a/core/io/resource_format_binary.cpp b/core/io/resource_format_binary.cpp index 0e9815245f..81ba5cc68d 100644 --- a/core/io/resource_format_binary.cpp +++ b/core/io/resource_format_binary.cpp @@ -84,9 +84,10 @@ enum { OBJECT_EXTERNAL_RESOURCE = 1, OBJECT_INTERNAL_RESOURCE = 2, OBJECT_EXTERNAL_RESOURCE_INDEX = 3, - //version 2: added 64 bits support for float and int - //version 3: changed nodepath encoding - FORMAT_VERSION = 3, + // Version 2: added 64 bits support for float and int. + // Version 3: changed nodepath encoding. + // Version 4: new string ID for ext/subresources, breaks forward compat. + FORMAT_VERSION = 4, FORMAT_VERSION_CAN_RENAME_DEPS = 1, FORMAT_VERSION_NO_NODEPATH_PROPERTY = 3, }; @@ -311,7 +312,14 @@ Error ResourceLoaderBinary::parse_variant(Variant &r_v) { } break; case OBJECT_INTERNAL_RESOURCE: { uint32_t index = f->get_32(); - String path = res_path + "::" + itos(index); + String path; + + if (using_named_scene_ids) { // New format. + ERR_FAIL_INDEX_V((int)index, internal_resources.size(), ERR_PARSE_ERROR); + path = internal_resources[index].path; + } else { + path += res_path + "::" + itos(index); + } //always use internal cache for loading internal resources if (!internal_index_cache.has(path)) { @@ -320,7 +328,6 @@ Error ResourceLoaderBinary::parse_variant(Variant &r_v) { } else { r_v = internal_index_cache[path]; } - } break; case OBJECT_EXTERNAL_RESOURCE: { //old file format, still around for compatibility @@ -378,7 +385,6 @@ Error ResourceLoaderBinary::parse_variant(Variant &r_v) { ERR_FAIL_V(ERR_FILE_CORRUPT); } break; } - } break; case VARIANT_CALLABLE: { r_v = Callable(); @@ -659,15 +665,17 @@ Error ResourceLoaderBinary::load() { //maybe it is loaded already String path; - int subindex = 0; + String id; if (!main) { path = internal_resources[i].path; if (path.begins_with("local://")) { path = path.replace_first("local://", ""); - subindex = path.to_int(); + id = path; path = res_path + "::" + path; + + internal_resources.write[i].path = path; // Update path. } if (cache_mode == ResourceFormatLoader::CACHE_MODE_REUSE) { @@ -722,7 +730,7 @@ Error ResourceLoaderBinary::load() { if (path != String() && cache_mode != ResourceFormatLoader::CACHE_MODE_IGNORE) { r->set_path(path, cache_mode == ResourceFormatLoader::CACHE_MODE_REPLACE); //if got here because the resource with same path has different type, replace it } - r->set_subindex(subindex); + r->set_scene_unique_id(id); } if (!main) { @@ -808,13 +816,18 @@ String ResourceLoaderBinary::get_unicode_string() { } void ResourceLoaderBinary::get_dependencies(FileAccess *p_f, List<String> *p_dependencies, bool p_add_types) { - open(p_f); + open(p_f, false, true); if (error) { return; } for (int i = 0; i < external_resources.size(); i++) { - String dep = external_resources[i].path; + String dep; + if (external_resources[i].uid != ResourceUID::INVALID_ID) { + dep = ResourceUID::get_singleton()->id_to_text(external_resources[i].uid); + } else { + dep = external_resources[i].path; + } if (p_add_types && external_resources[i].type != String()) { dep += "::" + external_resources[i].type; @@ -824,7 +837,7 @@ void ResourceLoaderBinary::get_dependencies(FileAccess *p_f, List<String> *p_dep } } -void ResourceLoaderBinary::open(FileAccess *p_f) { +void ResourceLoaderBinary::open(FileAccess *p_f, bool p_no_resources, bool p_keep_uuid_paths) { error = OK; f = p_f; @@ -879,10 +892,28 @@ void ResourceLoaderBinary::open(FileAccess *p_f) { print_bl("type: " + type); importmd_ofs = f->get_64(); - for (int i = 0; i < 14; i++) { + uint32_t flags = f->get_32(); + if (flags & ResourceFormatSaverBinaryInstance::FORMAT_FLAG_NAMED_SCENE_IDS) { + using_named_scene_ids = true; + } + if (flags & ResourceFormatSaverBinaryInstance::FORMAT_FLAG_UIDS) { + using_uids = true; + } + + if (using_uids) { + uid = f->get_64(); + } else { + uid = ResourceUID::INVALID_ID; + } + + for (int i = 0; i < 5; i++) { f->get_32(); //skip a few reserved fields } + if (p_no_resources) { + return; + } + uint32_t string_table_size = f->get_32(); string_map.resize(string_table_size); for (uint32_t i = 0; i < string_table_size; i++) { @@ -896,8 +927,18 @@ void ResourceLoaderBinary::open(FileAccess *p_f) { for (uint32_t i = 0; i < ext_resources_size; i++) { ExtResource er; er.type = get_unicode_string(); - er.path = get_unicode_string(); + if (using_uids) { + er.uid = f->get_64(); + if (!p_keep_uuid_paths && er.uid != ResourceUID::INVALID_ID) { + if (ResourceUID::get_singleton()->has_id(er.uid)) { + // If a UID is found and the path is valid, it will be used, otherwise, it falls back to the path. + er.path = ResourceUID::get_singleton()->get_id_path(er.uid); + } else { + WARN_PRINT(String(res_path + ": In external resouce #" + itos(i) + ", invalid UUID: " + ResourceUID::get_singleton()->id_to_text(er.uid) + " - using text path instead: " + er.path).utf8().get_data()); + } + } + } external_resources.push_back(er); } @@ -1013,8 +1054,8 @@ void ResourceFormatLoaderBinary::get_recognized_extensions_for_type(const String extensions.sort(); - for (List<String>::Element *E = extensions.front(); E; E = E->next()) { - String ext = E->get().to_lower(); + for (String &E : extensions) { + String ext = E.to_lower(); p_extensions->push_back(ext); } } @@ -1024,8 +1065,8 @@ void ResourceFormatLoaderBinary::get_recognized_extensions(List<String> *p_exten ClassDB::get_resource_base_extensions(&extensions); extensions.sort(); - for (List<String>::Element *E = extensions.front(); E; E = E->next()) { - String ext = E->get().to_lower(); + for (String &E : extensions) { + String ext = E.to_lower(); p_extensions->push_back(ext); } } @@ -1161,8 +1202,15 @@ Error ResourceFormatLoaderBinary::rename_dependencies(const String &p_path, cons uint64_t importmd_ofs = f->get_64(); fw->store_64(0); //metadata offset - for (int i = 0; i < 14; i++) { - fw->store_32(0); + uint32_t flags = f->get_32(); + bool using_uids = (flags & ResourceFormatSaverBinaryInstance::FORMAT_FLAG_UIDS); + uint64_t uid_data = f->get_64(); + + fw->store_32(flags); + fw->store_64(uid_data); + + for (int i = 0; i < 5; i++) { + f->store_32(0); // reserved f->get_32(); } @@ -1183,6 +1231,16 @@ Error ResourceFormatLoaderBinary::rename_dependencies(const String &p_path, cons String type = get_ustring(f); String path = get_ustring(f); + if (using_uids) { + ResourceUID::ID uid = f->get_64(); + if (uid != ResourceUID::INVALID_ID) { + if (ResourceUID::get_singleton()->has_id(uid)) { + // If a UID is found and the path is valid, it will be used, otherwise, it falls back to the path. + path = ResourceUID::get_singleton()->get_id_path(uid); + } + } + } + bool relative = false; if (!path.begins_with("res://")) { path = local_path.plus_file(path).simplify_path(); @@ -1194,6 +1252,8 @@ Error ResourceFormatLoaderBinary::rename_dependencies(const String &p_path, cons path = np; } + String full_path = path; + if (relative) { //restore relative path = local_path.path_to_file(path); @@ -1201,6 +1261,11 @@ Error ResourceFormatLoaderBinary::rename_dependencies(const String &p_path, cons save_ustring(fw, type); save_ustring(fw, path); + + if (using_uids) { + ResourceUID::ID uid = ResourceSaver::get_resource_id_for_path(full_path); + f->store_64(uid); + } } int64_t size_diff = (int64_t)fw->get_position() - (int64_t)f->get_position(); @@ -1256,6 +1321,28 @@ String ResourceFormatLoaderBinary::get_resource_type(const String &p_path) const return ClassDB::get_compatibility_remapped_class(r); } +ResourceUID::ID ResourceFormatLoaderBinary::get_resource_uid(const String &p_path) const { + String ext = p_path.get_extension().to_lower(); + if (!ClassDB::is_resource_extension(ext)) { + return ResourceUID::INVALID_ID; + } + + FileAccess *f = FileAccess::open(p_path, FileAccess::READ); + if (!f) { + return ResourceUID::INVALID_ID; //could not read + } + + ResourceLoaderBinary loader; + loader.local_path = ProjectSettings::get_singleton()->localize_path(p_path); + loader.res_path = loader.local_path; + //loader.set_local_path( Globals::get_singleton()->localize_path(p_path) ); + loader.open(f, true); + if (loader.error != OK) { + return ResourceUID::INVALID_ID; //could not read + } + return loader.uid; +} + /////////////////////////////////////////////////////////// /////////////////////////////////////////////////////////// /////////////////////////////////////////////////////////// @@ -1269,11 +1356,7 @@ void ResourceFormatSaverBinaryInstance::_pad_buffer(FileAccess *f, int p_bytes) } } -void ResourceFormatSaverBinaryInstance::_write_variant(const Variant &p_property, const PropertyInfo &p_hint) { - write_variant(f, p_property, resource_set, external_resources, string_map, p_hint); -} - -void ResourceFormatSaverBinaryInstance::write_variant(FileAccess *f, const Variant &p_property, Set<RES> &resource_set, Map<RES, int> &external_resources, Map<StringName, int> &string_map, const PropertyInfo &p_hint) { +void ResourceFormatSaverBinaryInstance::write_variant(FileAccess *f, const Variant &p_property, Map<RES, int> &resource_map, Map<RES, int> &external_resources, Map<StringName, int> &string_map, const PropertyInfo &p_hint) { switch (p_property.get_type()) { case Variant::NIL: { f->store_32(VARIANT_NIL); @@ -1492,13 +1575,13 @@ void ResourceFormatSaverBinaryInstance::write_variant(FileAccess *f, const Varia f->store_32(OBJECT_EXTERNAL_RESOURCE_INDEX); f->store_32(external_resources[res]); } else { - if (!resource_set.has(res)) { + if (!resource_map.has(res)) { f->store_32(OBJECT_EMPTY); ERR_FAIL_MSG("Resource was not pre cached for the resource section, most likely due to circular reference."); } f->store_32(OBJECT_INTERNAL_RESOURCE); - f->store_32(res->get_subindex()); + f->store_32(resource_map[res]); //internal resource } @@ -1520,14 +1603,14 @@ void ResourceFormatSaverBinaryInstance::write_variant(FileAccess *f, const Varia List<Variant> keys; d.get_key_list(&keys); - for (List<Variant>::Element *E = keys.front(); E; E = E->next()) { + for (Variant &E : keys) { /* - if (!_check_type(dict[E->get()])) + if (!_check_type(dict[E])) continue; */ - write_variant(f, E->get(), resource_set, external_resources, string_map); - write_variant(f, d[E->get()], resource_set, external_resources, string_map); + write_variant(f, E, resource_map, external_resources, string_map); + write_variant(f, d[E], resource_map, external_resources, string_map); } } break; @@ -1536,7 +1619,7 @@ void ResourceFormatSaverBinaryInstance::write_variant(FileAccess *f, const Varia Array a = p_property; f->store_32(uint32_t(a.size())); for (int i = 0; i < a.size(); i++) { - write_variant(f, a[i], resource_set, external_resources, string_map); + write_variant(f, a[i], resource_map, external_resources, string_map); } } break; @@ -1677,15 +1760,15 @@ void ResourceFormatSaverBinaryInstance::_find_resources(const Variant &p_variant res->get_property_list(&property_list); - for (List<PropertyInfo>::Element *E = property_list.front(); E; E = E->next()) { - if (E->get().usage & PROPERTY_USAGE_STORAGE) { - Variant value = res->get(E->get().name); - if (E->get().usage & PROPERTY_USAGE_RESOURCE_NOT_PERSISTENT) { + for (PropertyInfo &E : property_list) { + if (E.usage & PROPERTY_USAGE_STORAGE) { + Variant value = res->get(E.name); + if (E.usage & PROPERTY_USAGE_RESOURCE_NOT_PERSISTENT) { RES sres = value; if (sres.is_valid()) { NonPersistentKey npk; npk.base = res; - npk.property = E->get().name; + npk.property = E.name; non_persistent_map[npk] = sres; resource_set.insert(sres); saved_resources.push_back(sres); @@ -1715,9 +1798,9 @@ void ResourceFormatSaverBinaryInstance::_find_resources(const Variant &p_variant Dictionary d = p_variant; List<Variant> keys; d.get_key_list(&keys); - for (List<Variant>::Element *E = keys.front(); E; E = E->next()) { - _find_resources(E->get()); - Variant v = d[E->get()]; + for (Variant &E : keys) { + _find_resources(E); + Variant v = d[E]; _find_resources(v); } } break; @@ -1816,46 +1899,49 @@ Error ResourceFormatSaverBinaryInstance::save(const String &p_path, const RES &p save_unicode_string(f, p_resource->get_class()); f->store_64(0); //offset to import metadata - for (int i = 0; i < 14; i++) { + f->store_32(FORMAT_FLAG_NAMED_SCENE_IDS | FORMAT_FLAG_UIDS); + ResourceUID::ID uid = ResourceSaver::get_resource_id_for_path(p_path, true); + f->store_64(uid); + for (int i = 0; i < 5; i++) { f->store_32(0); // reserved } List<ResourceData> resources; { - for (List<RES>::Element *E = saved_resources.front(); E; E = E->next()) { + for (RES &E : saved_resources) { ResourceData &rd = resources.push_back(ResourceData())->get(); - rd.type = E->get()->get_class(); + rd.type = E->get_class(); List<PropertyInfo> property_list; - E->get()->get_property_list(&property_list); + E->get_property_list(&property_list); - for (List<PropertyInfo>::Element *F = property_list.front(); F; F = F->next()) { - if (skip_editor && F->get().name.begins_with("__editor")) { + for (PropertyInfo &F : property_list) { + if (skip_editor && F.name.begins_with("__editor")) { continue; } - if ((F->get().usage & PROPERTY_USAGE_STORAGE)) { + if ((F.usage & PROPERTY_USAGE_STORAGE)) { Property p; - p.name_idx = get_string_index(F->get().name); + p.name_idx = get_string_index(F.name); - if (F->get().usage & PROPERTY_USAGE_RESOURCE_NOT_PERSISTENT) { + if (F.usage & PROPERTY_USAGE_RESOURCE_NOT_PERSISTENT) { NonPersistentKey npk; - npk.base = E->get(); - npk.property = F->get().name; + npk.base = E; + npk.property = F.name; if (non_persistent_map.has(npk)) { p.value = non_persistent_map[npk]; } } else { - p.value = E->get()->get(F->get().name); + p.value = E->get(F.name); } - Variant default_value = ClassDB::class_get_default_property_value(E->get()->get_class(), F->get().name); + Variant default_value = ClassDB::class_get_default_property_value(E->get_class(), F.name); if (default_value.get_type() != Variant::NIL && bool(Variant::evaluate(Variant::OP_EQUAL, p.value, default_value))) { continue; } - p.pi = F->get(); + p.pi = F; rd.properties.push_back(p); } @@ -1882,41 +1968,47 @@ Error ResourceFormatSaverBinaryInstance::save(const String &p_path, const RES &p String path = save_order[i]->get_path(); path = relative_paths ? local_path.path_to_file(path) : path; save_unicode_string(f, path); + ResourceUID::ID ruid = ResourceSaver::get_resource_id_for_path(save_order[i]->get_path(), false); + f->store_64(ruid); } // save internal resource table f->store_32(saved_resources.size()); //amount of internal resources Vector<uint64_t> ofs_pos; - Set<int> used_indices; + Set<String> used_unique_ids; - for (List<RES>::Element *E = saved_resources.front(); E; E = E->next()) { - RES r = E->get(); + for (RES &r : saved_resources) { if (r->get_path() == "" || r->get_path().find("::") != -1) { - if (r->get_subindex() != 0) { - if (used_indices.has(r->get_subindex())) { - r->set_subindex(0); //repeated + if (r->get_scene_unique_id() != "") { + if (used_unique_ids.has(r->get_scene_unique_id())) { + r->set_scene_unique_id(""); } else { - used_indices.insert(r->get_subindex()); + used_unique_ids.insert(r->get_scene_unique_id()); } } } } - for (List<RES>::Element *E = saved_resources.front(); E; E = E->next()) { - RES r = E->get(); + Map<RES, int> resource_map; + int res_index = 0; + for (RES &r : saved_resources) { if (r->get_path() == "" || r->get_path().find("::") != -1) { - if (r->get_subindex() == 0) { - int new_subindex = 1; - if (used_indices.size()) { - new_subindex = used_indices.back()->get() + 1; + if (r->get_scene_unique_id() == "") { + String new_id; + + while (true) { + new_id = r->get_class() + "_" + Resource::generate_scene_unique_id(); + if (!used_unique_ids.has(new_id)) { + break; + } } - r->set_subindex(new_subindex); - used_indices.insert(new_subindex); + r->set_scene_unique_id(new_id); + used_unique_ids.insert(new_id); } - save_unicode_string(f, "local://" + itos(r->get_subindex())); + save_unicode_string(f, "local://" + r->get_scene_unique_id()); if (takeover_paths) { - r->set_path(p_path + "::" + itos(r->get_subindex()), true); + r->set_path(p_path + "::" + r->get_scene_unique_id(), true); } #ifdef TOOLS_ENABLED r->set_edited(false); @@ -1926,22 +2018,21 @@ Error ResourceFormatSaverBinaryInstance::save(const String &p_path, const RES &p } ofs_pos.push_back(f->get_position()); f->store_64(0); //offset in 64 bits + resource_map[r] = res_index++; } Vector<uint64_t> ofs_table; //now actually save the resources - for (List<ResourceData>::Element *E = resources.front(); E; E = E->next()) { - ResourceData &rd = E->get(); - + for (ResourceData &rd : resources) { ofs_table.push_back(f->get_position()); save_unicode_string(f, rd.type); f->store_32(rd.properties.size()); - for (List<Property>::Element *F = rd.properties.front(); F; F = F->next()) { - Property &p = F->get(); + for (Property &F : rd.properties) { + Property &p = F; f->store_32(p.name_idx); - _write_variant(p.value, F->get().pi); + write_variant(f, p.value, resource_map, external_resources, string_map, F.pi); } } diff --git a/core/io/resource_format_binary.h b/core/io/resource_format_binary.h index abc7403935..ac964d2053 100644 --- a/core/io/resource_format_binary.h +++ b/core/io/resource_format_binary.h @@ -47,6 +47,8 @@ class ResourceLoaderBinary { uint64_t importmd_ofs = 0; + ResourceUID::ID uid = ResourceUID::INVALID_ID; + Vector<char> str_buf; List<RES> resource_cache; @@ -57,9 +59,12 @@ class ResourceLoaderBinary { struct ExtResource { String path; String type; + ResourceUID::ID uid = ResourceUID::INVALID_ID; RES cache; }; + bool using_named_scene_ids = false; + bool using_uids = false; bool use_sub_threads = false; float *progress = nullptr; Vector<ExtResource> external_resources; @@ -93,7 +98,7 @@ public: void set_translation_remapped(bool p_remapped); void set_remaps(const Map<String, String> &p_remaps) { remaps = p_remaps; } - void open(FileAccess *p_f); + void open(FileAccess *p_f, bool p_no_resources = false, bool p_keep_uuid_paths = false); String recognize(FileAccess *p_f); void get_dependencies(FileAccess *p_f, List<String> *p_dependencies, bool p_add_types); @@ -108,6 +113,7 @@ public: virtual void get_recognized_extensions(List<String> *p_extensions) const; virtual bool handles_type(const String &p_type) const; virtual String get_resource_type(const String &p_path) const; + virtual ResourceUID::ID get_resource_uid(const String &p_path) const; virtual void get_dependencies(const String &p_path, List<String> *p_dependencies, bool p_add_types = false); virtual Error rename_dependencies(const String &p_path, const Map<String, String> &p_map); }; @@ -150,14 +156,17 @@ class ResourceFormatSaverBinaryInstance { }; static void _pad_buffer(FileAccess *f, int p_bytes); - void _write_variant(const Variant &p_property, const PropertyInfo &p_hint = PropertyInfo()); void _find_resources(const Variant &p_variant, bool p_main = false); static void save_unicode_string(FileAccess *f, const String &p_string, bool p_bit_on_len = false); int get_string_index(const String &p_string); public: + enum { + FORMAT_FLAG_NAMED_SCENE_IDS = 1, + FORMAT_FLAG_UIDS = 2, + }; Error save(const String &p_path, const RES &p_resource, uint32_t p_flags = 0); - static void write_variant(FileAccess *f, const Variant &p_property, Set<RES> &resource_set, Map<RES, int> &external_resources, Map<StringName, int> &string_map, const PropertyInfo &p_hint = PropertyInfo()); + static void write_variant(FileAccess *f, const Variant &p_property, Map<RES, int> &resource_map, Map<RES, int> &external_resources, Map<StringName, int> &string_map, const PropertyInfo &p_hint = PropertyInfo()); }; class ResourceFormatSaverBinary : public ResourceFormatSaver { diff --git a/core/io/resource_importer.cpp b/core/io/resource_importer.cpp index b503655edd..e7c0176e5a 100644 --- a/core/io/resource_importer.cpp +++ b/core/io/resource_importer.cpp @@ -93,6 +93,8 @@ Error ResourceFormatImporter::_get_path_and_type(const String &p_path, PathAndTy r_path_and_type.type = ClassDB::get_compatibility_remapped_class(value); } else if (assign == "importer") { r_path_and_type.importer = value; + } else if (assign == "uid") { + r_path_and_type.uid = ResourceUID::get_singleton()->text_to_id(value); } else if (assign == "group_file") { r_path_and_type.group_file = value; } else if (assign == "metadata") { @@ -146,10 +148,10 @@ void ResourceFormatImporter::get_recognized_extensions(List<String> *p_extension for (int i = 0; i < importers.size(); i++) { List<String> local_exts; importers[i]->get_recognized_extensions(&local_exts); - for (List<String>::Element *F = local_exts.front(); F; F = F->next()) { - if (!found.has(F->get())) { - p_extensions->push_back(F->get()); - found.insert(F->get()); + for (String &F : local_exts) { + if (!found.has(F)) { + p_extensions->push_back(F); + found.insert(F); } } } @@ -175,10 +177,10 @@ void ResourceFormatImporter::get_recognized_extensions_for_type(const String &p_ List<String> local_exts; importers[i]->get_recognized_extensions(&local_exts); - for (List<String>::Element *F = local_exts.front(); F; F = F->next()) { - if (!found.has(F->get())) { - p_extensions->push_back(F->get()); - found.insert(F->get()); + for (String &F : local_exts) { + if (!found.has(F)) { + p_extensions->push_back(F); + found.insert(F); } } } @@ -336,6 +338,17 @@ String ResourceFormatImporter::get_resource_type(const String &p_path) const { return pat.type; } +ResourceUID::ID ResourceFormatImporter::get_resource_uid(const String &p_path) const { + PathAndType pat; + Error err = _get_path_and_type(p_path, pat); + + if (err != OK) { + return ResourceUID::INVALID_ID; + } + + return pat.uid; +} + Variant ResourceFormatImporter::get_resource_metadata(const String &p_path) const { PathAndType pat; Error err = _get_path_and_type(p_path, pat); @@ -372,8 +385,8 @@ void ResourceFormatImporter::get_importers_for_extension(const String &p_extensi for (int i = 0; i < importers.size(); i++) { List<String> local_exts; importers[i]->get_recognized_extensions(&local_exts); - for (List<String>::Element *F = local_exts.front(); F; F = F->next()) { - if (p_extension.to_lower() == F->get()) { + for (String &F : local_exts) { + if (p_extension.to_lower() == F) { r_importers->push_back(importers[i]); } } @@ -393,8 +406,8 @@ Ref<ResourceImporter> ResourceFormatImporter::get_importer_by_extension(const St for (int i = 0; i < importers.size(); i++) { List<String> local_exts; importers[i]->get_recognized_extensions(&local_exts); - for (List<String>::Element *F = local_exts.front(); F; F = F->next()) { - if (p_extension.to_lower() == F->get() && importers[i]->get_priority() > priority) { + for (String &F : local_exts) { + if (p_extension.to_lower() == F && importers[i]->get_priority() > priority) { importer = importers[i]; priority = importers[i]->get_priority(); } @@ -445,3 +458,8 @@ ResourceFormatImporter *ResourceFormatImporter::singleton = nullptr; ResourceFormatImporter::ResourceFormatImporter() { singleton = this; } + +void ResourceImporter::_bind_methods() { + BIND_ENUM_CONSTANT(IMPORT_ORDER_DEFAULT); + BIND_ENUM_CONSTANT(IMPORT_ORDER_SCENE); +} diff --git a/core/io/resource_importer.h b/core/io/resource_importer.h index 2ceeb176e5..a1cacbd306 100644 --- a/core/io/resource_importer.h +++ b/core/io/resource_importer.h @@ -42,6 +42,7 @@ class ResourceFormatImporter : public ResourceFormatLoader { String importer; String group_file; Variant metadata; + uint64_t uid = ResourceUID::INVALID_ID; }; Error _get_path_and_type(const String &p_path, PathAndType &r_path_and_type, bool *r_valid = nullptr) const; @@ -63,6 +64,8 @@ public: virtual bool recognize_path(const String &p_path, const String &p_for_type = String()) const; virtual bool handles_type(const String &p_type) const; virtual String get_resource_type(const String &p_path) const; + virtual ResourceUID::ID get_resource_uid(const String &p_path) const; + virtual Variant get_resource_metadata(const String &p_path) const; virtual bool is_import_valid(const String &p_path) const; virtual void get_dependencies(const String &p_path, List<String> *p_dependencies, bool p_add_types = false); @@ -96,6 +99,9 @@ public: class ResourceImporter : public RefCounted { GDCLASS(ResourceImporter, RefCounted); +protected: + static void _bind_methods(); + public: virtual String get_importer_name() const = 0; virtual String get_visible_name() const = 0; @@ -103,7 +109,7 @@ public: virtual String get_save_extension() const = 0; virtual String get_resource_type() const = 0; virtual float get_priority() const { return 1.0; } - virtual int get_import_order() const { return 0; } + virtual int get_import_order() const { return IMPORT_ORDER_DEFAULT; } virtual int get_format_version() const { return 0; } struct ImportOption { @@ -117,6 +123,11 @@ public: ImportOption() {} }; + enum ImportOrder { + IMPORT_ORDER_DEFAULT = 0, + IMPORT_ORDER_SCENE = 100, + }; + virtual bool has_advanced_options() const { return false; } virtual void show_advanced_options(const String &p_path) {} @@ -137,4 +148,6 @@ public: virtual String get_import_settings_string() const { return String(); } }; +VARIANT_ENUM_CAST(ResourceImporter::ImportOrder); + #endif // RESOURCE_IMPORTER_H diff --git a/core/io/resource_loader.cpp b/core/io/resource_loader.cpp index c5dfe1f2b0..7e69b2ecab 100644 --- a/core/io/resource_loader.cpp +++ b/core/io/resource_loader.cpp @@ -58,8 +58,8 @@ bool ResourceFormatLoader::recognize_path(const String &p_path, const String &p_ get_recognized_extensions_for_type(p_for_type, &extensions); } - for (List<String>::Element *E = extensions.front(); E; E = E->next()) { - if (E->get().nocasecmp_to(extension) == 0) { + for (String &E : extensions) { + if (E.nocasecmp_to(extension) == 0) { return true; } } @@ -84,6 +84,14 @@ String ResourceFormatLoader::get_resource_type(const String &p_path) const { return ""; } +ResourceUID::ID ResourceFormatLoader::get_resource_uid(const String &p_path) const { + if (get_script_instance() && get_script_instance()->has_method("_get_resource_uid")) { + return get_script_instance()->call("_get_resource_uid", p_path); + } + + return ResourceUID::INVALID_ID; +} + void ResourceFormatLoader::get_recognized_extensions_for_type(const String &p_type, List<String> *p_extensions) const { if (p_type == "" || handles_type(p_type)) { get_recognized_extensions(p_extensions); @@ -270,13 +278,18 @@ void ResourceLoader::_thread_load_function(void *p_userdata) { thread_load_mutex->unlock(); } -Error ResourceLoader::load_threaded_request(const String &p_path, const String &p_type_hint, bool p_use_sub_threads, ResourceFormatLoader::CacheMode p_cache_mode, const String &p_source_resource) { - String local_path; - if (p_path.is_rel_path()) { - local_path = "res://" + p_path; +static String _validate_local_path(const String &p_path) { + ResourceUID::ID uid = ResourceUID::get_singleton()->text_to_id(p_path); + if (uid != ResourceUID::INVALID_ID) { + return ResourceUID::get_singleton()->get_id_path(uid); + } else if (p_path.is_rel_path()) { + return "res://" + p_path; } else { - local_path = ProjectSettings::get_singleton()->localize_path(p_path); + return ProjectSettings::get_singleton()->localize_path(p_path); } +} +Error ResourceLoader::load_threaded_request(const String &p_path, const String &p_type_hint, bool p_use_sub_threads, ResourceFormatLoader::CacheMode p_cache_mode, const String &p_source_resource) { + String local_path = _validate_local_path(p_path); thread_load_mutex->lock(); @@ -399,12 +412,7 @@ float ResourceLoader::_dependency_get_progress(const String &p_path) { } ResourceLoader::ThreadLoadStatus ResourceLoader::load_threaded_get_status(const String &p_path, float *r_progress) { - String local_path; - if (p_path.is_rel_path()) { - local_path = "res://" + p_path; - } else { - local_path = ProjectSettings::get_singleton()->localize_path(p_path); - } + String local_path = _validate_local_path(p_path); thread_load_mutex->lock(); if (!thread_load_tasks.has(local_path)) { @@ -424,12 +432,7 @@ ResourceLoader::ThreadLoadStatus ResourceLoader::load_threaded_get_status(const } RES ResourceLoader::load_threaded_get(const String &p_path, Error *r_error) { - String local_path; - if (p_path.is_rel_path()) { - local_path = "res://" + p_path; - } else { - local_path = ProjectSettings::get_singleton()->localize_path(p_path); - } + String local_path = _validate_local_path(p_path); thread_load_mutex->lock(); if (!thread_load_tasks.has(local_path)) { @@ -510,12 +513,7 @@ RES ResourceLoader::load(const String &p_path, const String &p_type_hint, Resour *r_error = ERR_CANT_OPEN; } - String local_path; - if (p_path.is_rel_path()) { - local_path = "res://" + p_path; - } else { - local_path = ProjectSettings::get_singleton()->localize_path(p_path); - } + String local_path = _validate_local_path(p_path); if (p_cache_mode != ResourceFormatLoader::CACHE_MODE_IGNORE) { thread_load_mutex->lock(); @@ -612,12 +610,7 @@ RES ResourceLoader::load(const String &p_path, const String &p_type_hint, Resour } bool ResourceLoader::exists(const String &p_path, const String &p_type_hint) { - String local_path; - if (p_path.is_rel_path()) { - local_path = "res://" + p_path; - } else { - local_path = ProjectSettings::get_singleton()->localize_path(p_path); - } + String local_path = _validate_local_path(p_path); if (ResourceCache::has(local_path)) { return true; // If cached, it probably exists @@ -677,14 +670,7 @@ void ResourceLoader::remove_resource_format_loader(Ref<ResourceFormatLoader> p_f } int ResourceLoader::get_import_order(const String &p_path) { - String path = _path_remap(p_path); - - String local_path; - if (path.is_rel_path()) { - local_path = "res://" + path; - } else { - local_path = ProjectSettings::get_singleton()->localize_path(path); - } + String local_path = _path_remap(_validate_local_path(p_path)); for (int i = 0; i < loader_count; i++) { if (!loader[i]->recognize_path(local_path)) { @@ -702,14 +688,7 @@ int ResourceLoader::get_import_order(const String &p_path) { } String ResourceLoader::get_import_group_file(const String &p_path) { - String path = _path_remap(p_path); - - String local_path; - if (path.is_rel_path()) { - local_path = "res://" + path; - } else { - local_path = ProjectSettings::get_singleton()->localize_path(path); - } + String local_path = _path_remap(_validate_local_path(p_path)); for (int i = 0; i < loader_count; i++) { if (!loader[i]->recognize_path(local_path)) { @@ -727,14 +706,7 @@ String ResourceLoader::get_import_group_file(const String &p_path) { } bool ResourceLoader::is_import_valid(const String &p_path) { - String path = _path_remap(p_path); - - String local_path; - if (path.is_rel_path()) { - local_path = "res://" + path; - } else { - local_path = ProjectSettings::get_singleton()->localize_path(path); - } + String local_path = _path_remap(_validate_local_path(p_path)); for (int i = 0; i < loader_count; i++) { if (!loader[i]->recognize_path(local_path)) { @@ -752,14 +724,7 @@ bool ResourceLoader::is_import_valid(const String &p_path) { } bool ResourceLoader::is_imported(const String &p_path) { - String path = _path_remap(p_path); - - String local_path; - if (path.is_rel_path()) { - local_path = "res://" + path; - } else { - local_path = ProjectSettings::get_singleton()->localize_path(path); - } + String local_path = _path_remap(_validate_local_path(p_path)); for (int i = 0; i < loader_count; i++) { if (!loader[i]->recognize_path(local_path)) { @@ -777,14 +742,7 @@ bool ResourceLoader::is_imported(const String &p_path) { } void ResourceLoader::get_dependencies(const String &p_path, List<String> *p_dependencies, bool p_add_types) { - String path = _path_remap(p_path); - - String local_path; - if (path.is_rel_path()) { - local_path = "res://" + path; - } else { - local_path = ProjectSettings::get_singleton()->localize_path(path); - } + String local_path = _path_remap(_validate_local_path(p_path)); for (int i = 0; i < loader_count; i++) { if (!loader[i]->recognize_path(local_path)) { @@ -800,14 +758,7 @@ void ResourceLoader::get_dependencies(const String &p_path, List<String> *p_depe } Error ResourceLoader::rename_dependencies(const String &p_path, const Map<String, String> &p_map) { - String path = _path_remap(p_path); - - String local_path; - if (path.is_rel_path()) { - local_path = "res://" + path; - } else { - local_path = ProjectSettings::get_singleton()->localize_path(path); - } + String local_path = _path_remap(_validate_local_path(p_path)); for (int i = 0; i < loader_count; i++) { if (!loader[i]->recognize_path(local_path)) { @@ -825,12 +776,7 @@ Error ResourceLoader::rename_dependencies(const String &p_path, const Map<String } String ResourceLoader::get_resource_type(const String &p_path) { - String local_path; - if (p_path.is_rel_path()) { - local_path = "res://" + p_path; - } else { - local_path = ProjectSettings::get_singleton()->localize_path(p_path); - } + String local_path = _validate_local_path(p_path); for (int i = 0; i < loader_count; i++) { String result = loader[i]->get_resource_type(local_path); @@ -842,6 +788,19 @@ String ResourceLoader::get_resource_type(const String &p_path) { return ""; } +ResourceUID::ID ResourceLoader::get_resource_uid(const String &p_path) { + String local_path = _validate_local_path(p_path); + + for (int i = 0; i < loader_count; i++) { + ResourceUID::ID id = loader[i]->get_resource_uid(local_path); + if (id != ResourceUID::INVALID_ID) { + return id; + } + } + + return ResourceUID::INVALID_ID; +} + String ResourceLoader::_path_remap(const String &p_path, bool *r_translation_remapped) { String new_path = p_path; @@ -978,15 +937,15 @@ void ResourceLoader::load_translation_remaps() { Dictionary remaps = ProjectSettings::get_singleton()->get("internationalization/locale/translation_remaps"); List<Variant> keys; remaps.get_key_list(&keys); - for (List<Variant>::Element *E = keys.front(); E; E = E->next()) { - Array langs = remaps[E->get()]; + for (Variant &E : keys) { + Array langs = remaps[E]; Vector<String> lang_remaps; lang_remaps.resize(langs.size()); for (int i = 0; i < langs.size(); i++) { lang_remaps.write[i] = langs[i]; } - translation_remaps[String(E->get())] = lang_remaps; + translation_remaps[String(E)] = lang_remaps; } } @@ -1071,8 +1030,7 @@ void ResourceLoader::add_custom_loaders() { List<StringName> global_classes; ScriptServer::get_global_class_list(&global_classes); - for (List<StringName>::Element *E = global_classes.front(); E; E = E->next()) { - StringName class_name = E->get(); + for (StringName &class_name : global_classes) { StringName base_class = ScriptServer::get_global_class_native_base(class_name); if (base_class == custom_loader_base_class) { diff --git a/core/io/resource_loader.h b/core/io/resource_loader.h index c656b9a69c..b9e234fdd2 100644 --- a/core/io/resource_loader.h +++ b/core/io/resource_loader.h @@ -56,6 +56,7 @@ public: virtual bool recognize_path(const String &p_path, const String &p_for_type = String()) const; virtual bool handles_type(const String &p_type) const; virtual String get_resource_type(const String &p_path) const; + virtual ResourceUID::ID get_resource_uid(const String &p_path) const; virtual void get_dependencies(const String &p_path, List<String> *p_dependencies, bool p_add_types = false); virtual Error rename_dependencies(const String &p_path, const Map<String, String> &p_map); virtual bool is_import_valid(const String &p_path) const { return true; } @@ -157,6 +158,7 @@ public: static void add_resource_format_loader(Ref<ResourceFormatLoader> p_format_loader, bool p_at_front = false); static void remove_resource_format_loader(Ref<ResourceFormatLoader> p_format_loader); static String get_resource_type(const String &p_path); + static ResourceUID::ID get_resource_uid(const String &p_path); static void get_dependencies(const String &p_path, List<String> *p_dependencies, bool p_add_types = false); static Error rename_dependencies(const String &p_path, const Map<String, String> &p_map); static bool is_import_valid(const String &p_path); diff --git a/core/io/resource_saver.cpp b/core/io/resource_saver.cpp index 80cb85fba3..6158f421d1 100644 --- a/core/io/resource_saver.cpp +++ b/core/io/resource_saver.cpp @@ -39,6 +39,7 @@ Ref<ResourceFormatSaver> ResourceSaver::saver[MAX_SAVERS]; int ResourceSaver::saver_count = 0; bool ResourceSaver::timestamp_on_save = false; ResourceSavedCallback ResourceSaver::save_callback = nullptr; +ResourceSaverGetResourceIDForPath ResourceSaver::save_get_id_for_path = nullptr; Error ResourceFormatSaver::save(const String &p_path, const RES &p_resource, uint32_t p_flags) { if (get_script_instance() && get_script_instance()->has_method("_save")) { @@ -94,8 +95,8 @@ Error ResourceSaver::save(const String &p_path, const RES &p_resource, uint32_t bool recognized = false; saver[i]->get_recognized_extensions(p_resource, &extensions); - for (List<String>::Element *E = extensions.front(); E; E = E->next()) { - if (E->get().nocasecmp_to(extension) == 0) { + for (String &E : extensions) { + if (E.nocasecmp_to(extension) == 0) { recognized = true; } } @@ -236,8 +237,7 @@ void ResourceSaver::add_custom_savers() { List<StringName> global_classes; ScriptServer::get_global_class_list(&global_classes); - for (List<StringName>::Element *E = global_classes.front(); E; E = E->next()) { - StringName class_name = E->get(); + for (StringName &class_name : global_classes) { StringName base_class = ScriptServer::get_global_class_native_base(class_name); if (base_class == custom_saver_base_class) { @@ -259,3 +259,14 @@ void ResourceSaver::remove_custom_savers() { remove_resource_format_saver(custom_savers[i]); } } + +ResourceUID::ID ResourceSaver::get_resource_id_for_path(const String &p_path, bool p_generate) { + if (save_get_id_for_path) { + return save_get_id_for_path(p_path, p_generate); + } + return ResourceUID::INVALID_ID; +} + +void ResourceSaver::set_get_resource_id_for_path(ResourceSaverGetResourceIDForPath p_callback) { + save_get_id_for_path = p_callback; +} diff --git a/core/io/resource_saver.h b/core/io/resource_saver.h index 07154aac4d..2fc8d32126 100644 --- a/core/io/resource_saver.h +++ b/core/io/resource_saver.h @@ -48,6 +48,7 @@ public: }; typedef void (*ResourceSavedCallback)(Ref<Resource> p_resource, const String &p_path); +typedef ResourceUID::ID (*ResourceSaverGetResourceIDForPath)(const String &p_path, bool p_generate); class ResourceSaver { enum { @@ -58,6 +59,7 @@ class ResourceSaver { static int saver_count; static bool timestamp_on_save; static ResourceSavedCallback save_callback; + static ResourceSaverGetResourceIDForPath save_get_id_for_path; static Ref<ResourceFormatSaver> _find_custom_resource_format_saver(String path); @@ -80,7 +82,10 @@ public: static void set_timestamp_on_save(bool p_timestamp) { timestamp_on_save = p_timestamp; } static bool get_timestamp_on_save() { return timestamp_on_save; } + static ResourceUID::ID get_resource_id_for_path(const String &p_path, bool p_generate = false); + static void set_save_callback(ResourceSavedCallback p_callback); + static void set_get_resource_id_for_path(ResourceSaverGetResourceIDForPath p_callback); static bool add_custom_resource_format_saver(String script_path); static void remove_custom_resource_format_saver(String script_path); diff --git a/core/io/resource_uid.cpp b/core/io/resource_uid.cpp new file mode 100644 index 0000000000..d4e8fcb6b0 --- /dev/null +++ b/core/io/resource_uid.cpp @@ -0,0 +1,262 @@ +/*************************************************************************/ +/* resource_uid.cpp */ +/*************************************************************************/ +/* This file is part of: */ +/* GODOT ENGINE */ +/* https://godotengine.org */ +/*************************************************************************/ +/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */ +/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */ +/* */ +/* Permission is hereby granted, free of charge, to any person obtaining */ +/* a copy of this software and associated documentation files (the */ +/* "Software"), to deal in the Software without restriction, including */ +/* without limitation the rights to use, copy, modify, merge, publish, */ +/* distribute, sublicense, and/or sell copies of the Software, and to */ +/* permit persons to whom the Software is furnished to do so, subject to */ +/* the following conditions: */ +/* */ +/* The above copyright notice and this permission notice shall be */ +/* included in all copies or substantial portions of the Software. */ +/* */ +/* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, */ +/* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF */ +/* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.*/ +/* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY */ +/* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, */ +/* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE */ +/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ +/*************************************************************************/ + +#include "resource_uid.h" +#include "core/crypto/crypto.h" +#include "core/io/dir_access.h" +#include "core/io/file_access.h" + +static constexpr uint32_t char_count = ('z' - 'a'); +static constexpr uint32_t base = char_count + ('9' - '0'); + +const char *ResourceUID::CACHE_FILE = "res://.godot/uid_cache.bin"; + +String ResourceUID::id_to_text(ID p_id) const { + if (p_id < 0) { + return "uid://<invalid>"; + } + String txt; + + while (p_id) { + uint32_t c = p_id % base; + if (c < char_count) { + txt = String::chr('a' + c) + txt; + } else { + txt = String::chr('0' + (c - char_count)) + txt; + } + p_id /= base; + } + + return "uid://" + txt; +} + +ResourceUID::ID ResourceUID::text_to_id(const String &p_text) const { + if (!p_text.begins_with("uid://") || p_text == "uid://<invalid>") { + return INVALID_ID; + } + + uint32_t l = p_text.length(); + uint64_t uid = 0; + for (uint32_t i = 6; i < l; i++) { + uid *= base; + uint32_t c = p_text[i]; + if (c >= 'a' && c <= 'z') { + uid += c - 'a'; + } else if (c >= '0' && c <= '9') { + uid += c - '0' + char_count; + } else { + return INVALID_ID; + } + } + return ID(uid & 0x7FFFFFFFFFFFFFFF); +} + +ResourceUID::ID ResourceUID::create_id() const { + mutex.lock(); + if (crypto.is_null()) { + crypto = Ref<Crypto>(Crypto::create()); + } + mutex.unlock(); + while (true) { + PackedByteArray bytes = crypto->generate_random_bytes(8); + ERR_FAIL_COND_V(bytes.size() != 8, INVALID_ID); + const uint64_t *ptr64 = (const uint64_t *)bytes.ptr(); + ID id = int64_t((*ptr64) & 0x7FFFFFFFFFFFFFFF); + mutex.lock(); + bool exists = unique_ids.has(id); + mutex.unlock(); + if (!exists) { + return id; + } + } +} + +bool ResourceUID::has_id(ID p_id) const { + MutexLock l(mutex); + return unique_ids.has(p_id); +} +void ResourceUID::add_id(ID p_id, const String &p_path) { + MutexLock l(mutex); + ERR_FAIL_COND(unique_ids.has(p_id)); + Cache c; + c.cs = p_path.utf8(); + unique_ids[p_id] = c; + changed = true; +} + +void ResourceUID::set_id(ID p_id, const String &p_path) { + MutexLock l(mutex); + ERR_FAIL_COND(!unique_ids.has(p_id)); + CharString cs = p_path.utf8(); + if (strcmp(cs.ptr(), unique_ids[p_id].cs.ptr()) != 0) { + unique_ids[p_id].cs = cs; + unique_ids[p_id].saved_to_cache = false; //changed + changed = true; + } +} + +String ResourceUID::get_id_path(ID p_id) const { + MutexLock l(mutex); + ERR_FAIL_COND_V(!unique_ids.has(p_id), String()); + const CharString &cs = unique_ids[p_id].cs; + String s(cs.ptr()); + return s; +} +void ResourceUID::remove_id(ID p_id) { + MutexLock l(mutex); + ERR_FAIL_COND(!unique_ids.has(p_id)); + unique_ids.erase(p_id); +} + +Error ResourceUID::save_to_cache() { + if (!FileAccess::exists(CACHE_FILE)) { + DirAccessRef d = DirAccess::create(DirAccess::ACCESS_RESOURCES); + d->make_dir_recursive(String(CACHE_FILE).get_base_dir()); //ensure base dir exists + } + + FileAccessRef f = FileAccess::open(CACHE_FILE, FileAccess::WRITE); + if (!f) { + return ERR_CANT_OPEN; + } + + MutexLock l(mutex); + f->store_32(unique_ids.size()); + + cache_entries = 0; + + for (OrderedHashMap<ID, Cache>::Element E = unique_ids.front(); E; E = E.next()) { + f->store_64(E.key()); + uint32_t s = E.get().cs.length(); + f->store_32(s); + f->store_buffer((const uint8_t *)E.get().cs.ptr(), s); + E.get().saved_to_cache = true; + cache_entries++; + } + + changed = false; + return OK; +} + +Error ResourceUID::load_from_cache() { + FileAccessRef f = FileAccess::open(CACHE_FILE, FileAccess::READ); + if (!f) { + return ERR_CANT_OPEN; + } + + MutexLock l(mutex); + unique_ids.clear(); + + uint32_t entry_count = f->get_32(); + for (uint32_t i = 0; i < entry_count; i++) { + int64_t id = f->get_64(); + int32_t len = f->get_32(); + Cache c; + c.cs.resize(len + 1); + ERR_FAIL_COND_V(c.cs.size() != len + 1, ERR_FILE_CORRUPT); // out of memory + c.cs[len] = 0; + int32_t rl = f->get_buffer((uint8_t *)c.cs.ptrw(), len); + ERR_FAIL_COND_V(rl != len, ERR_FILE_CORRUPT); + + c.saved_to_cache = true; + unique_ids[id] = c; + } + + cache_entries = entry_count; + changed = false; + return OK; +} + +Error ResourceUID::update_cache() { + if (!changed) { + return OK; + } + + if (cache_entries == 0) { + return save_to_cache(); + } + MutexLock l(mutex); + + FileAccess *f = nullptr; + for (OrderedHashMap<ID, Cache>::Element E = unique_ids.front(); E; E = E.next()) { + if (!E.get().saved_to_cache) { + if (f == nullptr) { + f = FileAccess::open(CACHE_FILE, FileAccess::READ_WRITE); //append + if (!f) { + return ERR_CANT_OPEN; + } + f->seek_end(); + } + f->store_64(E.key()); + uint32_t s = E.get().cs.length(); + f->store_32(s); + f->store_buffer((const uint8_t *)E.get().cs.ptr(), s); + E.get().saved_to_cache = true; + cache_entries++; + } + } + + if (f != nullptr) { + f->seek(0); + f->store_32(cache_entries); //update amount of entries + f->close(); + memdelete(f); + } + + changed = false; + + return OK; +} + +void ResourceUID::clear() { + cache_entries = 0; + unique_ids.clear(); + changed = false; +} +void ResourceUID::_bind_methods() { + ClassDB::bind_method(D_METHOD("id_to_text", "id"), &ResourceUID::id_to_text); + ClassDB::bind_method(D_METHOD("text_to_id", "text_id"), &ResourceUID::text_to_id); + + ClassDB::bind_method(D_METHOD("create_id"), &ResourceUID::create_id); + + ClassDB::bind_method(D_METHOD("has_id", "id"), &ResourceUID::has_id); + ClassDB::bind_method(D_METHOD("add_id", "id", "path"), &ResourceUID::add_id); + ClassDB::bind_method(D_METHOD("set_id", "id", "path"), &ResourceUID::set_id); + ClassDB::bind_method(D_METHOD("get_id_path", "id"), &ResourceUID::get_id_path); + ClassDB::bind_method(D_METHOD("remove_id", "id", "path"), &ResourceUID::remove_id); + + BIND_CONSTANT(INVALID_ID) +} +ResourceUID *ResourceUID::singleton = nullptr; +ResourceUID::ResourceUID() { + ERR_FAIL_COND(singleton != nullptr); + singleton = this; +} +ResourceUID::~ResourceUID() { +} diff --git a/core/io/resource_uid.h b/core/io/resource_uid.h new file mode 100644 index 0000000000..b12138425a --- /dev/null +++ b/core/io/resource_uid.h @@ -0,0 +1,89 @@ +/*************************************************************************/ +/* resource_uid.h */ +/*************************************************************************/ +/* This file is part of: */ +/* GODOT ENGINE */ +/* https://godotengine.org */ +/*************************************************************************/ +/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */ +/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */ +/* */ +/* Permission is hereby granted, free of charge, to any person obtaining */ +/* a copy of this software and associated documentation files (the */ +/* "Software"), to deal in the Software without restriction, including */ +/* without limitation the rights to use, copy, modify, merge, publish, */ +/* distribute, sublicense, and/or sell copies of the Software, and to */ +/* permit persons to whom the Software is furnished to do so, subject to */ +/* the following conditions: */ +/* */ +/* The above copyright notice and this permission notice shall be */ +/* included in all copies or substantial portions of the Software. */ +/* */ +/* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, */ +/* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF */ +/* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.*/ +/* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY */ +/* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, */ +/* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE */ +/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ +/*************************************************************************/ + +#ifndef RESOURCE_UUID_H +#define RESOURCE_UUID_H + +#include "core/object/ref_counted.h" +#include "core/string/string_name.h" +#include "core/templates/ordered_hash_map.h" + +class Crypto; +class ResourceUID : public Object { + GDCLASS(ResourceUID, Object) +public: + typedef int64_t ID; + enum { + INVALID_ID = -1 + }; + + static const char *CACHE_FILE; + +private: + mutable Ref<Crypto> crypto; + Mutex mutex; + struct Cache { + CharString cs; + bool saved_to_cache = false; + }; + + OrderedHashMap<ID, Cache> unique_ids; //unique IDs and utf8 paths (less memory used) + static ResourceUID *singleton; + + uint32_t cache_entries = 0; + bool changed = false; + +protected: + static void _bind_methods(); + +public: + String id_to_text(ID p_id) const; + ID text_to_id(const String &p_text) const; + + ID create_id() const; + bool has_id(ID p_id) const; + void add_id(ID p_id, const String &p_path); + void set_id(ID p_id, const String &p_path); + String get_id_path(ID p_id) const; + void remove_id(ID p_id); + + Error load_from_cache(); + Error save_to_cache(); + Error update_cache(); + + void clear(); + + static ResourceUID *get_singleton() { return singleton; } + + ResourceUID(); + ~ResourceUID(); +}; + +#endif // RESOURCEUUID_H diff --git a/core/math/delaunay_3d.h b/core/math/delaunay_3d.h index 6f7209556e..81adf4d19a 100644 --- a/core/math/delaunay_3d.h +++ b/core/math/delaunay_3d.h @@ -375,8 +375,7 @@ public: OutputSimplex *ret_simplicesw = ret_simplices.ptrw(); uint32_t simplices_written = 0; - for (List<Simplex *>::Element *E = simplex_list.front(); E; E = E->next()) { - Simplex *simplex = E->get(); + for (Simplex *simplex : simplex_list) { bool invalid = false; for (int j = 0; j < 4; j++) { if (simplex->points[j] >= point_count) { diff --git a/core/math/dynamic_bvh.cpp b/core/math/dynamic_bvh.cpp index 8e596f0f9d..f3fb473981 100644 --- a/core/math/dynamic_bvh.cpp +++ b/core/math/dynamic_bvh.cpp @@ -181,7 +181,7 @@ DynamicBVH::Volume DynamicBVH::_bounds(Node **leaves, int p_count) { void DynamicBVH::_bottom_up(Node **leaves, int p_count) { while (p_count > 1) { - real_t minsize = Math_INF; + real_t minsize = INFINITY; int minidx[2] = { -1, -1 }; for (int i = 0; i < p_count; ++i) { for (int j = i + 1; j < p_count; ++j) { diff --git a/core/math/expression.cpp b/core/math/expression.cpp index 0146c345f0..05f2c8dac9 100644 --- a/core/math/expression.cpp +++ b/core/math/expression.cpp @@ -397,10 +397,10 @@ Error Expression::_get_token(Token &r_token) { r_token.value = Math_TAU; } else if (id == "INF") { r_token.type = TK_CONSTANT; - r_token.value = Math_INF; + r_token.value = INFINITY; } else if (id == "NAN") { r_token.type = TK_CONSTANT; - r_token.value = Math_NAN; + r_token.value = NAN; } else if (id == "not") { r_token.type = TK_OP_NOT; } else if (id == "or") { diff --git a/core/math/math_defs.h b/core/math/math_defs.h index df2223fb78..7692e1be47 100644 --- a/core/math/math_defs.h +++ b/core/math/math_defs.h @@ -43,8 +43,6 @@ #define Math_TAU 6.2831853071795864769252867666 #define Math_PI 3.1415926535897932384626433833 #define Math_E 2.7182818284590452353602874714 -#define Math_INF INFINITY -#define Math_NAN NAN #ifdef DEBUG_ENABLED #define MATH_CHECKS diff --git a/core/math/quick_hull.cpp b/core/math/quick_hull.cpp index 0d77bfe933..9b506269ea 100644 --- a/core/math/quick_hull.cpp +++ b/core/math/quick_hull.cpp @@ -192,9 +192,9 @@ Error QuickHull::build(const Vector<Vector3> &p_points, Geometry3D::MeshData &r_ continue; } - for (List<Face>::Element *E = faces.front(); E; E = E->next()) { - if (E->get().plane.distance_to(p_points[i]) > over_tolerance) { - E->get().points_over.push_back(i); + for (Face &E : faces) { + if (E.plane.distance_to(p_points[i]) > over_tolerance) { + E.points_over.push_back(i); break; } } @@ -292,8 +292,8 @@ Error QuickHull::build(const Vector<Vector3> &p_points, Geometry3D::MeshData &r_ //distribute points into new faces - for (List<List<Face>::Element *>::Element *F = lit_faces.front(); F; F = F->next()) { - Face &lf = F->get()->get(); + for (List<Face>::Element *&F : lit_faces) { + Face &lf = F->get(); for (int i = 0; i < lf.points_over.size(); i++) { if (lf.points_over[i] == f.points_over[next]) { //do not add current one @@ -301,8 +301,8 @@ Error QuickHull::build(const Vector<Vector3> &p_points, Geometry3D::MeshData &r_ } Vector3 p = p_points[lf.points_over[i]]; - for (List<List<Face>::Element *>::Element *E = new_faces.front(); E; E = E->next()) { - Face &f2 = E->get()->get(); + for (List<Face>::Element *&E : new_faces) { + Face &f2 = E->get(); if (f2.plane.distance_to(p) > over_tolerance) { f2.points_over.push_back(lf.points_over[i]); break; @@ -320,10 +320,10 @@ Error QuickHull::build(const Vector<Vector3> &p_points, Geometry3D::MeshData &r_ //put faces that contain no points on the front - for (List<List<Face>::Element *>::Element *E = new_faces.front(); E; E = E->next()) { - Face &f2 = E->get()->get(); + for (List<Face>::Element *&E : new_faces) { + Face &f2 = E->get(); if (f2.points_over.size() == 0) { - faces.move_to_front(E->get()); + faces.move_to_front(E); } } @@ -336,19 +336,19 @@ Error QuickHull::build(const Vector<Vector3> &p_points, Geometry3D::MeshData &r_ Map<Edge, RetFaceConnect> ret_edges; List<Geometry3D::MeshData::Face> ret_faces; - for (List<Face>::Element *E = faces.front(); E; E = E->next()) { + for (Face &E : faces) { Geometry3D::MeshData::Face f; - f.plane = E->get().plane; + f.plane = E.plane; for (int i = 0; i < 3; i++) { - f.indices.push_back(E->get().vertices[i]); + f.indices.push_back(E.vertices[i]); } List<Geometry3D::MeshData::Face>::Element *F = ret_faces.push_back(f); for (int i = 0; i < 3; i++) { - uint32_t a = E->get().vertices[i]; - uint32_t b = E->get().vertices[(i + 1) % 3]; + uint32_t a = E.vertices[i]; + uint32_t b = E.vertices[(i + 1) % 3]; Edge e(a, b); Map<Edge, RetFaceConnect>::Element *G = ret_edges.find(e); @@ -439,8 +439,8 @@ Error QuickHull::build(const Vector<Vector3> &p_points, Geometry3D::MeshData &r_ r_mesh.faces.resize(ret_faces.size()); int idx = 0; - for (List<Geometry3D::MeshData::Face>::Element *E = ret_faces.front(); E; E = E->next()) { - r_mesh.faces.write[idx++] = E->get(); + for (Geometry3D::MeshData::Face &E : ret_faces) { + r_mesh.faces.write[idx++] = E; } r_mesh.edges.resize(ret_edges.size()); idx = 0; diff --git a/core/math/triangle_mesh.cpp b/core/math/triangle_mesh.cpp index 903d5951a8..bf06c848c5 100644 --- a/core/math/triangle_mesh.cpp +++ b/core/math/triangle_mesh.cpp @@ -32,9 +32,9 @@ #include "core/templates/sort_array.h" -int TriangleMesh::_create_bvh(BVH *p_bvh, BVH **p_bb, int p_from, int p_size, int p_depth, int &max_depth, int &max_alloc) { - if (p_depth > max_depth) { - max_depth = p_depth; +int TriangleMesh::_create_bvh(BVH *p_bvh, BVH **p_bb, int p_from, int p_size, int p_depth, int &r_max_depth, int &r_max_alloc) { + if (p_depth > r_max_depth) { + r_max_depth = p_depth; } if (p_size == 1) { @@ -70,10 +70,10 @@ int TriangleMesh::_create_bvh(BVH *p_bvh, BVH **p_bb, int p_from, int p_size, in } break; } - int left = _create_bvh(p_bvh, p_bb, p_from, p_size / 2, p_depth + 1, max_depth, max_alloc); - int right = _create_bvh(p_bvh, p_bb, p_from + p_size / 2, p_size - p_size / 2, p_depth + 1, max_depth, max_alloc); + int left = _create_bvh(p_bvh, p_bb, p_from, p_size / 2, p_depth + 1, r_max_depth, r_max_alloc); + int right = _create_bvh(p_bvh, p_bb, p_from + p_size / 2, p_size - p_size / 2, p_depth + 1, r_max_depth, r_max_alloc); - int index = max_alloc++; + int index = r_max_alloc++; BVH *_new = &p_bvh[index]; _new->aabb = aabb; _new->center = aabb.position + aabb.size * 0.5; diff --git a/core/math/vector2.h b/core/math/vector2.h index 78deb473b4..4d9f3126e9 100644 --- a/core/math/vector2.h +++ b/core/math/vector2.h @@ -300,6 +300,14 @@ struct Vector2i { return p_idx ? y : x; } + _FORCE_INLINE_ int min_axis() const { + return x < y ? 0 : 1; + } + + _FORCE_INLINE_ int max_axis() const { + return x < y ? 1 : 0; + } + Vector2i min(const Vector2i &p_vector2i) const { return Vector2(MIN(x, p_vector2i.x), MIN(y, p_vector2i.y)); } diff --git a/core/object/class_db.cpp b/core/object/class_db.cpp index a10405dfae..57495a4fbd 100644 --- a/core/object/class_db.cpp +++ b/core/object/class_db.cpp @@ -359,9 +359,9 @@ uint64_t ClassDB::get_api_hash(APIType p_api) { //must be alphabetically sorted for hash to compute names.sort_custom<StringName::AlphCompare>(); - for (List<StringName>::Element *E = names.front(); E; E = E->next()) { - ClassInfo *t = classes.getptr(E->get()); - ERR_FAIL_COND_V_MSG(!t, 0, "Cannot get class '" + String(E->get()) + "'."); + for (StringName &E : names) { + ClassInfo *t = classes.getptr(E); + ERR_FAIL_COND_V_MSG(!t, 0, "Cannot get class '" + String(E) + "'."); if (t->api != p_api || !t->exposed) { continue; } @@ -388,8 +388,8 @@ uint64_t ClassDB::get_api_hash(APIType p_api) { snames.sort_custom<StringName::AlphCompare>(); - for (List<StringName>::Element *F = snames.front(); F; F = F->next()) { - MethodBind *mb = t->method_map[F->get()]; + for (StringName &F : snames) { + MethodBind *mb = t->method_map[F]; hash = hash_djb2_one_64(mb->get_name().hash(), hash); hash = hash_djb2_one_64(mb->get_argument_count(), hash); hash = hash_djb2_one_64(mb->get_argument_type(-1), hash); //return @@ -426,9 +426,9 @@ uint64_t ClassDB::get_api_hash(APIType p_api) { snames.sort_custom<StringName::AlphCompare>(); - for (List<StringName>::Element *F = snames.front(); F; F = F->next()) { - hash = hash_djb2_one_64(F->get().hash(), hash); - hash = hash_djb2_one_64(t->constant_map[F->get()], hash); + for (StringName &F : snames) { + hash = hash_djb2_one_64(F.hash(), hash); + hash = hash_djb2_one_64(t->constant_map[F], hash); } } @@ -444,9 +444,9 @@ uint64_t ClassDB::get_api_hash(APIType p_api) { snames.sort_custom<StringName::AlphCompare>(); - for (List<StringName>::Element *F = snames.front(); F; F = F->next()) { - MethodInfo &mi = t->signal_map[F->get()]; - hash = hash_djb2_one_64(F->get().hash(), hash); + for (StringName &F : snames) { + MethodInfo &mi = t->signal_map[F]; + hash = hash_djb2_one_64(F.hash(), hash); for (int i = 0; i < mi.arguments.size(); i++) { hash = hash_djb2_one_64(mi.arguments[i].type, hash); } @@ -465,23 +465,23 @@ uint64_t ClassDB::get_api_hash(APIType p_api) { snames.sort_custom<StringName::AlphCompare>(); - for (List<StringName>::Element *F = snames.front(); F; F = F->next()) { - PropertySetGet *psg = t->property_setget.getptr(F->get()); + for (StringName &F : snames) { + PropertySetGet *psg = t->property_setget.getptr(F); ERR_FAIL_COND_V(!psg, 0); - hash = hash_djb2_one_64(F->get().hash(), hash); + hash = hash_djb2_one_64(F.hash(), hash); hash = hash_djb2_one_64(psg->setter.hash(), hash); hash = hash_djb2_one_64(psg->getter.hash(), hash); } } //property list - for (List<PropertyInfo>::Element *F = t->property_list.front(); F; F = F->next()) { - hash = hash_djb2_one_64(F->get().name.hash(), hash); - hash = hash_djb2_one_64(F->get().type, hash); - hash = hash_djb2_one_64(F->get().hint, hash); - hash = hash_djb2_one_64(F->get().hint_string.hash(), hash); - hash = hash_djb2_one_64(F->get().usage, hash); + for (PropertyInfo &F : t->property_list) { + hash = hash_djb2_one_64(F.name.hash(), hash); + hash = hash_djb2_one_64(F.type, hash); + hash = hash_djb2_one_64(F.hint, hash); + hash = hash_djb2_one_64(F.hint_string.hash(), hash); + hash = hash_djb2_one_64(F.usage, hash); } } @@ -602,7 +602,7 @@ static MethodInfo info_from_bind(MethodBind *p_method) { } #endif -void ClassDB::get_method_list(StringName p_class, List<MethodInfo> *p_methods, bool p_no_inheritance, bool p_exclude_from_properties) { +void ClassDB::get_method_list(const StringName &p_class, List<MethodInfo> *p_methods, bool p_no_inheritance, bool p_exclude_from_properties) { OBJTYPE_RLOCK; ClassInfo *type = classes.getptr(p_class); @@ -619,16 +619,16 @@ void ClassDB::get_method_list(StringName p_class, List<MethodInfo> *p_methods, b #ifdef DEBUG_METHODS_ENABLED - for (List<MethodInfo>::Element *E = type->virtual_methods.front(); E; E = E->next()) { - p_methods->push_back(E->get()); + for (MethodInfo &E : type->virtual_methods) { + p_methods->push_back(E); } - for (List<StringName>::Element *E = type->method_order.front(); E; E = E->next()) { - if (p_exclude_from_properties && type->methods_in_properties.has(E->get())) { + for (StringName &E : type->method_order) { + if (p_exclude_from_properties && type->methods_in_properties.has(E)) { continue; } - MethodBind *method = type->method_map.get(E->get()); + MethodBind *method = type->method_map.get(E); MethodInfo minfo = info_from_bind(method); p_methods->push_back(minfo); @@ -655,7 +655,7 @@ void ClassDB::get_method_list(StringName p_class, List<MethodInfo> *p_methods, b } } -bool ClassDB::get_method_info(StringName p_class, StringName p_method, MethodInfo *r_info, bool p_no_inheritance, bool p_exclude_from_properties) { +bool ClassDB::get_method_info(const StringName &p_class, const StringName &p_method, MethodInfo *r_info, bool p_no_inheritance, bool p_exclude_from_properties) { OBJTYPE_RLOCK; ClassInfo *type = classes.getptr(p_class); @@ -706,7 +706,7 @@ bool ClassDB::get_method_info(StringName p_class, StringName p_method, MethodInf return false; } -MethodBind *ClassDB::get_method(StringName p_class, StringName p_name) { +MethodBind *ClassDB::get_method(const StringName &p_class, const StringName &p_name) { OBJTYPE_RLOCK; ClassInfo *type = classes.getptr(p_class); @@ -763,8 +763,8 @@ void ClassDB::get_integer_constant_list(const StringName &p_class, List<String> while (type) { #ifdef DEBUG_METHODS_ENABLED - for (List<StringName>::Element *E = type->constant_order.front(); E; E = E->next()) { - p_constants->push_back(E->get()); + for (StringName &E : type->constant_order) { + p_constants->push_back(E); } #else const StringName *K = nullptr; @@ -910,7 +910,7 @@ bool ClassDB::has_enum(const StringName &p_class, const StringName &p_name, bool return false; } -void ClassDB::add_signal(StringName p_class, const MethodInfo &p_signal) { +void ClassDB::add_signal(const StringName &p_class, const MethodInfo &p_signal) { OBJTYPE_WLOCK; ClassInfo *type = classes.getptr(p_class); @@ -929,7 +929,7 @@ void ClassDB::add_signal(StringName p_class, const MethodInfo &p_signal) { type->signal_map[sname] = p_signal; } -void ClassDB::get_signal_list(StringName p_class, List<MethodInfo> *p_signals, bool p_no_inheritance) { +void ClassDB::get_signal_list(const StringName &p_class, List<MethodInfo> *p_signals, bool p_no_inheritance) { OBJTYPE_RLOCK; ClassInfo *type = classes.getptr(p_class); @@ -951,7 +951,7 @@ void ClassDB::get_signal_list(StringName p_class, List<MethodInfo> *p_signals, b } } -bool ClassDB::has_signal(StringName p_class, StringName p_signal, bool p_no_inheritance) { +bool ClassDB::has_signal(const StringName &p_class, const StringName &p_signal, bool p_no_inheritance) { OBJTYPE_RLOCK; ClassInfo *type = classes.getptr(p_class); ClassInfo *check = type; @@ -968,7 +968,7 @@ bool ClassDB::has_signal(StringName p_class, StringName p_signal, bool p_no_inhe return false; } -bool ClassDB::get_signal(StringName p_class, StringName p_signal, MethodInfo *r_signal) { +bool ClassDB::get_signal(const StringName &p_class, const StringName &p_signal, MethodInfo *r_signal) { OBJTYPE_RLOCK; ClassInfo *type = classes.getptr(p_class); ClassInfo *check = type; @@ -985,7 +985,7 @@ bool ClassDB::get_signal(StringName p_class, StringName p_signal, MethodInfo *r_ return false; } -void ClassDB::add_property_group(StringName p_class, const String &p_name, const String &p_prefix) { +void ClassDB::add_property_group(const StringName &p_class, const String &p_name, const String &p_prefix) { OBJTYPE_WLOCK; ClassInfo *type = classes.getptr(p_class); ERR_FAIL_COND(!type); @@ -993,7 +993,7 @@ void ClassDB::add_property_group(StringName p_class, const String &p_name, const type->property_list.push_back(PropertyInfo(Variant::NIL, p_name, PROPERTY_HINT_NONE, p_prefix, PROPERTY_USAGE_GROUP)); } -void ClassDB::add_property_subgroup(StringName p_class, const String &p_name, const String &p_prefix) { +void ClassDB::add_property_subgroup(const StringName &p_class, const String &p_name, const String &p_prefix) { OBJTYPE_WLOCK; ClassInfo *type = classes.getptr(p_class); ERR_FAIL_COND(!type); @@ -1002,7 +1002,7 @@ void ClassDB::add_property_subgroup(StringName p_class, const String &p_name, co } // NOTE: For implementation simplicity reasons, this method doesn't allow setters to have optional arguments at the end. -void ClassDB::add_property(StringName p_class, const PropertyInfo &p_pinfo, const StringName &p_setter, const StringName &p_getter, int p_index) { +void ClassDB::add_property(const StringName &p_class, const PropertyInfo &p_pinfo, const StringName &p_setter, const StringName &p_getter, int p_index) { lock.read_lock(); ClassInfo *type = classes.getptr(p_class); lock.read_unlock(); @@ -1060,26 +1060,25 @@ void ClassDB::add_property(StringName p_class, const PropertyInfo &p_pinfo, cons type->property_setget[p_pinfo.name] = psg; } -void ClassDB::set_property_default_value(StringName p_class, const StringName &p_name, const Variant &p_default) { +void ClassDB::set_property_default_value(const StringName &p_class, const StringName &p_name, const Variant &p_default) { if (!default_values.has(p_class)) { default_values[p_class] = HashMap<StringName, Variant>(); } default_values[p_class][p_name] = p_default; } -void ClassDB::get_property_list(StringName p_class, List<PropertyInfo> *p_list, bool p_no_inheritance, const Object *p_validator) { +void ClassDB::get_property_list(const StringName &p_class, List<PropertyInfo> *p_list, bool p_no_inheritance, const Object *p_validator) { OBJTYPE_RLOCK; ClassInfo *type = classes.getptr(p_class); ClassInfo *check = type; while (check) { - for (List<PropertyInfo>::Element *E = check->property_list.front(); E; E = E->next()) { + for (PropertyInfo pi : check->property_list) { if (p_validator) { - PropertyInfo pi = E->get(); p_validator->_validate_property(pi); p_list->push_back(pi); } else { - p_list->push_back(E->get()); + p_list->push_back(pi); } } @@ -1090,7 +1089,7 @@ void ClassDB::get_property_list(StringName p_class, List<PropertyInfo> *p_list, } } -bool ClassDB::get_property_info(StringName p_class, StringName p_property, PropertyInfo *r_info, bool p_no_inheritance, const Object *p_validator) { +bool ClassDB::get_property_info(const StringName &p_class, const StringName &p_property, PropertyInfo *r_info, bool p_no_inheritance, const Object *p_validator) { OBJTYPE_RLOCK; ClassInfo *check = classes.getptr(p_class); @@ -1258,7 +1257,7 @@ Variant::Type ClassDB::get_property_type(const StringName &p_class, const String return Variant::NIL; } -StringName ClassDB::get_property_setter(StringName p_class, const StringName &p_property) { +StringName ClassDB::get_property_setter(const StringName &p_class, const StringName &p_property) { ClassInfo *type = classes.getptr(p_class); ClassInfo *check = type; while (check) { @@ -1273,7 +1272,7 @@ StringName ClassDB::get_property_setter(StringName p_class, const StringName &p_ return StringName(); } -StringName ClassDB::get_property_getter(StringName p_class, const StringName &p_property) { +StringName ClassDB::get_property_getter(const StringName &p_class, const StringName &p_property) { ClassInfo *type = classes.getptr(p_class); ClassInfo *check = type; while (check) { @@ -1305,7 +1304,7 @@ bool ClassDB::has_property(const StringName &p_class, const StringName &p_proper return false; } -void ClassDB::set_method_flags(StringName p_class, StringName p_method, int p_flags) { +void ClassDB::set_method_flags(const StringName &p_class, const StringName &p_method, int p_flags) { OBJTYPE_WLOCK; ClassInfo *type = classes.getptr(p_class); ClassInfo *check = type; @@ -1314,7 +1313,7 @@ void ClassDB::set_method_flags(StringName p_class, StringName p_method, int p_fl check->method_map[p_method]->set_hint_flags(p_flags); } -bool ClassDB::has_method(StringName p_class, StringName p_method, bool p_no_inheritance) { +bool ClassDB::has_method(const StringName &p_class, const StringName &p_method, bool p_no_inheritance) { ClassInfo *type = classes.getptr(p_class); ClassInfo *check = type; while (check) { @@ -1429,8 +1428,8 @@ void ClassDB::get_virtual_methods(const StringName &p_class, List<MethodInfo> *p ClassInfo *type = classes.getptr(p_class); ClassInfo *check = type; while (check) { - for (List<MethodInfo>::Element *E = check->virtual_methods.front(); E; E = E->next()) { - p_methods->push_back(E->get()); + for (MethodInfo &E : check->virtual_methods) { + p_methods->push_back(E); } if (p_no_inheritance) { @@ -1442,14 +1441,14 @@ void ClassDB::get_virtual_methods(const StringName &p_class, List<MethodInfo> *p #endif } -void ClassDB::set_class_enabled(StringName p_class, bool p_enable) { +void ClassDB::set_class_enabled(const StringName &p_class, bool p_enable) { OBJTYPE_WLOCK; ERR_FAIL_COND_MSG(!classes.has(p_class), "Request for nonexistent class '" + p_class + "'."); classes[p_class].disabled = !p_enable; } -bool ClassDB::is_class_enabled(StringName p_class) { +bool ClassDB::is_class_enabled(const StringName &p_class) { OBJTYPE_RLOCK; ClassInfo *ti = classes.getptr(p_class); @@ -1463,7 +1462,7 @@ bool ClassDB::is_class_enabled(StringName p_class) { return !ti->disabled; } -bool ClassDB::is_class_exposed(StringName p_class) { +bool ClassDB::is_class_exposed(const StringName &p_class) { OBJTYPE_RLOCK; ClassInfo *ti = classes.getptr(p_class); @@ -1496,6 +1495,10 @@ void ClassDB::get_resource_base_extensions(List<String> *p_extensions) { } } +bool ClassDB::is_resource_extension(const StringName &p_extension) { + return resource_base_extensions.has(p_extension); +} + void ClassDB::get_extensions_for_type(const StringName &p_class, List<String> *p_extensions) { const StringName *K = nullptr; @@ -1530,11 +1533,11 @@ Variant ClassDB::class_get_default_property_value(const StringName &p_class, con if (c) { List<PropertyInfo> plist; c->get_property_list(&plist); - for (List<PropertyInfo>::Element *E = plist.front(); E; E = E->next()) { - if (E->get().usage & (PROPERTY_USAGE_STORAGE | PROPERTY_USAGE_EDITOR)) { - if (!default_values[p_class].has(E->get().name)) { - Variant v = c->get(E->get().name); - default_values[p_class][E->get().name] = v; + for (PropertyInfo &E : plist) { + if (E.usage & (PROPERTY_USAGE_STORAGE | PROPERTY_USAGE_EDITOR)) { + if (!default_values[p_class].has(E.name)) { + Variant v = c->get(E.name); + default_values[p_class][E.name] = v; } } } diff --git a/core/object/class_db.h b/core/object/class_db.h index e0cba1b8b5..3a84e9ab38 100644 --- a/core/object/class_db.h +++ b/core/object/class_db.h @@ -311,7 +311,7 @@ public: } template <class M> - static MethodBind *bind_vararg_method(uint32_t p_flags, StringName p_name, M p_method, const MethodInfo &p_info = MethodInfo(), const Vector<Variant> &p_default_args = Vector<Variant>(), bool p_return_nil_is_variant = true) { + static MethodBind *bind_vararg_method(uint32_t p_flags, const StringName &p_name, M p_method, const MethodInfo &p_info = MethodInfo(), const Vector<Variant> &p_default_args = Vector<Variant>(), bool p_return_nil_is_variant = true) { GLOBAL_LOCK_FUNCTION; MethodBind *bind = create_vararg_method_bind(p_method, p_info, p_return_nil_is_variant); @@ -345,31 +345,31 @@ public: static void bind_method_custom(const StringName &p_class, MethodBind *p_method); - static void add_signal(StringName p_class, const MethodInfo &p_signal); - static bool has_signal(StringName p_class, StringName p_signal, bool p_no_inheritance = false); - static bool get_signal(StringName p_class, StringName p_signal, MethodInfo *r_signal); - static void get_signal_list(StringName p_class, List<MethodInfo> *p_signals, bool p_no_inheritance = false); - - static void add_property_group(StringName p_class, const String &p_name, const String &p_prefix = ""); - static void add_property_subgroup(StringName p_class, const String &p_name, const String &p_prefix = ""); - static void add_property(StringName p_class, const PropertyInfo &p_pinfo, const StringName &p_setter, const StringName &p_getter, int p_index = -1); - static void set_property_default_value(StringName p_class, const StringName &p_name, const Variant &p_default); - static void get_property_list(StringName p_class, List<PropertyInfo> *p_list, bool p_no_inheritance = false, const Object *p_validator = nullptr); - static bool get_property_info(StringName p_class, StringName p_property, PropertyInfo *r_info, bool p_no_inheritance = false, const Object *p_validator = nullptr); + static void add_signal(const StringName &p_class, const MethodInfo &p_signal); + static bool has_signal(const StringName &p_class, const StringName &p_signal, bool p_no_inheritance = false); + static bool get_signal(const StringName &p_class, const StringName &p_signal, MethodInfo *r_signal); + static void get_signal_list(const StringName &p_class, List<MethodInfo> *p_signals, bool p_no_inheritance = false); + + static void add_property_group(const StringName &p_class, const String &p_name, const String &p_prefix = ""); + static void add_property_subgroup(const StringName &p_class, const String &p_name, const String &p_prefix = ""); + static void add_property(const StringName &p_class, const PropertyInfo &p_pinfo, const StringName &p_setter, const StringName &p_getter, int p_index = -1); + static void set_property_default_value(const StringName &p_class, const StringName &p_name, const Variant &p_default); + static void get_property_list(const StringName &p_class, List<PropertyInfo> *p_list, bool p_no_inheritance = false, const Object *p_validator = nullptr); + static bool get_property_info(const StringName &p_class, const StringName &p_property, PropertyInfo *r_info, bool p_no_inheritance = false, const Object *p_validator = nullptr); static bool set_property(Object *p_object, const StringName &p_property, const Variant &p_value, bool *r_valid = nullptr); static bool get_property(Object *p_object, const StringName &p_property, Variant &r_value); static bool has_property(const StringName &p_class, const StringName &p_property, bool p_no_inheritance = false); static int get_property_index(const StringName &p_class, const StringName &p_property, bool *r_is_valid = nullptr); static Variant::Type get_property_type(const StringName &p_class, const StringName &p_property, bool *r_is_valid = nullptr); - static StringName get_property_setter(StringName p_class, const StringName &p_property); - static StringName get_property_getter(StringName p_class, const StringName &p_property); + static StringName get_property_setter(const StringName &p_class, const StringName &p_property); + static StringName get_property_getter(const StringName &p_class, const StringName &p_property); - static bool has_method(StringName p_class, StringName p_method, bool p_no_inheritance = false); - static void set_method_flags(StringName p_class, StringName p_method, int p_flags); + static bool has_method(const StringName &p_class, const StringName &p_method, bool p_no_inheritance = false); + static void set_method_flags(const StringName &p_class, const StringName &p_method, int p_flags); - static void get_method_list(StringName p_class, List<MethodInfo> *p_methods, bool p_no_inheritance = false, bool p_exclude_from_properties = false); - static bool get_method_info(StringName p_class, StringName p_method, MethodInfo *r_info, bool p_no_inheritance = false, bool p_exclude_from_properties = false); - static MethodBind *get_method(StringName p_class, StringName p_name); + static void get_method_list(const StringName &p_class, List<MethodInfo> *p_methods, bool p_no_inheritance = false, bool p_exclude_from_properties = false); + static bool get_method_info(const StringName &p_class, const StringName &p_method, MethodInfo *r_info, bool p_no_inheritance = false, bool p_exclude_from_properties = false); + static MethodBind *get_method(const StringName &p_class, const StringName &p_name); static void add_virtual_method(const StringName &p_class, const MethodInfo &p_method, bool p_virtual = true); static void get_virtual_methods(const StringName &p_class, List<MethodInfo> *p_methods, bool p_no_inheritance = false); @@ -388,14 +388,15 @@ public: static StringName get_category(const StringName &p_node); - static void set_class_enabled(StringName p_class, bool p_enable); - static bool is_class_enabled(StringName p_class); + static void set_class_enabled(const StringName &p_class, bool p_enable); + static bool is_class_enabled(const StringName &p_class); - static bool is_class_exposed(StringName p_class); + static bool is_class_exposed(const StringName &p_class); static void add_resource_base_extension(const StringName &p_extension, const StringName &p_class); static void get_resource_base_extensions(List<String> *p_extensions); static void get_extensions_for_type(const StringName &p_class, List<String> *p_extensions); + static bool is_resource_extension(const StringName &p_extension); static void add_compatibility_class(const StringName &p_class, const StringName &p_fallback); diff --git a/core/object/object.cpp b/core/object/object.cpp index 0644012318..0e397d8518 100644 --- a/core/object/object.cpp +++ b/core/object/object.cpp @@ -922,11 +922,11 @@ Variant Object::get_script() const { return script; } -bool Object::has_meta(const String &p_name) const { +bool Object::has_meta(const StringName &p_name) const { return metadata.has(p_name); } -void Object::set_meta(const String &p_name, const Variant &p_value) { +void Object::set_meta(const StringName &p_name, const Variant &p_value) { if (p_value.get_type() == Variant::NIL) { metadata.erase(p_name); return; @@ -935,12 +935,12 @@ void Object::set_meta(const String &p_name, const Variant &p_value) { metadata[p_name] = p_value; } -Variant Object::get_meta(const String &p_name) const { +Variant Object::get_meta(const StringName &p_name) const { ERR_FAIL_COND_V_MSG(!metadata.has(p_name), Variant(), "The object does not have any 'meta' values with the key '" + p_name + "'."); return metadata[p_name]; } -void Object::remove_meta(const String &p_name) { +void Object::remove_meta(const StringName &p_name) { metadata.erase(p_name); } @@ -964,23 +964,23 @@ Array Object::_get_method_list_bind() const { return ret; } -Vector<String> Object::_get_meta_list_bind() const { - Vector<String> _metaret; +Vector<StringName> Object::_get_meta_list_bind() const { + Vector<StringName> _metaret; List<Variant> keys; metadata.get_key_list(&keys); - for (List<Variant>::Element *E = keys.front(); E; E = E->next()) { - _metaret.push_back(E->get()); + for (Variant &E : keys) { + _metaret.push_back(E); } return _metaret; } -void Object::get_meta_list(List<String> *p_list) const { +void Object::get_meta_list(List<StringName> *p_list) const { List<Variant> keys; metadata.get_key_list(&keys); - for (List<Variant>::Element *E = keys.front(); E; E = E->next()) { - p_list->push_back(E->get()); + for (Variant &E : keys) { + p_list->push_back(E); } } @@ -1184,8 +1184,8 @@ Array Object::_get_signal_list() const { get_signal_list(&signal_list); Array ret; - for (List<MethodInfo>::Element *E = signal_list.front(); E; E = E->next()) { - ret.push_back(Dictionary(E->get())); + for (MethodInfo &E : signal_list) { + ret.push_back(Dictionary(E)); } return ret; @@ -1197,8 +1197,7 @@ Array Object::_get_signal_connection_list(const String &p_signal) const { Array ret; - for (List<Connection>::Element *E = conns.front(); E; E = E->next()) { - Connection &c = E->get(); + for (Connection &c : conns) { if (c.signal.get_name() == p_signal) { ret.push_back(c); } @@ -1297,8 +1296,8 @@ int Object::get_persistent_signal_connection_count() const { } void Object::get_signals_connected_to_this(List<Connection> *p_connections) const { - for (const List<Connection>::Element *E = connections.front(); E; E = E->next()) { - p_connections->push_back(E->get()); + for (const Connection &E : connections) { + p_connections->push_back(E); } } @@ -1500,9 +1499,9 @@ void Object::_clear_internal_resource_paths(const Variant &p_var) { List<Variant> keys; d.get_key_list(&keys); - for (List<Variant>::Element *E = keys.front(); E; E = E->next()) { - _clear_internal_resource_paths(E->get()); - _clear_internal_resource_paths(d[E->get()]); + for (Variant &E : keys) { + _clear_internal_resource_paths(E); + _clear_internal_resource_paths(d[E]); } } break; default: { @@ -1531,8 +1530,8 @@ void Object::clear_internal_resource_paths() { get_property_list(&pinfo); - for (List<PropertyInfo>::Element *E = pinfo.front(); E; E = E->next()) { - _clear_internal_resource_paths(get(E->get().name)); + for (PropertyInfo &E : pinfo) { + _clear_internal_resource_paths(get(E.name)); } } @@ -1666,12 +1665,12 @@ void Object::get_translatable_strings(List<String> *p_strings) const { List<PropertyInfo> plist; get_property_list(&plist); - for (List<PropertyInfo>::Element *E = plist.front(); E; E = E->next()) { - if (!(E->get().usage & PROPERTY_USAGE_INTERNATIONALIZED)) { + for (PropertyInfo &E : plist) { + if (!(E.usage & PROPERTY_USAGE_INTERNATIONALIZED)) { continue; } - String text = get(E->get().name); + String text = get(E.name); if (text == "") { continue; diff --git a/core/object/object.h b/core/object/object.h index 89385b81a3..b7d0916a54 100644 --- a/core/object/object.h +++ b/core/object/object.h @@ -44,13 +44,13 @@ #include "core/variant/callable_bind.h" #include "core/variant/variant.h" -#define VARIANT_ARG_LIST const Variant &p_arg1 = Variant(), const Variant &p_arg2 = Variant(), const Variant &p_arg3 = Variant(), const Variant &p_arg4 = Variant(), const Variant &p_arg5 = Variant() -#define VARIANT_ARG_PASS p_arg1, p_arg2, p_arg3, p_arg4, p_arg5 -#define VARIANT_ARG_DECLARE const Variant &p_arg1, const Variant &p_arg2, const Variant &p_arg3, const Variant &p_arg4, const Variant &p_arg5 -#define VARIANT_ARG_MAX 5 -#define VARIANT_ARGPTRS const Variant *argptr[5] = { &p_arg1, &p_arg2, &p_arg3, &p_arg4, &p_arg5 }; -#define VARIANT_ARGPTRS_PASS *argptr[0], *argptr[1], *argptr[2], *argptr[3], *argptr[4] -#define VARIANT_ARGS_FROM_ARRAY(m_arr) m_arr[0], m_arr[1], m_arr[2], m_arr[3], m_arr[4] +#define VARIANT_ARG_LIST const Variant &p_arg1 = Variant(), const Variant &p_arg2 = Variant(), const Variant &p_arg3 = Variant(), const Variant &p_arg4 = Variant(), const Variant &p_arg5 = Variant(), const Variant &p_arg6 = Variant(), const Variant &p_arg7 = Variant(), const Variant &p_arg8 = Variant() +#define VARIANT_ARG_PASS p_arg1, p_arg2, p_arg3, p_arg4, p_arg5, p_arg6, p_arg7, p_arg8 +#define VARIANT_ARG_DECLARE const Variant &p_arg1, const Variant &p_arg2, const Variant &p_arg3, const Variant &p_arg4, const Variant &p_arg5, const Variant &p_arg6, const Variant &p_arg7, const Variant &p_arg8 +#define VARIANT_ARG_MAX 8 +#define VARIANT_ARGPTRS const Variant *argptr[8] = { &p_arg1, &p_arg2, &p_arg3, &p_arg4, &p_arg5, &p_arg6, &p_arg7, &p_arg8 }; +#define VARIANT_ARGPTRS_PASS *argptr[0], *argptr[1], *argptr[2], *argptr[3], *argptr[4], *argptr[5], *argptr[6]], *argptr[7] +#define VARIANT_ARGS_FROM_ARRAY(m_arr) m_arr[0], m_arr[1], m_arr[2], m_arr[3], m_arr[4], m_arr[5], m_arr[6], m_arr[7] /** @author Juan Linietsky <reduzio@gmail.com> @@ -615,7 +615,7 @@ protected: return &_class_name; } - Vector<String> _get_meta_list_bind() const; + Vector<StringName> _get_meta_list_bind() const; Array _get_property_list_bind() const; Array _get_method_list_bind() const; @@ -743,11 +743,11 @@ public: /* SCRIPT */ - bool has_meta(const String &p_name) const; - void set_meta(const String &p_name, const Variant &p_value); - void remove_meta(const String &p_name); - Variant get_meta(const String &p_name) const; - void get_meta_list(List<String> *p_list) const; + bool has_meta(const StringName &p_name) const; + void set_meta(const StringName &p_name, const Variant &p_value); + void remove_meta(const StringName &p_name); + Variant get_meta(const StringName &p_name) const; + void get_meta_list(List<StringName> *p_list) const; #ifdef TOOLS_ENABLED void set_edited(bool p_edited); diff --git a/core/object/script_language.cpp b/core/object/script_language.cpp index 626a7413e7..5aa032192e 100644 --- a/core/object/script_language.cpp +++ b/core/object/script_language.cpp @@ -63,8 +63,8 @@ Array Script::_get_script_property_list() { Array ret; List<PropertyInfo> list; get_script_property_list(&list); - for (List<PropertyInfo>::Element *E = list.front(); E; E = E->next()) { - ret.append(E->get().operator Dictionary()); + for (PropertyInfo &E : list) { + ret.append(E.operator Dictionary()); } return ret; } @@ -73,8 +73,8 @@ Array Script::_get_script_method_list() { Array ret; List<MethodInfo> list; get_script_method_list(&list); - for (List<MethodInfo>::Element *E = list.front(); E; E = E->next()) { - ret.append(E->get().operator Dictionary()); + for (MethodInfo &E : list) { + ret.append(E.operator Dictionary()); } return ret; } @@ -83,8 +83,8 @@ Array Script::_get_script_signal_list() { Array ret; List<MethodInfo> list; get_script_signal_list(&list); - for (List<MethodInfo>::Element *E = list.front(); E; E = E->next()) { - ret.append(E->get().operator Dictionary()); + for (MethodInfo &E : list) { + ret.append(E.operator Dictionary()); } return ret; } @@ -257,8 +257,8 @@ void ScriptServer::get_global_class_list(List<StringName> *r_global_classes) { classes.push_back(*K); } classes.sort_custom<StringName::AlphCompare>(); - for (List<StringName>::Element *E = classes.front(); E; E = E->next()) { - r_global_classes->push_back(E->get()); + for (StringName &E : classes) { + r_global_classes->push_back(E); } } @@ -266,12 +266,12 @@ void ScriptServer::save_global_classes() { List<StringName> gc; get_global_class_list(&gc); Array gcarr; - for (List<StringName>::Element *E = gc.front(); E; E = E->next()) { + for (StringName &E : gc) { Dictionary d; - d["class"] = E->get(); - d["language"] = global_classes[E->get()].language; - d["path"] = global_classes[E->get()].path; - d["base"] = global_classes[E->get()].base; + d["class"] = E; + d["language"] = global_classes[E].language; + d["path"] = global_classes[E].path; + d["base"] = global_classes[E].base; gcarr.push_back(d); } @@ -297,10 +297,10 @@ void ScriptServer::save_global_classes() { void ScriptInstance::get_property_state(List<Pair<StringName, Variant>> &state) { List<PropertyInfo> pinfo; get_property_list(&pinfo); - for (List<PropertyInfo>::Element *E = pinfo.front(); E; E = E->next()) { - if (E->get().usage & PROPERTY_USAGE_STORAGE) { + for (PropertyInfo &E : pinfo) { + if (E.usage & PROPERTY_USAGE_STORAGE) { Pair<StringName, Variant> p; - p.first = E->get().name; + p.first = E.name; if (get(p.first, p.second)) { state.push_back(p); } @@ -430,16 +430,16 @@ bool PlaceHolderScriptInstance::get(const StringName &p_name, Variant &r_ret) co void PlaceHolderScriptInstance::get_property_list(List<PropertyInfo> *p_properties) const { if (script->is_placeholder_fallback_enabled()) { - for (const List<PropertyInfo>::Element *E = properties.front(); E; E = E->next()) { - p_properties->push_back(E->get()); + for (const PropertyInfo &E : properties) { + p_properties->push_back(E); } } else { - for (const List<PropertyInfo>::Element *E = properties.front(); E; E = E->next()) { - PropertyInfo pinfo = E->get(); + for (const PropertyInfo &E : properties) { + PropertyInfo pinfo = E; if (!values.has(pinfo.name)) { pinfo.usage |= PROPERTY_USAGE_SCRIPT_DEFAULT_VALUE; } - p_properties->push_back(E->get()); + p_properties->push_back(E); } } } @@ -489,11 +489,11 @@ bool PlaceHolderScriptInstance::has_method(const StringName &p_method) const { void PlaceHolderScriptInstance::update(const List<PropertyInfo> &p_properties, const Map<StringName, Variant> &p_values) { Set<StringName> new_values; - for (const List<PropertyInfo>::Element *E = p_properties.front(); E; E = E->next()) { - StringName n = E->get().name; + for (const PropertyInfo &E : p_properties) { + StringName n = E.name; new_values.insert(n); - if (!values.has(n) || values[n].get_type() != E->get().type) { + if (!values.has(n) || values[n].get_type() != E.type) { if (p_values.has(n)) { values[n] = p_values[n]; } @@ -511,7 +511,7 @@ void PlaceHolderScriptInstance::update(const List<PropertyInfo> &p_properties, c Variant defval; if (script->get_property_default_value(E->key(), defval)) { //remove because it's the same as the default value - if (defval == E->get()) { + if (defval == E) { to_remove.push_back(E->key()); } } @@ -542,8 +542,8 @@ void PlaceHolderScriptInstance::property_set_fallback(const StringName &p_name, } bool found = false; - for (const List<PropertyInfo>::Element *F = properties.front(); F; F = F->next()) { - if (F->get().name == p_name) { + for (const PropertyInfo &F : properties) { + if (F.name == p_name) { found = true; break; } diff --git a/core/object/undo_redo.cpp b/core/object/undo_redo.cpp index 96c96c1efb..adf068eb2f 100644 --- a/core/object/undo_redo.cpp +++ b/core/object/undo_redo.cpp @@ -39,11 +39,15 @@ void UndoRedo::_discard_redo() { } for (int i = current_action + 1; i < actions.size(); i++) { - for (List<Operation>::Element *E = actions.write[i].do_ops.front(); E; E = E->next()) { - if (E->get().type == Operation::TYPE_REFERENCE) { - Object *obj = ObjectDB::get_instance(E->get().object); - if (obj) { - memdelete(obj); + for (Operation &E : actions.write[i].do_ops) { + if (E.type == Operation::TYPE_REFERENCE) { + if (E.ref.is_valid()) { + E.ref.unref(); + } else { + Object *obj = ObjectDB::get_instance(E.object); + if (obj) { + memdelete(obj); + } } } } @@ -65,7 +69,7 @@ bool UndoRedo::_redo(bool p_execute) { _process_operation_list(actions.write[current_action].do_ops.front()); } version++; - emit_signal("version_changed"); + emit_signal(SNAME("version_changed")); return true; } @@ -240,11 +244,15 @@ void UndoRedo::_pop_history_tail() { return; } - for (List<Operation>::Element *E = actions.write[0].undo_ops.front(); E; E = E->next()) { - if (E->get().type == Operation::TYPE_REFERENCE) { - Object *obj = ObjectDB::get_instance(E->get().object); - if (obj) { - memdelete(obj); + for (Operation &E : actions.write[0].undo_ops) { + if (E.type == Operation::TYPE_REFERENCE) { + if (E.ref.is_valid()) { + E.ref.unref(); + } else { + Object *obj = ObjectDB::get_instance(E.object); + if (obj) { + memdelete(obj); + } } } } @@ -352,7 +360,7 @@ bool UndoRedo::undo() { _process_operation_list(actions.write[current_action].undo_ops.front()); current_action--; version--; - emit_signal("version_changed"); + emit_signal(SNAME("version_changed")); return true; } @@ -385,7 +393,7 @@ void UndoRedo::clear_history(bool p_increase_version) { if (p_increase_version) { version++; - emit_signal("version_changed"); + emit_signal(SNAME("version_changed")); } } @@ -460,8 +468,8 @@ Variant UndoRedo::_add_do_method(const Variant **p_args, int p_argcount, Callabl v[i] = *p_args[i + 2]; } - static_assert(VARIANT_ARG_MAX == 5, "This code needs to be updated if VARIANT_ARG_MAX != 5"); - add_do_method(object, method, v[0], v[1], v[2], v[3], v[4]); + static_assert(VARIANT_ARG_MAX == 8, "This code needs to be updated if VARIANT_ARG_MAX != 8"); + add_do_method(object, method, v[0], v[1], v[2], v[3], v[4], v[5], v[6], v[7]); return Variant(); } @@ -497,8 +505,8 @@ Variant UndoRedo::_add_undo_method(const Variant **p_args, int p_argcount, Calla v[i] = *p_args[i + 2]; } - static_assert(VARIANT_ARG_MAX == 5, "This code needs to be updated if VARIANT_ARG_MAX != 5"); - add_undo_method(object, method, v[0], v[1], v[2], v[3], v[4]); + static_assert(VARIANT_ARG_MAX == 8, "This code needs to be updated if VARIANT_ARG_MAX != 8"); + add_undo_method(object, method, v[0], v[1], v[2], v[3], v[4], v[5], v[6], v[7]); return Variant(); } diff --git a/core/os/os.cpp b/core/os/os.cpp index 535eee4797..f7af74da3e 100644 --- a/core/os/os.cpp +++ b/core/os/os.cpp @@ -110,6 +110,10 @@ void OS::printerr(const char *p_format, ...) { va_end(argp); } +void OS::alert(const String &p_alert, const String &p_title) { + fprintf(stderr, "%s: %s\n", p_title.utf8().get_data(), p_alert.utf8().get_data()); +} + void OS::set_low_processor_usage_mode(bool p_enabled) { low_processor_usage_mode = p_enabled; } diff --git a/core/os/os.h b/core/os/os.h index 301718a8b3..fcb195afe1 100644 --- a/core/os/os.h +++ b/core/os/os.h @@ -120,6 +120,8 @@ public: virtual void open_midi_inputs(); virtual void close_midi_inputs(); + virtual void alert(const String &p_alert, const String &p_title = "ALERT!"); + virtual Error open_dynamic_library(const String p_path, void *&p_library_handle, bool p_also_set_library_path = false) { return ERR_UNAVAILABLE; } virtual Error close_dynamic_library(void *p_library_handle) { return ERR_UNAVAILABLE; } virtual Error get_dynamic_library_symbol_handle(void *p_library_handle, const String p_name, void *&p_symbol_handle, bool p_optional = false) { return ERR_UNAVAILABLE; } diff --git a/core/register_core_types.cpp b/core/register_core_types.cpp index eb37267546..c088390cf0 100644 --- a/core/register_core_types.cpp +++ b/core/register_core_types.cpp @@ -56,6 +56,7 @@ #include "core/io/pck_packer.h" #include "core/io/resource_format_binary.h" #include "core/io/resource_importer.h" +#include "core/io/resource_uid.h" #include "core/io/stream_peer_ssl.h" #include "core/io/tcp_server.h" #include "core/io/translation_loader_po.h" @@ -102,6 +103,8 @@ static NativeExtensionManager *native_extension_manager = nullptr; extern void register_global_constants(); extern void unregister_global_constants(); +static ResourceUID *resource_uid = nullptr; + void register_core_types() { //consistency check static_assert(sizeof(Callable) <= 16); @@ -225,6 +228,10 @@ void register_core_types() { GDREGISTER_VIRTUAL_CLASS(NativeExtensionManager); + GDREGISTER_VIRTUAL_CLASS(ResourceUID); + + resource_uid = memnew(ResourceUID); + native_extension_manager = memnew(NativeExtensionManager); ip = IP::create(); @@ -286,6 +293,7 @@ void register_core_singletons() { Engine::get_singleton()->add_singleton(Engine::Singleton("EngineDebugger", _EngineDebugger::get_singleton())); Engine::get_singleton()->add_singleton(Engine::Singleton("Time", Time::get_singleton())); Engine::get_singleton()->add_singleton(Engine::Singleton("NativeExtensionManager", NativeExtensionManager::get_singleton())); + Engine::get_singleton()->add_singleton(Engine::Singleton("ResourceUID", ResourceUID::get_singleton())); } void register_core_extensions() { @@ -304,6 +312,8 @@ void unregister_core_types() { native_extension_manager->deinitialize_extensions(NativeExtension::INITIALIZATION_LEVEL_CORE); memdelete(native_extension_manager); + + memdelete(resource_uid); memdelete(_resource_loader); memdelete(_resource_saver); memdelete(_os); diff --git a/core/string/node_path.cpp b/core/string/node_path.cpp index d3afa7b4dd..5fae13779e 100644 --- a/core/string/node_path.cpp +++ b/core/string/node_path.cpp @@ -240,19 +240,26 @@ NodePath NodePath::rel_path_to(const NodePath &p_np) const { common_parent--; Vector<StringName> relpath; + relpath.resize(src_dirs.size() + dst_dirs.size() + 1); - for (int i = src_dirs.size() - 1; i > common_parent; i--) { - relpath.push_back(".."); + StringName *relpath_ptr = relpath.ptrw(); + + int path_size = 0; + StringName back_str(".."); + for (int i = common_parent + 1; i < src_dirs.size(); i++) { + relpath_ptr[path_size++] = back_str; } for (int i = common_parent + 1; i < dst_dirs.size(); i++) { - relpath.push_back(dst_dirs[i]); + relpath_ptr[path_size++] = dst_dirs[i]; } - if (relpath.size() == 0) { - relpath.push_back("."); + if (path_size == 0) { + relpath_ptr[path_size++] = "."; } + relpath.resize(path_size); + return NodePath(relpath, p_np.get_subnames(), false); } diff --git a/core/string/optimized_translation.cpp b/core/string/optimized_translation.cpp index 268562d971..cf0b8d10db 100644 --- a/core/string/optimized_translation.cpp +++ b/core/string/optimized_translation.cpp @@ -66,9 +66,9 @@ void OptimizedTranslation::generate(const Ref<Translation> &p_from) { int total_compression_size = 0; int total_string_size = 0; - for (List<StringName>::Element *E = keys.front(); E; E = E->next()) { + for (StringName &E : keys) { //hash string - CharString cs = E->get().operator String().utf8(); + CharString cs = E.operator String().utf8(); uint32_t h = hash(0, cs.get_data()); Pair<int, CharString> p; p.first = idx; @@ -76,7 +76,7 @@ void OptimizedTranslation::generate(const Ref<Translation> &p_from) { buckets.write[h % size].push_back(p); //compress string - CharString src_s = p_from->get_message(E->get()).operator String().utf8(); + CharString src_s = p_from->get_message(E).operator String().utf8(); CompressedString ps; ps.orig_len = src_s.size(); ps.offset = total_compression_size; diff --git a/core/string/string_name.cpp b/core/string/string_name.cpp index 14b87072bb..9024f60dae 100644 --- a/core/string/string_name.cpp +++ b/core/string/string_name.cpp @@ -41,13 +41,17 @@ StaticCString StaticCString::create(const char *p_ptr) { StringName::_Data *StringName::_table[STRING_TABLE_LEN]; -StringName _scs_create(const char *p_chr) { - return (p_chr[0] ? StringName(StaticCString::create(p_chr)) : StringName()); +StringName _scs_create(const char *p_chr, bool p_static) { + return (p_chr[0] ? StringName(StaticCString::create(p_chr), p_static) : StringName()); } bool StringName::configured = false; Mutex StringName::mutex; +#ifdef DEBUG_ENABLED +bool StringName::debug_stringname = false; +#endif + void StringName::setup() { ERR_FAIL_COND(configured); for (int i = 0; i < STRING_TABLE_LEN; i++) { @@ -59,12 +63,29 @@ void StringName::setup() { void StringName::cleanup() { MutexLock lock(mutex); +#ifdef DEBUG_ENABLED + if (unlikely(debug_stringname)) { + Vector<_Data *> data; + for (int i = 0; i < STRING_TABLE_LEN; i++) { + _Data *d = _table[i]; + while (d) { + data.push_back(d); + d = d->next; + } + } + print_line("\nStringName Reference Ranking:\n"); + data.sort_custom<DebugSortReferences>(); + for (int i = 0; i < MIN(100, data.size()); i++) { + print_line(itos(i + 1) + ": " + data[i]->get_name() + " - " + itos(data[i]->debug_references)); + } + } +#endif int lost_strings = 0; for (int i = 0; i < STRING_TABLE_LEN; i++) { while (_table[i]) { _Data *d = _table[i]; lost_strings++; - if (OS::get_singleton()->is_stdout_verbose()) { + if (d->static_count.get() != d->refcount.get() && OS::get_singleton()->is_stdout_verbose()) { if (d->cname) { print_line("Orphan StringName: " + String(d->cname)); } else { @@ -79,6 +100,7 @@ void StringName::cleanup() { if (lost_strings) { print_verbose("StringName: " + itos(lost_strings) + " unclaimed string names at exit."); } + configured = false; } void StringName::unref() { @@ -87,6 +109,13 @@ void StringName::unref() { if (_data && _data->refcount.unref()) { MutexLock lock(mutex); + if (_data->static_count.get() > 0) { + if (_data->cname) { + ERR_PRINT("BUG: Unreferenced static string to 0: " + String(_data->cname)); + } else { + ERR_PRINT("BUG: Unreferenced static string to 0: " + String(_data->name)); + } + } if (_data->prev) { _data->prev->next = _data->next; } else { @@ -153,7 +182,7 @@ StringName::StringName(const StringName &p_name) { } } -StringName::StringName(const char *p_name) { +StringName::StringName(const char *p_name, bool p_static) { _data = nullptr; ERR_FAIL_COND(!configured); @@ -181,25 +210,42 @@ StringName::StringName(const char *p_name) { if (_data) { if (_data->refcount.ref()) { // exists - return; + if (p_static) { + _data->static_count.increment(); + } +#ifdef DEBUG_ENABLED + if (unlikely(debug_stringname)) { + _data->debug_references++; + } +#endif } + + return; } _data = memnew(_Data); _data->name = p_name; _data->refcount.init(); + _data->static_count.set(p_static ? 1 : 0); _data->hash = hash; _data->idx = idx; _data->cname = nullptr; _data->next = _table[idx]; _data->prev = nullptr; +#ifdef DEBUG_ENABLED + if (unlikely(debug_stringname)) { + // Keep in memory, force static. + _data->refcount.ref(); + _data->static_count.increment(); + } +#endif if (_table[idx]) { _table[idx]->prev = _data; } _table[idx] = _data; } -StringName::StringName(const StaticCString &p_static_string) { +StringName::StringName(const StaticCString &p_static_string, bool p_static) { _data = nullptr; ERR_FAIL_COND(!configured); @@ -225,6 +271,14 @@ StringName::StringName(const StaticCString &p_static_string) { if (_data) { if (_data->refcount.ref()) { // exists + if (p_static) { + _data->static_count.increment(); + } +#ifdef DEBUG_ENABLED + if (unlikely(debug_stringname)) { + _data->debug_references++; + } +#endif return; } } @@ -232,18 +286,26 @@ StringName::StringName(const StaticCString &p_static_string) { _data = memnew(_Data); _data->refcount.init(); + _data->static_count.set(p_static ? 1 : 0); _data->hash = hash; _data->idx = idx; _data->cname = p_static_string.ptr; _data->next = _table[idx]; _data->prev = nullptr; +#ifdef DEBUG_ENABLED + if (unlikely(debug_stringname)) { + // Keep in memory, force static. + _data->refcount.ref(); + _data->static_count.increment(); + } +#endif if (_table[idx]) { _table[idx]->prev = _data; } _table[idx] = _data; } -StringName::StringName(const String &p_name) { +StringName::StringName(const String &p_name, bool p_static) { _data = nullptr; ERR_FAIL_COND(!configured); @@ -269,6 +331,14 @@ StringName::StringName(const String &p_name) { if (_data) { if (_data->refcount.ref()) { // exists + if (p_static) { + _data->static_count.increment(); + } +#ifdef DEBUG_ENABLED + if (unlikely(debug_stringname)) { + _data->debug_references++; + } +#endif return; } } @@ -276,11 +346,20 @@ StringName::StringName(const String &p_name) { _data = memnew(_Data); _data->name = p_name; _data->refcount.init(); + _data->static_count.set(p_static ? 1 : 0); _data->hash = hash; _data->idx = idx; _data->cname = nullptr; _data->next = _table[idx]; _data->prev = nullptr; +#ifdef DEBUG_ENABLED + if (unlikely(debug_stringname)) { + // Keep in memory, force static. + _data->refcount.ref(); + _data->static_count.increment(); + } +#endif + if (_table[idx]) { _table[idx]->prev = _data; } @@ -311,6 +390,12 @@ StringName StringName::search(const char *p_name) { } if (_data && _data->refcount.ref()) { +#ifdef DEBUG_ENABLED + if (unlikely(debug_stringname)) { + _data->debug_references++; + } +#endif + return StringName(_data); } @@ -368,16 +453,17 @@ StringName StringName::search(const String &p_name) { } if (_data && _data->refcount.ref()) { +#ifdef DEBUG_ENABLED + if (unlikely(debug_stringname)) { + _data->debug_references++; + } +#endif return StringName(_data); } return StringName(); //does not exist } -StringName::~StringName() { - unref(); -} - bool operator==(const String &p_name, const StringName &p_string_name) { return p_name == p_string_name.operator String(); } diff --git a/core/string/string_name.h b/core/string/string_name.h index 44d0ea14fa..ce7988744b 100644 --- a/core/string/string_name.h +++ b/core/string/string_name.h @@ -44,16 +44,19 @@ struct StaticCString { class StringName { enum { - STRING_TABLE_BITS = 12, + STRING_TABLE_BITS = 16, STRING_TABLE_LEN = 1 << STRING_TABLE_BITS, STRING_TABLE_MASK = STRING_TABLE_LEN - 1 }; struct _Data { SafeRefCount refcount; + SafeNumeric<uint32_t> static_count; const char *cname = nullptr; String name; - +#ifdef DEBUG_ENABLED + uint32_t debug_references = 0; +#endif String get_name() const { return cname ? String(cname) : name; } int idx = 0; uint32_t hash = 0; @@ -79,6 +82,15 @@ class StringName { static void setup(); static void cleanup(); static bool configured; +#ifdef DEBUG_ENABLED + struct DebugSortReferences { + bool operator()(const _Data *p_left, const _Data *p_right) const { + return p_left->debug_references > p_right->debug_references; + } + }; + + static bool debug_stringname; +#endif StringName(_Data *p_data) { _data = p_data; } @@ -146,12 +158,20 @@ public: }; void operator=(const StringName &p_name); - StringName(const char *p_name); + StringName(const char *p_name, bool p_static = false); StringName(const StringName &p_name); - StringName(const String &p_name); - StringName(const StaticCString &p_static_string); + StringName(const String &p_name, bool p_static = false); + StringName(const StaticCString &p_static_string, bool p_static = false); StringName() {} - ~StringName(); + _FORCE_INLINE_ ~StringName() { + if (likely(configured) && _data) { //only free if configured + unref(); + } + } + +#ifdef DEBUG_ENABLED + static void set_debug_stringnames(bool p_enable) { debug_stringname = p_enable; } +#endif }; bool operator==(const String &p_name, const StringName &p_string_name); @@ -159,6 +179,8 @@ bool operator!=(const String &p_name, const StringName &p_string_name); bool operator==(const char *p_name, const StringName &p_string_name); bool operator!=(const char *p_name, const StringName &p_string_name); -StringName _scs_create(const char *p_chr); +StringName _scs_create(const char *p_chr, bool p_static = false); + +#define SNAME(m_arg) ([]() -> const StringName & { static StringName sname = _scs_create(m_arg, true); return sname; })() #endif // STRING_NAME_H diff --git a/core/string/translation.cpp b/core/string/translation.cpp index 153f0190fd..981954c8ae 100644 --- a/core/string/translation.cpp +++ b/core/string/translation.cpp @@ -84,6 +84,7 @@ static const char *locale_list[] = { "ast_ES", // Asturian (Spain) "ayc_PE", // Southern Aymara (Peru) "ay_PE", // Aymara (Peru) + "az", // Azerbaijani "az_AZ", // Azerbaijani (Azerbaijan) "be", // Belarusian "be_BY", // Belarusian (Belarus) @@ -240,6 +241,7 @@ static const char *locale_list[] = { "ka_GE", // Georgian (Georgia) "kk_KZ", // Kazakh (Kazakhstan) "kl_GL", // Kalaallisut (Greenland) + "km", // Central Khmer "km_KH", // Central Khmer (Cambodia) "kn_IN", // Kannada (India) "kok_IN", // Konkani (India) @@ -390,6 +392,7 @@ static const char *locale_list[] = { "tr_CY", // Turkish (Cyprus) "tr_TR", // Turkish (Turkey) "ts_ZA", // Tsonga (South Africa) + "tt", // Tatar "tt_RU", // Tatar (Russia) "tzm", // Central Atlas Tamazight "tzm_MA", // Central Atlas Tamazight (Marrocos) @@ -458,6 +461,7 @@ static const char *locale_names[] = { "Asturian (Spain)", "Southern Aymara (Peru)", "Aymara (Peru)", + "Azerbaijani", "Azerbaijani (Azerbaijan)", "Belarusian", "Belarusian (Belarus)", @@ -614,6 +618,7 @@ static const char *locale_names[] = { "Georgian (Georgia)", "Kazakh (Kazakhstan)", "Kalaallisut (Greenland)", + "Central Khmer", "Central Khmer (Cambodia)", "Kannada (India)", "Konkani (India)", @@ -764,6 +769,7 @@ static const char *locale_names[] = { "Turkish (Cyprus)", "Turkish (Turkey)", "Tsonga (South Africa)", + "Tatar", "Tatar (Russia)", "Central Atlas Tamazight", "Central Atlas Tamazight (Marrocos)", @@ -835,8 +841,8 @@ Vector<String> Translation::_get_message_list() const { void Translation::_set_messages(const Dictionary &p_messages) { List<Variant> keys; p_messages.get_key_list(&keys); - for (List<Variant>::Element *E = keys.front(); E; E = E->next()) { - translation_map[E->get()] = p_messages[E->get()]; + for (Variant &E : keys) { + translation_map[E] = p_messages[E]; } } diff --git a/core/string/translation_po.cpp b/core/string/translation_po.cpp index f9b4e661e4..afd3b76588 100644 --- a/core/string/translation_po.cpp +++ b/core/string/translation_po.cpp @@ -47,8 +47,7 @@ void TranslationPO::print_translation_map() { List<StringName> context_l; translation_map.get_key_list(&context_l); - for (List<StringName>::Element *E = context_l.front(); E; E = E->next()) { - StringName ctx = E->get(); + for (StringName &ctx : context_l) { file->store_line(" ===== Context: " + String::utf8(String(ctx).utf8()) + " ===== "); const HashMap<StringName, Vector<StringName>> &inner_map = translation_map[ctx]; @@ -74,8 +73,7 @@ Dictionary TranslationPO::_get_messages() const { List<StringName> context_l; translation_map.get_key_list(&context_l); - for (List<StringName>::Element *E = context_l.front(); E; E = E->next()) { - StringName ctx = E->get(); + for (StringName &ctx : context_l) { const HashMap<StringName, Vector<StringName>> &id_str_map = translation_map[ctx]; Dictionary d2; @@ -98,8 +96,7 @@ void TranslationPO::_set_messages(const Dictionary &p_messages) { List<Variant> context_l; p_messages.get_key_list(&context_l); - for (List<Variant>::Element *E = context_l.front(); E; E = E->next()) { - StringName ctx = E->get(); + for (Variant &ctx : context_l) { const Dictionary &id_str_map = p_messages[ctx]; HashMap<StringName, Vector<StringName>> temp_map; @@ -121,8 +118,8 @@ Vector<String> TranslationPO::_get_message_list() const { get_message_list(&msgs); Vector<String> v; - for (List<StringName>::Element *E = msgs.front(); E; E = E->next()) { - v.push_back(E->get()); + for (StringName &E : msgs) { + v.push_back(E); } return v; @@ -281,13 +278,13 @@ void TranslationPO::get_message_list(List<StringName> *r_messages) const { List<StringName> context_l; translation_map.get_key_list(&context_l); - for (List<StringName>::Element *E = context_l.front(); E; E = E->next()) { - if (String(E->get()) != "") { + for (StringName &E : context_l) { + if (String(E) != "") { continue; } List<StringName> msgid_l; - translation_map[E->get()].get_key_list(&msgid_l); + translation_map[E].get_key_list(&msgid_l); for (List<StringName>::Element *E2 = msgid_l.front(); E2; E2 = E2->next()) { r_messages->push_back(E2->get()); @@ -300,8 +297,8 @@ int TranslationPO::get_message_count() const { translation_map.get_key_list(&context_l); int count = 0; - for (List<StringName>::Element *E = context_l.front(); E; E = E->next()) { - count += translation_map[E->get()].size(); + for (StringName &E : context_l) { + count += translation_map[E].size(); } return count; } diff --git a/core/string/ustring.cpp b/core/string/ustring.cpp index 4cd2915ffa..dbb8dc8283 100644 --- a/core/string/ustring.cpp +++ b/core/string/ustring.cpp @@ -3421,11 +3421,8 @@ String String::format(const Variant &values, String placeholder) const { List<Variant> keys; d.get_key_list(&keys); - for (List<Variant>::Element *E = keys.front(); E; E = E->next()) { - String key = E->get(); - String val = d[E->get()]; - - new_string = new_string.replace(placeholder.replace("_", key), val); + for (Variant &key : keys) { + new_string = new_string.replace(placeholder.replace("_", key), d[key]); } } else { ERR_PRINT(String("Invalid type: use Array or Dictionary.").ascii().get_data()); diff --git a/core/templates/hashfuncs.h b/core/templates/hashfuncs.h index 4572b269cf..2e932f9f26 100644 --- a/core/templates/hashfuncs.h +++ b/core/templates/hashfuncs.h @@ -95,7 +95,7 @@ static inline uint32_t hash_djb2_one_float(double p_in, uint32_t p_prev = 5381) if (p_in == 0.0f) { u.d = 0.0; } else if (Math::is_nan(p_in)) { - u.d = Math_NAN; + u.d = NAN; } else { u.d = p_in; } @@ -124,7 +124,7 @@ static inline uint64_t hash_djb2_one_float_64(double p_in, uint64_t p_prev = 538 if (p_in == 0.0f) { u.d = 0.0; } else if (Math::is_nan(p_in)) { - u.d = Math_NAN; + u.d = NAN; } else { u.d = p_in; } diff --git a/core/variant/callable.cpp b/core/variant/callable.cpp index ca6f3d615e..2a3a9a4f1a 100644 --- a/core/variant/callable.cpp +++ b/core/variant/callable.cpp @@ -407,8 +407,8 @@ Array Signal::get_connections() const { object->get_signal_connection_list(name, &connections); Array arr; - for (List<Object::Connection>::Element *E = connections.front(); E; E = E->next()) { - arr.push_back(E->get()); + for (Object::Connection &E : connections) { + arr.push_back(E); } return arr; } diff --git a/core/variant/variant.cpp b/core/variant/variant.cpp index badb5ba103..12b6465005 100644 --- a/core/variant/variant.cpp +++ b/core/variant/variant.cpp @@ -1681,10 +1681,10 @@ String Variant::stringify(List<const void *> &stack) const { Vector<_VariantStrPair> pairs; - for (List<Variant>::Element *E = keys.front(); E; E = E->next()) { + for (Variant &E : keys) { _VariantStrPair sp; - sp.key = E->get().stringify(stack); - sp.value = d[E->get()].stringify(stack); + sp.key = E.stringify(stack); + sp.value = d[E].stringify(stack); pairs.push_back(sp); } diff --git a/core/variant/variant.h b/core/variant/variant.h index 373fe32921..6d1b4da9e8 100644 --- a/core/variant/variant.h +++ b/core/variant/variant.h @@ -502,7 +502,7 @@ public: static uint32_t get_builtin_method_hash(Variant::Type p_type, const StringName &p_method); void call(const StringName &p_method, const Variant **p_args, int p_argcount, Variant &r_ret, Callable::CallError &r_error); - Variant call(const StringName &p_method, const Variant &p_arg1 = Variant(), const Variant &p_arg2 = Variant(), const Variant &p_arg3 = Variant(), const Variant &p_arg4 = Variant(), const Variant &p_arg5 = Variant()); + Variant call(const StringName &p_method, const Variant &p_arg1 = Variant(), const Variant &p_arg2 = Variant(), const Variant &p_arg3 = Variant(), const Variant &p_arg4 = Variant(), const Variant &p_arg5 = Variant(), const Variant &p_arg6 = Variant(), const Variant &p_arg7 = Variant(), const Variant &p_arg8 = Variant()); static void call_static(Variant::Type p_type, const StringName &p_method, const Variant **p_args, int p_argcount, Variant &r_ret, Callable::CallError &r_error); diff --git a/core/variant/variant_call.cpp b/core/variant/variant_call.cpp index 733361fe58..a9645da045 100644 --- a/core/variant/variant_call.cpp +++ b/core/variant/variant_call.cpp @@ -750,6 +750,42 @@ struct _VariantCall { return 0; } + static PackedInt32Array func_PackedByteArray_decode_s32_array(PackedByteArray *p_instance) { + uint64_t size = p_instance->size(); + const uint8_t *r = p_instance->ptr(); + PackedInt32Array dest; + dest.resize(size / sizeof(int32_t)); + memcpy(dest.ptrw(), r, size); + return dest; + } + + static PackedInt64Array func_PackedByteArray_decode_s64_array(PackedByteArray *p_instance) { + uint64_t size = p_instance->size(); + const uint8_t *r = p_instance->ptr(); + PackedInt64Array dest; + dest.resize(size / sizeof(int64_t)); + memcpy(dest.ptrw(), r, size); + return dest; + } + + static PackedFloat32Array func_PackedByteArray_decode_float_array(PackedByteArray *p_instance) { + uint64_t size = p_instance->size(); + const uint8_t *r = p_instance->ptr(); + PackedFloat32Array dest; + dest.resize(size / sizeof(float)); + memcpy(dest.ptrw(), r, size); + return dest; + } + + static PackedFloat64Array func_PackedByteArray_decode_double_array(PackedByteArray *p_instance) { + uint64_t size = p_instance->size(); + const uint8_t *r = p_instance->ptr(); + PackedFloat64Array dest; + dest.resize(size / sizeof(double)); + memcpy(dest.ptrw(), r, size); + return dest; + } + static void func_PackedByteArray_encode_u8(PackedByteArray *p_instance, int64_t p_offset, int64_t p_value) { uint64_t size = p_instance->size(); ERR_FAIL_COND(p_offset < 0 || p_offset > int64_t(size) - 1); @@ -1088,8 +1124,8 @@ bool Variant::has_builtin_method_return_value(Variant::Type p_type, const String void Variant::get_builtin_method_list(Variant::Type p_type, List<StringName> *p_list) { ERR_FAIL_INDEX(p_type, Variant::VARIANT_MAX); - for (List<StringName>::Element *E = builtin_method_names[p_type].front(); E; E = E->next()) { - p_list->push_back(E->get()); + for (StringName &E : builtin_method_names[p_type]) { + p_list->push_back(E); } } @@ -1152,12 +1188,12 @@ void Variant::get_method_list(List<MethodInfo> *p_list) const { obj->get_method_list(p_list); } } else { - for (List<StringName>::Element *E = builtin_method_names[type].front(); E; E = E->next()) { - const VariantBuiltInMethodInfo *method = builtin_method_info[type].lookup_ptr(E->get()); + for (StringName &E : builtin_method_names[type]) { + const VariantBuiltInMethodInfo *method = builtin_method_info[type].lookup_ptr(E); ERR_CONTINUE(!method); MethodInfo mi; - mi.name = E->get(); + mi.name = E; //return type if (method->has_return_type) { @@ -1824,6 +1860,11 @@ static void _register_variant_builtin_methods() { bind_function(PackedByteArray, decode_var, _VariantCall::func_PackedByteArray_decode_var, sarray("byte_offset", "allow_objects"), varray(false)); bind_function(PackedByteArray, decode_var_size, _VariantCall::func_PackedByteArray_decode_var_size, sarray("byte_offset", "allow_objects"), varray(false)); + bind_function(PackedByteArray, to_int32_array, _VariantCall::func_PackedByteArray_decode_s32_array, sarray(), varray()); + bind_function(PackedByteArray, to_int64_array, _VariantCall::func_PackedByteArray_decode_s64_array, sarray(), varray()); + bind_function(PackedByteArray, to_float32_array, _VariantCall::func_PackedByteArray_decode_float_array, sarray(), varray()); + bind_function(PackedByteArray, to_float64_array, _VariantCall::func_PackedByteArray_decode_double_array, sarray(), varray()); + bind_functionnc(PackedByteArray, encode_u8, _VariantCall::func_PackedByteArray_encode_u8, sarray("byte_offset", "value"), varray()); bind_functionnc(PackedByteArray, encode_s8, _VariantCall::func_PackedByteArray_encode_s8, sarray("byte_offset", "value"), varray()); bind_functionnc(PackedByteArray, encode_u16, _VariantCall::func_PackedByteArray_encode_u16, sarray("byte_offset", "value"), varray()); @@ -2002,7 +2043,7 @@ static void _register_variant_builtin_methods() { _VariantCall::add_variant_constant(Variant::VECTOR3, "ZERO", Vector3(0, 0, 0)); _VariantCall::add_variant_constant(Variant::VECTOR3, "ONE", Vector3(1, 1, 1)); - _VariantCall::add_variant_constant(Variant::VECTOR3, "INF", Vector3(Math_INF, Math_INF, Math_INF)); + _VariantCall::add_variant_constant(Variant::VECTOR3, "INF", Vector3(INFINITY, INFINITY, INFINITY)); _VariantCall::add_variant_constant(Variant::VECTOR3, "LEFT", Vector3(-1, 0, 0)); _VariantCall::add_variant_constant(Variant::VECTOR3, "RIGHT", Vector3(1, 0, 0)); _VariantCall::add_variant_constant(Variant::VECTOR3, "UP", Vector3(0, 1, 0)); @@ -2031,7 +2072,7 @@ static void _register_variant_builtin_methods() { _VariantCall::add_variant_constant(Variant::VECTOR2, "ZERO", Vector2(0, 0)); _VariantCall::add_variant_constant(Variant::VECTOR2, "ONE", Vector2(1, 1)); - _VariantCall::add_variant_constant(Variant::VECTOR2, "INF", Vector2(Math_INF, Math_INF)); + _VariantCall::add_variant_constant(Variant::VECTOR2, "INF", Vector2(INFINITY, INFINITY)); _VariantCall::add_variant_constant(Variant::VECTOR2, "LEFT", Vector2(-1, 0)); _VariantCall::add_variant_constant(Variant::VECTOR2, "RIGHT", Vector2(1, 0)); _VariantCall::add_variant_constant(Variant::VECTOR2, "UP", Vector2(0, -1)); diff --git a/core/variant/variant_parser.cpp b/core/variant/variant_parser.cpp index 86d5ae7f38..dc92ac8ac4 100644 --- a/core/variant/variant_parser.cpp +++ b/core/variant/variant_parser.cpp @@ -506,9 +506,9 @@ Error VariantParser::parse_value(Token &token, Variant &value, Stream *p_stream, } else if (id == "null" || id == "nil") { value = Variant(); } else if (id == "inf") { - value = Math_INF; + value = INFINITY; } else if (id == "nan") { - value = Math_NAN; + value = NAN; } else if (id == "Vector2") { Vector<real_t> args; Error err = _parse_construct<real_t>(p_stream, args, line, r_err_str); @@ -1586,8 +1586,8 @@ Error VariantWriter::write(const Variant &p_variant, StoreStringFunc p_store_str List<PropertyInfo> props; obj->get_property_list(&props); bool first = true; - for (List<PropertyInfo>::Element *E = props.front(); E; E = E->next()) { - if (E->get().usage & PROPERTY_USAGE_STORAGE || E->get().usage & PROPERTY_USAGE_SCRIPT_VARIABLE) { + for (PropertyInfo &E : props) { + if (E.usage & PROPERTY_USAGE_STORAGE || E.usage & PROPERTY_USAGE_SCRIPT_VARIABLE) { //must be serialized if (first) { @@ -1596,8 +1596,8 @@ Error VariantWriter::write(const Variant &p_variant, StoreStringFunc p_store_str p_store_string_func(p_store_string_ud, ","); } - p_store_string_func(p_store_string_ud, "\"" + E->get().name + "\":"); - write(obj->get(E->get().name), p_store_string_func, p_store_string_ud, p_encode_res_func, p_encode_res_ud); + p_store_string_func(p_store_string_ud, "\"" + E.name + "\":"); + write(obj->get(E.name), p_store_string_func, p_store_string_ud, p_encode_res_func, p_encode_res_ud); } } @@ -1615,7 +1615,7 @@ Error VariantWriter::write(const Variant &p_variant, StoreStringFunc p_store_str p_store_string_func(p_store_string_ud, "{\n"); for (List<Variant>::Element *E = keys.front(); E; E = E->next()) { /* - if (!_check_type(dict[E->get()])) + if (!_check_type(dict[E])) continue; */ write(E->get(), p_store_string_func, p_store_string_ud, p_encode_res_func, p_encode_res_ud); diff --git a/core/variant/variant_setget.cpp b/core/variant/variant_setget.cpp index de1deace63..62228ea87c 100644 --- a/core/variant/variant_setget.cpp +++ b/core/variant/variant_setget.cpp @@ -1093,9 +1093,9 @@ void Variant::get_property_list(List<PropertyInfo> *p_list) const { const Dictionary *dic = reinterpret_cast<const Dictionary *>(_data._mem); List<Variant> keys; dic->get_key_list(&keys); - for (List<Variant>::Element *E = keys.front(); E; E = E->next()) { - if (E->get().get_type() == Variant::STRING) { - p_list->push_back(PropertyInfo(Variant::STRING, E->get())); + for (Variant &E : keys) { + if (E.get_type() == Variant::STRING) { + p_list->push_back(PropertyInfo(Variant::STRING, E)); } } } else if (type == OBJECT) { @@ -1106,10 +1106,10 @@ void Variant::get_property_list(List<PropertyInfo> *p_list) const { } else { List<StringName> members; get_member_list(type, &members); - for (List<StringName>::Element *E = members.front(); E; E = E->next()) { + for (StringName &E : members) { PropertyInfo pi; - pi.name = E->get(); - pi.type = get_member_type(type, E->get()); + pi.name = E; + pi.type = get_member_type(type, E); p_list->push_back(pi); } } diff --git a/core/variant/variant_utility.cpp b/core/variant/variant_utility.cpp index 1f69e81d99..e9fa952af3 100644 --- a/core/variant/variant_utility.cpp +++ b/core/variant/variant_utility.cpp @@ -1397,8 +1397,8 @@ uint32_t Variant::get_utility_function_hash(const StringName &p_name) { } void Variant::get_utility_function_list(List<StringName> *r_functions) { - for (List<StringName>::Element *E = utility_function_name_table.front(); E; E = E->next()) { - r_functions->push_back(E->get()); + for (StringName &E : utility_function_name_table) { + r_functions->push_back(E); } } |