summaryrefslogtreecommitdiff
path: root/core
diff options
context:
space:
mode:
Diffstat (limited to 'core')
-rw-r--r--core/config/project_settings.cpp168
-rw-r--r--core/config/project_settings.h14
-rw-r--r--core/core_bind.cpp42
-rw-r--r--core/core_bind.h13
-rw-r--r--core/core_builders.py4
-rw-r--r--core/core_constants.cpp698
-rw-r--r--core/debugger/engine_debugger.h2
-rw-r--r--core/debugger/local_debugger.cpp4
-rw-r--r--core/debugger/local_debugger.h2
-rw-r--r--core/debugger/remote_debugger.cpp10
-rw-r--r--core/debugger/remote_debugger.h4
-rw-r--r--core/debugger/script_debugger.cpp4
-rw-r--r--core/debugger/script_debugger.h2
-rw-r--r--core/doc_data.cpp4
-rw-r--r--core/doc_data.h40
-rw-r--r--core/error/error_macros.cpp38
-rw-r--r--core/error/error_macros.h251
-rw-r--r--core/extension/extension_api_dump.cpp4
-rw-r--r--core/extension/gdnative_interface.cpp57
-rw-r--r--core/extension/gdnative_interface.h15
-rw-r--r--core/extension/native_extension.cpp3
-rw-r--r--core/extension/native_extension_manager.cpp2
-rw-r--r--core/input/gamecontrollerdb.txt1038
-rw-r--r--core/input/input.cpp248
-rw-r--r--core/input/input.h25
-rw-r--r--core/input/input_enums.h184
-rw-r--r--core/input/input_event.cpp177
-rw-r--r--core/input/input_event.h24
-rw-r--r--core/input/input_map.cpp178
-rw-r--r--core/input/input_map.h4
-rw-r--r--core/io/compression.h2
-rw-r--r--core/io/config_file.cpp8
-rw-r--r--core/io/dir_access.cpp8
-rw-r--r--core/io/file_access.cpp4
-rw-r--r--core/io/file_access_pack.cpp2
-rw-r--r--core/io/http_client.cpp14
-rw-r--r--core/io/http_client.h4
-rw-r--r--core/io/http_client_tcp.cpp93
-rw-r--r--core/io/http_client_tcp.h11
-rw-r--r--core/io/image.cpp74
-rw-r--r--core/io/image.h11
-rw-r--r--core/io/logger.cpp16
-rw-r--r--core/io/logger.h5
-rw-r--r--core/io/marshalls.cpp2
-rw-r--r--core/io/marshalls.h6
-rw-r--r--core/io/packed_data_container.cpp4
-rw-r--r--core/io/pck_packer.cpp3
-rw-r--r--core/io/pck_packer.h2
-rw-r--r--core/io/resource.cpp9
-rw-r--r--core/io/resource.h1
-rw-r--r--core/io/resource_format_binary.cpp20
-rw-r--r--core/io/resource_importer.cpp14
-rw-r--r--core/io/resource_importer.h4
-rw-r--r--core/io/resource_loader.cpp16
-rw-r--r--core/io/translation_loader_po.cpp16
-rw-r--r--core/math/a_star.cpp16
-rw-r--r--core/math/a_star.h4
-rw-r--r--core/math/aabb.cpp22
-rw-r--r--core/math/aabb.h36
-rw-r--r--core/math/audio_frame.h3
-rw-r--r--core/math/basis.cpp531
-rw-r--r--core/math/basis.h46
-rw-r--r--core/math/bvh.h2
-rw-r--r--core/math/bvh_logic.inc50
-rw-r--r--core/math/bvh_pair.inc2
-rw-r--r--core/math/bvh_split.inc4
-rw-r--r--core/math/camera_matrix.cpp22
-rw-r--r--core/math/color.cpp96
-rw-r--r--core/math/color.h4
-rw-r--r--core/math/convex_hull.cpp36
-rw-r--r--core/math/delaunay_2d.h4
-rw-r--r--core/math/expression.cpp14
-rw-r--r--core/math/face3.h14
-rw-r--r--core/math/geometry_2d.h5
-rw-r--r--core/math/geometry_3d.h2
-rw-r--r--core/math/math_defs.h53
-rw-r--r--core/math/math_funcs.cpp4
-rw-r--r--core/math/math_funcs.h26
-rw-r--r--core/math/plane.cpp2
-rw-r--r--core/math/quaternion.cpp13
-rw-r--r--core/math/quaternion.h13
-rw-r--r--core/math/rect2.cpp10
-rw-r--r--core/math/rect2.h92
-rw-r--r--core/math/transform_2d.cpp10
-rw-r--r--core/math/transform_2d.h2
-rw-r--r--core/math/transform_3d.cpp6
-rw-r--r--core/math/triangulate.cpp11
-rw-r--r--core/math/vector2.cpp13
-rw-r--r--core/math/vector2.h18
-rw-r--r--core/math/vector3.cpp17
-rw-r--r--core/math/vector3.h55
-rw-r--r--core/math/vector3i.cpp8
-rw-r--r--core/math/vector3i.h6
-rw-r--r--core/multiplayer/multiplayer_replicator.cpp2
-rw-r--r--core/object/class_db.cpp50
-rw-r--r--core/object/class_db.h5
-rw-r--r--core/object/make_virtuals.py11
-rw-r--r--core/object/method_bind.cpp2
-rw-r--r--core/object/object.cpp23
-rw-r--r--core/object/object.h13
-rw-r--r--core/object/script_language.cpp4
-rw-r--r--core/object/undo_redo.cpp4
-rw-r--r--core/os/keyboard.cpp709
-rw-r--r--core/os/keyboard.h539
-rw-r--r--core/os/memory.h1
-rw-r--r--core/os/midi_driver.cpp18
-rw-r--r--core/os/os.cpp28
-rw-r--r--core/os/os.h29
-rw-r--r--core/string/node_path.cpp8
-rw-r--r--core/string/print_string.cpp6
-rw-r--r--core/string/print_string.h12
-rw-r--r--core/string/string_builder.cpp2
-rw-r--r--core/string/string_name.cpp4
-rw-r--r--core/string/translation.cpp8
-rw-r--r--core/string/ustring.cpp162
-rw-r--r--core/string/ustring.h22
-rw-r--r--core/templates/bin_sorted_array.h2
-rw-r--r--core/templates/cowdata.h2
-rw-r--r--core/templates/hash_map.h6
-rw-r--r--core/templates/list.h16
-rw-r--r--core/templates/local_vector.h12
-rw-r--r--core/templates/oa_hash_map.h3
-rw-r--r--core/templates/ordered_hash_map.h12
-rw-r--r--core/templates/thread_work_pool.cpp2
-rw-r--r--core/templates/thread_work_pool.h24
-rw-r--r--core/templates/vector.h42
-rw-r--r--core/templates/vmap.h5
-rw-r--r--core/templates/vset.h2
-rw-r--r--core/typedefs.h7
-rw-r--r--core/variant/array.cpp131
-rw-r--r--core/variant/array.h7
-rw-r--r--core/variant/binder_common.h12
-rw-r--r--core/variant/dictionary.cpp62
-rw-r--r--core/variant/dictionary.h3
-rw-r--r--core/variant/type_info.h2
-rw-r--r--core/variant/variant.cpp92
-rw-r--r--core/variant/variant.h25
-rw-r--r--core/variant/variant_call.cpp98
-rw-r--r--core/variant/variant_construct.cpp3
-rw-r--r--core/variant/variant_internal.h16
-rw-r--r--core/variant/variant_parser.cpp77
-rw-r--r--core/variant/variant_parser.h2
-rw-r--r--core/variant/variant_setget.cpp18
-rw-r--r--core/variant/variant_utility.cpp18
144 files changed, 4313 insertions, 2930 deletions
diff --git a/core/config/project_settings.cpp b/core/config/project_settings.cpp
index 562cbbdd27..c85b0866cb 100644
--- a/core/config/project_settings.cpp
+++ b/core/config/project_settings.cpp
@@ -41,6 +41,11 @@
#include "core/os/keyboard.h"
#include "core/os/os.h"
#include "core/variant/variant_parser.h"
+#include "core/version.h"
+
+#include "modules/modules_enabled.gen.h" // For mono.
+
+const String ProjectSettings::PROJECT_DATA_DIR_NAME_SUFFIX = "godot";
ProjectSettings *ProjectSettings::singleton = nullptr;
@@ -60,10 +65,81 @@ String ProjectSettings::get_resource_path() const {
return resource_path;
}
+String ProjectSettings::get_safe_project_name() const {
+ String safe_name = OS::get_singleton()->get_safe_dir_name(get("application/config/name"));
+ if (safe_name.is_empty()) {
+ safe_name = "UnnamedProject";
+ }
+ return safe_name;
+}
+
String ProjectSettings::get_imported_files_path() const {
return get_project_data_path().plus_file("imported");
}
+// Returns the features that a project must have when opened with this build of Godot.
+// This is used by the project manager to provide the initial_settings for config/features.
+const PackedStringArray ProjectSettings::get_required_features() {
+ PackedStringArray features = PackedStringArray();
+ features.append(VERSION_BRANCH);
+#ifdef REAL_T_IS_DOUBLE
+ features.append("Double Precision");
+#endif
+ return features;
+}
+
+// Returns the features supported by this build of Godot. Includes all required features.
+const PackedStringArray ProjectSettings::_get_supported_features() {
+ PackedStringArray features = get_required_features();
+#ifdef MODULE_MONO_ENABLED
+ features.append("C#");
+#endif
+ // Allow pinning to a specific patch number or build type by marking
+ // them as supported. They're only used if the user adds them manually.
+ features.append(VERSION_BRANCH "." _MKSTR(VERSION_PATCH));
+ features.append(VERSION_FULL_CONFIG);
+ features.append(VERSION_FULL_BUILD);
+ // For now, assume Vulkan is always supported.
+ // This should be removed if it's possible to build the editor without Vulkan.
+ features.append("Vulkan Clustered");
+ features.append("Vulkan Mobile");
+ return features;
+}
+
+// Returns the features that this project needs but this build of Godot lacks.
+const PackedStringArray ProjectSettings::get_unsupported_features(const PackedStringArray &p_project_features) {
+ PackedStringArray unsupported_features = PackedStringArray();
+ PackedStringArray supported_features = singleton->_get_supported_features();
+ for (int i = 0; i < p_project_features.size(); i++) {
+ if (!supported_features.has(p_project_features[i])) {
+ unsupported_features.append(p_project_features[i]);
+ }
+ }
+ unsupported_features.sort();
+ return unsupported_features;
+}
+
+// Returns the features that both this project has and this build of Godot has, ensuring required features exist.
+const PackedStringArray ProjectSettings::_trim_to_supported_features(const PackedStringArray &p_project_features) {
+ // Remove unsupported features if present.
+ PackedStringArray features = PackedStringArray(p_project_features);
+ PackedStringArray supported_features = _get_supported_features();
+ for (int i = p_project_features.size() - 1; i > -1; i--) {
+ if (!supported_features.has(p_project_features[i])) {
+ features.remove_at(i);
+ }
+ }
+ // Add required features if not present.
+ PackedStringArray required_features = get_required_features();
+ for (int i = 0; i < required_features.size(); i++) {
+ if (!features.has(required_features[i])) {
+ features.append(required_features[i]);
+ }
+ }
+ features.sort();
+ return features;
+}
+
String ProjectSettings::localize_path(const String &p_path) const {
if (resource_path.is_empty() || p_path.begins_with("res://") || p_path.begins_with("user://") ||
(p_path.is_absolute_path() && !p_path.begins_with(resource_path))) {
@@ -108,7 +184,7 @@ String ProjectSettings::localize_path(const String &p_path) const {
String parent = path.substr(0, sep);
String plocal = localize_path(parent);
- if (plocal == "") {
+ if (plocal.is_empty()) {
return "";
}
// Only strip the starting '/' from 'path' if its parent ('plocal') ends with '/'
@@ -152,13 +228,13 @@ bool ProjectSettings::get_ignore_value_in_docs(const String &p_name) const {
String ProjectSettings::globalize_path(const String &p_path) const {
if (p_path.begins_with("res://")) {
- if (resource_path != "") {
+ if (!resource_path.is_empty()) {
return p_path.replace("res:/", resource_path);
}
return p_path.replace("res://", "");
} else if (p_path.begins_with("user://")) {
String data_dir = OS::get_singleton()->get_user_data_dir();
- if (data_dir != "") {
+ if (!data_dir.is_empty()) {
return p_path.replace("user:/", data_dir);
}
return p_path.replace("user://", "");
@@ -366,12 +442,12 @@ void ProjectSettings::_convert_to_last_version(int p_from_version) {
* If a project file is found, load it or fail.
* If nothing was found, error out.
*/
-Error ProjectSettings::_setup(const String &p_path, const String &p_main_pack, bool p_upwards) {
+Error ProjectSettings::_setup(const String &p_path, const String &p_main_pack, bool p_upwards, bool p_ignore_override) {
// If looking for files in a network client, use it directly
if (FileAccessNetworkClient::get_singleton()) {
Error err = _load_settings_text_or_binary("res://project.godot", "res://project.binary");
- if (err == OK) {
+ if (err == OK && !p_ignore_override) {
// Optional, we don't mind if it fails
_load_settings_text("res://override.cfg");
}
@@ -380,12 +456,12 @@ Error ProjectSettings::_setup(const String &p_path, const String &p_main_pack, b
// Attempt with a user-defined main pack first
- if (p_main_pack != "") {
+ if (!p_main_pack.is_empty()) {
bool ok = _load_resource_pack(p_main_pack);
ERR_FAIL_COND_V_MSG(!ok, ERR_CANT_OPEN, "Cannot open resource pack '" + p_main_pack + "'.");
Error err = _load_settings_text_or_binary("res://project.godot", "res://project.binary");
- if (err == OK) {
+ if (err == OK && !p_ignore_override) {
// Load override from location of the main pack
// Optional, we don't mind if it fails
_load_settings_text(p_main_pack.get_base_dir().plus_file("override.cfg"));
@@ -395,7 +471,7 @@ Error ProjectSettings::_setup(const String &p_path, const String &p_main_pack, b
String exec_path = OS::get_singleton()->get_executable_path();
- if (exec_path != "") {
+ if (!exec_path.is_empty()) {
// We do several tests sequentially until one succeeds to find a PCK,
// and if so, we attempt loading it at the end.
@@ -435,7 +511,7 @@ Error ProjectSettings::_setup(const String &p_path, const String &p_main_pack, b
// If we opened our package, try and load our project.
if (found) {
Error err = _load_settings_text_or_binary("res://project.godot", "res://project.binary");
- if (err == OK) {
+ if (err == OK && !p_ignore_override) {
// Load override from location of the executable.
// Optional, we don't mind if it fails.
_load_settings_text(exec_path.get_base_dir().plus_file("override.cfg"));
@@ -447,16 +523,16 @@ Error ProjectSettings::_setup(const String &p_path, const String &p_main_pack, b
// Try to use the filesystem for files, according to OS.
// (Only Android -when reading from pck- and iOS use this.)
- if (OS::get_singleton()->get_resource_dir() != "") {
+ if (!OS::get_singleton()->get_resource_dir().is_empty()) {
// OS will call ProjectSettings->get_resource_path which will be empty if not overridden!
// If the OS would rather use a specific location, then it will not be empty.
resource_path = OS::get_singleton()->get_resource_dir().replace("\\", "/");
- if (resource_path != "" && resource_path[resource_path.length() - 1] == '/') {
+ if (!resource_path.is_empty() && resource_path[resource_path.length() - 1] == '/') {
resource_path = resource_path.substr(0, resource_path.length() - 1); // Chop end.
}
Error err = _load_settings_text_or_binary("res://project.godot", "res://project.binary");
- if (err == OK) {
+ if (err == OK && !p_ignore_override) {
// Optional, we don't mind if it fails.
_load_settings_text("res://override.cfg");
}
@@ -479,7 +555,7 @@ Error ProjectSettings::_setup(const String &p_path, const String &p_main_pack, b
resource_path = current_dir;
resource_path = resource_path.replace("\\", "/"); // Windows path to Unix path just in case.
err = _load_settings_text_or_binary(current_dir.plus_file("project.godot"), current_dir.plus_file("project.binary"));
- if (err == OK) {
+ if (err == OK && !p_ignore_override) {
// Optional, we don't mind if it fails.
_load_settings_text(current_dir.plus_file("override.cfg"));
found = true;
@@ -511,17 +587,18 @@ Error ProjectSettings::_setup(const String &p_path, const String &p_main_pack, b
return OK;
}
-Error ProjectSettings::setup(const String &p_path, const String &p_main_pack, bool p_upwards) {
- Error err = _setup(p_path, p_main_pack, p_upwards);
+Error ProjectSettings::setup(const String &p_path, const String &p_main_pack, bool p_upwards, bool p_ignore_override) {
+ Error err = _setup(p_path, p_main_pack, p_upwards, p_ignore_override);
if (err == OK) {
String custom_settings = GLOBAL_DEF("application/config/project_settings_override", "");
- if (custom_settings != "") {
+ if (!custom_settings.is_empty()) {
_load_settings_text(custom_settings);
}
}
// Updating the default value after the project settings have loaded.
- project_data_dir_name = GLOBAL_GET("application/config/project_data_dir_name");
+ bool use_hidden_directory = GLOBAL_GET("application/config/use_hidden_project_data_directory");
+ project_data_dir_name = (use_hidden_directory ? "." : "") + PROJECT_DATA_DIR_NAME_SUFFIX;
// Using GLOBAL_GET on every block for compressing can be slow, so assigning here.
Compression::zstd_long_distance_matching = GLOBAL_GET("compression/formats/zstd/long_distance_matching");
@@ -622,21 +699,21 @@ Error ProjectSettings::_load_settings_text(const String &p_path) {
return err;
}
- if (assign != String()) {
- if (section == String() && assign == "config_version") {
+ if (!assign.is_empty()) {
+ if (section.is_empty() && assign == "config_version") {
config_version = value;
if (config_version > CONFIG_VERSION) {
memdelete(f);
ERR_FAIL_V_MSG(ERR_FILE_CANT_OPEN, vformat("Can't open project at '%s', its `config_version` (%d) is from a more recent and incompatible version of the engine. Expected config version: %d.", p_path, config_version, CONFIG_VERSION));
}
} else {
- if (section == String()) {
+ if (section.is_empty()) {
set(assign, value);
} else {
set(section + "/" + assign, value);
}
}
- } else if (next_tag.name != String()) {
+ } else if (!next_tag.name.is_empty()) {
section = next_tag.name;
}
}
@@ -663,6 +740,13 @@ Error ProjectSettings::_load_settings_text_or_binary(const String &p_text_path,
return err;
}
+Error ProjectSettings::load_custom(const String &p_path) {
+ if (p_path.ends_with(".binary")) {
+ return _load_settings_binary(p_path);
+ }
+ return _load_settings_text(p_path);
+}
+
int ProjectSettings::get_order(const String &p_name) const {
ERR_FAIL_COND_V_MSG(!props.has(p_name), -1, "Request for nonexistent project setting: " + p_name + ".");
return props[p_name].order;
@@ -713,7 +797,7 @@ Error ProjectSettings::_save_settings_binary(const String &p_file, const Map<Str
count += E.value.size();
}
- if (p_custom_features != String()) {
+ if (!p_custom_features.is_empty()) {
file->store_32(count + 1);
//store how many properties are saved, add one for custom featuers, which must always go first
String key = CoreStringNames::get_singleton()->_custom_features;
@@ -743,7 +827,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 (String &key : E->get()) {
- if (E->key() != "") {
+ if (!E->key().is_empty()) {
key = E->key() + "/" + key;
}
Variant value;
@@ -797,7 +881,7 @@ Error ProjectSettings::_save_settings_text(const String &p_file, const Map<Strin
file->store_line("");
file->store_string("config_version=" + itos(CONFIG_VERSION) + "\n");
- if (p_custom_features != String()) {
+ if (!p_custom_features.is_empty()) {
file->store_string("custom_features=\"" + p_custom_features + "\"\n");
}
file->store_string("\n");
@@ -807,12 +891,12 @@ Error ProjectSettings::_save_settings_text(const String &p_file, const Map<Strin
file->store_string("\n");
}
- if (E->key() != "") {
+ if (!E->key().is_empty()) {
file->store_string("[" + E->key() + "]\n\n");
}
for (const String &F : E->get()) {
String key = F;
- if (E->key() != "") {
+ if (!E->key().is_empty()) {
key = E->key() + "/" + key;
}
Variant value;
@@ -840,7 +924,35 @@ Error ProjectSettings::_save_custom_bnd(const String &p_file) { // add other par
}
Error ProjectSettings::save_custom(const String &p_path, const CustomMap &p_custom, const Vector<String> &p_custom_features, bool p_merge_with_current) {
- ERR_FAIL_COND_V_MSG(p_path == "", ERR_INVALID_PARAMETER, "Project settings save path cannot be empty.");
+ ERR_FAIL_COND_V_MSG(p_path.is_empty(), ERR_INVALID_PARAMETER, "Project settings save path cannot be empty.");
+
+ PackedStringArray project_features = has_setting("application/config/features") ? (PackedStringArray)get_setting("application/config/features") : PackedStringArray();
+ // If there is no feature list currently present, force one to generate.
+ if (project_features.is_empty()) {
+ project_features = ProjectSettings::get_required_features();
+ }
+ // Check the rendering API.
+ const String rendering_api = has_setting("rendering/quality/driver/driver_name") ? (String)get_setting("rendering/quality/driver/driver_name") : String();
+ if (!rendering_api.is_empty()) {
+ // Add the rendering API as a project feature if it doesn't already exist.
+ if (!project_features.has(rendering_api)) {
+ project_features.append(rendering_api);
+ }
+ }
+ // Check for the existence of a csproj file.
+ if (FileAccess::exists(get_resource_path().plus_file(get_safe_project_name() + ".csproj"))) {
+ // If there is a csproj file, add the C# feature if it doesn't already exist.
+ if (!project_features.has("C#")) {
+ project_features.append("C#");
+ }
+ } else {
+ // If there isn't a csproj file, remove the C# feature if it exists.
+ if (project_features.has("C#")) {
+ project_features.remove_at(project_features.find("C#"));
+ }
+ }
+ project_features = _trim_to_supported_features(project_features);
+ set_setting("application/config/features", project_features);
Set<_VCSort> vclist;
@@ -1094,7 +1206,7 @@ ProjectSettings::ProjectSettings() {
custom_prop_info["application/run/main_scene"] = PropertyInfo(Variant::STRING, "application/run/main_scene", PROPERTY_HINT_FILE, "*.tscn,*.scn,*.res");
GLOBAL_DEF("application/run/disable_stdout", false);
GLOBAL_DEF("application/run/disable_stderr", false);
- project_data_dir_name = GLOBAL_DEF_RST("application/config/project_data_dir_name", ".godot");
+ GLOBAL_DEF_RST("application/config/use_hidden_project_data_directory", true);
GLOBAL_DEF("application/config/use_custom_user_dir", false);
GLOBAL_DEF("application/config/custom_user_dir_name", "");
GLOBAL_DEF("application/config/project_settings_override", "");
diff --git a/core/config/project_settings.h b/core/config/project_settings.h
index 82f04b94df..5b74356337 100644
--- a/core/config/project_settings.h
+++ b/core/config/project_settings.h
@@ -42,11 +42,14 @@ class ProjectSettings : public Object {
public:
typedef Map<String, Variant> CustomMap;
+ static const String PROJECT_DATA_DIR_NAME_SUFFIX;
enum {
//properties that are not for built in values begin from this value, so builtin ones are displayed first
NO_BUILTIN_ORDER_BASE = 1 << 16
};
+ const static PackedStringArray get_required_features();
+ const static PackedStringArray get_unsupported_features(const PackedStringArray &p_project_features);
struct AutoloadInfo {
StringName name;
@@ -110,13 +113,16 @@ protected:
Error _save_custom_bnd(const String &p_file);
+ const static PackedStringArray _get_supported_features();
+ const static PackedStringArray _trim_to_supported_features(const PackedStringArray &p_project_features);
+
void _convert_to_last_version(int p_from_version);
bool _load_resource_pack(const String &p_pack, bool p_replace_files = true, int p_offset = 0);
void _add_property_info_bind(const Dictionary &p_info);
- Error _setup(const String &p_path, const String &p_main_pack, bool p_upwards = false);
+ Error _setup(const String &p_path, const String &p_main_pack, bool p_upwards = false, bool p_ignore_override = false);
void _add_builtin_input_map();
@@ -124,7 +130,7 @@ protected:
static void _bind_methods();
public:
- static const int CONFIG_VERSION = 4;
+ static const int CONFIG_VERSION = 5;
void set_setting(const String &p_setting, const Variant &p_value);
Variant get_setting(const String &p_setting) const;
@@ -145,6 +151,7 @@ public:
String get_project_data_dir_name() const;
String get_project_data_path() const;
String get_resource_path() const;
+ String get_safe_project_name() const;
String get_imported_files_path() const;
static ProjectSettings *get_singleton();
@@ -155,8 +162,9 @@ public:
void set_builtin_order(const String &p_name);
bool is_builtin_setting(const String &p_name) const;
- Error setup(const String &p_path, const String &p_main_pack, bool p_upwards = false);
+ Error setup(const String &p_path, const String &p_main_pack, bool p_upwards = false, bool p_ignore_override = false);
+ Error load_custom(const String &p_path);
Error save_custom(const String &p_path = "", const CustomMap &p_custom = CustomMap(), const Vector<String> &p_custom_features = Vector<String>(), bool p_merge_with_current = true);
Error save();
void set_custom_property_info(const String &p_prop, const PropertyInfo &p_info);
diff --git a/core/core_bind.cpp b/core/core_bind.cpp
index 3a4fddc670..161008fd35 100644
--- a/core/core_bind.cpp
+++ b/core/core_bind.cpp
@@ -207,6 +207,10 @@ void OS::alert(const String &p_alert, const String &p_title) {
::OS::get_singleton()->alert(p_alert, p_title);
}
+void OS::crash(const String &p_message) {
+ CRASH_NOW_MSG(p_message);
+}
+
String OS::get_executable_path() const {
return ::OS::get_singleton()->get_executable_path();
}
@@ -235,6 +239,19 @@ int OS::execute(const String &p_path, const Vector<String> &p_arguments, Array r
return exitcode;
}
+int OS::create_instance(const Vector<String> &p_arguments) {
+ List<String> args;
+ for (int i = 0; i < p_arguments.size(); i++) {
+ args.push_back(p_arguments[i]);
+ }
+ ::OS::ProcessID pid = 0;
+ Error err = ::OS::get_singleton()->create_instance(args, &pid);
+ if (err != OK) {
+ return -1;
+ }
+ return pid;
+}
+
int OS::create_process(const String &p_path, const Vector<String> &p_arguments) {
List<String> args;
for (int i = 0; i < p_arguments.size(); i++) {
@@ -302,6 +319,10 @@ Error OS::set_thread_name(const String &p_name) {
return ::Thread::get_caller_id();
};
+::Thread::ID OS::get_main_thread_id() const {
+ return ::Thread::get_main_id();
+};
+
bool OS::has_feature(const String &p_feature) const {
return ::OS::get_singleton()->has_feature(p_feature);
}
@@ -489,15 +510,15 @@ String OS::get_system_dir(SystemDir p_dir, bool p_shared_storage) const {
return ::OS::get_singleton()->get_system_dir(::OS::SystemDir(p_dir), p_shared_storage);
}
-String OS::get_keycode_string(uint32_t p_code) const {
+String OS::get_keycode_string(Key p_code) const {
return ::keycode_get_string(p_code);
}
-bool OS::is_keycode_unicode(uint32_t p_unicode) const {
- return ::keycode_has_unicode(p_unicode);
+bool OS::is_keycode_unicode(char32_t p_unicode) const {
+ return ::keycode_has_unicode((Key)p_unicode);
}
-int OS::find_keycode_from_string(const String &p_code) const {
+Key OS::find_keycode_from_string(const String &p_code) const {
return find_keycode(p_code);
}
@@ -525,6 +546,7 @@ void OS::_bind_methods() {
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("crash", "message"), &OS::crash);
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);
@@ -537,6 +559,7 @@ void OS::_bind_methods() {
ClassDB::bind_method(D_METHOD("get_executable_path"), &OS::get_executable_path);
ClassDB::bind_method(D_METHOD("execute", "path", "arguments", "output", "read_stderr"), &OS::execute, DEFVAL(Array()), DEFVAL(false));
ClassDB::bind_method(D_METHOD("create_process", "path", "arguments"), &OS::create_process);
+ ClassDB::bind_method(D_METHOD("create_instance", "arguments"), &OS::create_instance);
ClassDB::bind_method(D_METHOD("kill", "pid"), &OS::kill);
ClassDB::bind_method(D_METHOD("shell_open", "uri"), &OS::shell_open);
ClassDB::bind_method(D_METHOD("get_process_id"), &OS::get_process_id);
@@ -587,6 +610,7 @@ void OS::_bind_methods() {
ClassDB::bind_method(D_METHOD("set_thread_name", "name"), &OS::set_thread_name);
ClassDB::bind_method(D_METHOD("get_thread_caller_id"), &OS::get_thread_caller_id);
+ ClassDB::bind_method(D_METHOD("get_main_thread_id"), &OS::get_main_thread_id);
ClassDB::bind_method(D_METHOD("has_feature", "tag_name"), &OS::has_feature);
@@ -603,8 +627,8 @@ void OS::_bind_methods() {
ADD_PROPERTY_DEFAULT("low_processor_usage_mode", false);
ADD_PROPERTY_DEFAULT("low_processor_usage_mode_sleep_usec", 6900);
- BIND_ENUM_CONSTANT(VIDEO_DRIVER_GLES2);
BIND_ENUM_CONSTANT(VIDEO_DRIVER_VULKAN);
+ BIND_ENUM_CONSTANT(VIDEO_DRIVER_OPENGL_3);
BIND_ENUM_CONSTANT(DAY_SUNDAY);
BIND_ENUM_CONSTANT(DAY_MONDAY);
@@ -1459,7 +1483,7 @@ String Directory::get_next() {
ERR_FAIL_COND_V_MSG(!is_open(), "", "Directory must be opened before use.");
String next = d->get_next();
- while (next != "" && ((_list_skip_navigational && (next == "." || next == "..")) || (_list_skip_hidden && d->current_is_hidden()))) {
+ while (!next.is_empty() && ((_list_skip_navigational && (next == "." || next == "..")) || (_list_skip_hidden && d->current_is_hidden()))) {
next = d->get_next();
}
return next;
@@ -1641,7 +1665,7 @@ String Marshalls::variant_to_base64(const Variant &p_var, bool p_full_objects) {
ERR_FAIL_COND_V_MSG(err != OK, "", "Error when trying to encode Variant.");
String ret = CryptoCore::b64_encode_str(&w[0], len);
- ERR_FAIL_COND_V(ret == "", ret);
+ ERR_FAIL_COND_V(ret.is_empty(), ret);
return ret;
}
@@ -1666,7 +1690,7 @@ Variant Marshalls::base64_to_variant(const String &p_str, bool p_allow_objects)
String Marshalls::raw_to_base64(const Vector<uint8_t> &p_arr) {
String ret = CryptoCore::b64_encode_str(p_arr.ptr(), p_arr.size());
- ERR_FAIL_COND_V(ret == "", ret);
+ ERR_FAIL_COND_V(ret.is_empty(), ret);
return ret;
}
@@ -1690,7 +1714,7 @@ Vector<uint8_t> Marshalls::base64_to_raw(const String &p_str) {
String Marshalls::utf8_to_base64(const String &p_str) {
CharString cstr = p_str.utf8();
String ret = CryptoCore::b64_encode_str((unsigned char *)cstr.get_data(), cstr.length());
- ERR_FAIL_COND_V(ret == "", ret);
+ ERR_FAIL_COND_V(ret.is_empty(), ret);
return ret;
}
diff --git a/core/core_bind.h b/core/core_bind.h
index 4eab085dda..920f2b539b 100644
--- a/core/core_bind.h
+++ b/core/core_bind.h
@@ -119,8 +119,8 @@ protected:
public:
enum VideoDriver {
- VIDEO_DRIVER_GLES2,
VIDEO_DRIVER_VULKAN,
+ VIDEO_DRIVER_OPENGL_3,
};
enum Weekday {
@@ -161,10 +161,12 @@ public:
int get_low_processor_usage_mode_sleep_usec() const;
void alert(const String &p_alert, const String &p_title = "ALERT!");
+ void crash(const String &p_message);
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);
+ int create_instance(const Vector<String> &p_arguments);
Error kill(int p_pid);
Error shell_open(String p_uri);
@@ -194,9 +196,9 @@ public:
String get_unique_id() const;
- String get_keycode_string(uint32_t p_code) const;
- bool is_keycode_unicode(uint32_t p_unicode) const;
- int find_keycode_from_string(const String &p_code) const;
+ String get_keycode_string(Key p_code) const;
+ bool is_keycode_unicode(char32_t p_unicode) const;
+ Key find_keycode_from_string(const String &p_code) const;
void set_use_file_access_save_and_swap(bool p_enable);
@@ -205,7 +207,7 @@ public:
void delay_usec(int p_usec) const;
void delay_msec(int p_msec) const;
- uint32_t get_ticks_msec() const;
+ uint64_t get_ticks_msec() const;
uint64_t get_ticks_usec() const;
bool can_use_threads() const;
@@ -236,6 +238,7 @@ public:
Error set_thread_name(const String &p_name);
Thread::ID get_thread_caller_id() const;
+ Thread::ID get_main_thread_id() const;
bool has_feature(const String &p_feature) const;
diff --git a/core/core_builders.py b/core/core_builders.py
index 004475faa7..b07daa80ae 100644
--- a/core/core_builders.py
+++ b/core/core_builders.py
@@ -35,7 +35,9 @@ def make_certs_header(target, source, env):
decomp_size = len(buf)
import zlib
- buf = zlib.compress(buf)
+ # Use maximum zlib compression level to further reduce file size
+ # (at the cost of initial build times).
+ buf = zlib.compress(buf, zlib.Z_BEST_COMPRESSION)
g.write("/* THIS FILE IS GENERATED DO NOT EDIT */\n")
g.write("#ifndef CERTS_COMPRESSED_GEN_H\n")
diff --git a/core/core_constants.cpp b/core/core_constants.cpp
index b2d5a8fdf1..51fcfd5305 100644
--- a/core/core_constants.cpp
+++ b/core/core_constants.cpp
@@ -71,6 +71,16 @@ static Vector<_CoreConstant> _global_constants;
#define BIND_CORE_ENUM_CONSTANT(m_constant) \
_global_constants.push_back(_CoreConstant(__constant_get_enum_name(m_constant, #m_constant), #m_constant, m_constant));
+// This just binds enum classes as if they were regular enum constants.
+#define BIND_CORE_ENUM_CLASS_CONSTANT(m_enum, m_prefix, m_member) \
+ _global_constants.push_back(_CoreConstant(__constant_get_enum_name(m_enum::m_member, #m_prefix "_" #m_member), #m_prefix "_" #m_member, (int)m_enum::m_member));
+
+#define BIND_CORE_ENUM_CLASS_CONSTANT_CUSTOM(m_enum, m_name, m_member) \
+ _global_constants.push_back(_CoreConstant(__constant_get_enum_name(m_enum::m_member, #m_name), #m_name, (int)m_enum::m_member));
+
+#define BIND_CORE_ENUM_CLASS_CONSTANT_NO_VAL(m_enum, m_prefix, m_member) \
+ _global_constants.push_back(_CoreConstant(__constant_get_enum_name(m_enum::m_member, #m_prefix "_" #m_member), #m_prefix "_" #m_member, (int)m_enum::m_member, true));
+
#define BIND_CORE_ENUM_CONSTANT_CUSTOM(m_custom_name, m_constant) \
_global_constants.push_back(_CoreConstant(__constant_get_enum_name(m_constant, #m_constant), m_custom_name, m_constant));
@@ -91,6 +101,16 @@ static Vector<_CoreConstant> _global_constants;
#define BIND_CORE_ENUM_CONSTANT(m_constant) \
_global_constants.push_back(_CoreConstant(#m_constant, m_constant));
+// This just binds enum classes as if they were regular enum constants.
+#define BIND_CORE_ENUM_CLASS_CONSTANT(m_enum, m_prefix, m_member) \
+ _global_constants.push_back(_CoreConstant(#m_prefix "_" #m_member, (int)m_enum::m_member));
+
+#define BIND_CORE_ENUM_CLASS_CONSTANT_CUSTOM(m_enum, m_name, m_member) \
+ _global_constants.push_back(_CoreConstant(#m_name, (int)m_enum::m_member));
+
+#define BIND_CORE_ENUM_CLASS_CONSTANT_NO_VAL(m_enum, m_prefix, m_member) \
+ _global_constants.push_back(_CoreConstant(#m_prefix "_" #m_member, (int)m_enum::m_member));
+
#define BIND_CORE_ENUM_CONSTANT_CUSTOM(m_custom_name, m_constant) \
_global_constants.push_back(_CoreConstant(m_custom_name, m_constant));
@@ -122,348 +142,340 @@ void register_global_constants() {
BIND_CORE_ENUM_CONSTANT(CLOCKWISE);
BIND_CORE_ENUM_CONSTANT(COUNTERCLOCKWISE);
- BIND_CORE_ENUM_CONSTANT(HALIGN_LEFT);
- BIND_CORE_ENUM_CONSTANT(HALIGN_CENTER);
- BIND_CORE_ENUM_CONSTANT(HALIGN_RIGHT);
- BIND_CORE_ENUM_CONSTANT(HALIGN_FILL);
-
- BIND_CORE_ENUM_CONSTANT(VALIGN_TOP);
- BIND_CORE_ENUM_CONSTANT(VALIGN_CENTER);
- BIND_CORE_ENUM_CONSTANT(VALIGN_BOTTOM);
-
- BIND_CORE_ENUM_CONSTANT(INLINE_ALIGN_TOP_TO);
- BIND_CORE_ENUM_CONSTANT(INLINE_ALIGN_CENTER_TO);
- BIND_CORE_ENUM_CONSTANT(INLINE_ALIGN_BOTTOM_TO);
-
- BIND_CORE_ENUM_CONSTANT(INLINE_ALIGN_TO_TOP);
- BIND_CORE_ENUM_CONSTANT(INLINE_ALIGN_TO_CENTER);
- BIND_CORE_ENUM_CONSTANT(INLINE_ALIGN_TO_BASELINE);
- BIND_CORE_ENUM_CONSTANT(INLINE_ALIGN_TO_BOTTOM);
-
- BIND_CORE_ENUM_CONSTANT(INLINE_ALIGN_TOP);
- BIND_CORE_ENUM_CONSTANT(INLINE_ALIGN_CENTER);
- BIND_CORE_ENUM_CONSTANT(INLINE_ALIGN_BOTTOM);
-
- // huge list of keys
- BIND_CORE_CONSTANT(SPKEY);
-
- BIND_CORE_ENUM_CONSTANT(KEY_ESCAPE);
- BIND_CORE_ENUM_CONSTANT(KEY_TAB);
- BIND_CORE_ENUM_CONSTANT(KEY_BACKTAB);
- BIND_CORE_ENUM_CONSTANT(KEY_BACKSPACE);
- BIND_CORE_ENUM_CONSTANT(KEY_ENTER);
- BIND_CORE_ENUM_CONSTANT(KEY_KP_ENTER);
- BIND_CORE_ENUM_CONSTANT(KEY_INSERT);
- BIND_CORE_ENUM_CONSTANT(KEY_DELETE);
- BIND_CORE_ENUM_CONSTANT(KEY_PAUSE);
- BIND_CORE_ENUM_CONSTANT(KEY_PRINT);
- BIND_CORE_ENUM_CONSTANT(KEY_SYSREQ);
- BIND_CORE_ENUM_CONSTANT(KEY_CLEAR);
- BIND_CORE_ENUM_CONSTANT(KEY_HOME);
- BIND_CORE_ENUM_CONSTANT(KEY_END);
- BIND_CORE_ENUM_CONSTANT(KEY_LEFT);
- BIND_CORE_ENUM_CONSTANT(KEY_UP);
- BIND_CORE_ENUM_CONSTANT(KEY_RIGHT);
- BIND_CORE_ENUM_CONSTANT(KEY_DOWN);
- BIND_CORE_ENUM_CONSTANT(KEY_PAGEUP);
- BIND_CORE_ENUM_CONSTANT(KEY_PAGEDOWN);
- BIND_CORE_ENUM_CONSTANT(KEY_SHIFT);
- BIND_CORE_ENUM_CONSTANT(KEY_CTRL);
- BIND_CORE_ENUM_CONSTANT(KEY_META);
- BIND_CORE_ENUM_CONSTANT(KEY_ALT);
- BIND_CORE_ENUM_CONSTANT(KEY_CAPSLOCK);
- BIND_CORE_ENUM_CONSTANT(KEY_NUMLOCK);
- BIND_CORE_ENUM_CONSTANT(KEY_SCROLLLOCK);
- BIND_CORE_ENUM_CONSTANT(KEY_F1);
- BIND_CORE_ENUM_CONSTANT(KEY_F2);
- BIND_CORE_ENUM_CONSTANT(KEY_F3);
- BIND_CORE_ENUM_CONSTANT(KEY_F4);
- BIND_CORE_ENUM_CONSTANT(KEY_F5);
- BIND_CORE_ENUM_CONSTANT(KEY_F6);
- BIND_CORE_ENUM_CONSTANT(KEY_F7);
- BIND_CORE_ENUM_CONSTANT(KEY_F8);
- BIND_CORE_ENUM_CONSTANT(KEY_F9);
- BIND_CORE_ENUM_CONSTANT(KEY_F10);
- BIND_CORE_ENUM_CONSTANT(KEY_F11);
- BIND_CORE_ENUM_CONSTANT(KEY_F12);
- BIND_CORE_ENUM_CONSTANT(KEY_F13);
- BIND_CORE_ENUM_CONSTANT(KEY_F14);
- BIND_CORE_ENUM_CONSTANT(KEY_F15);
- BIND_CORE_ENUM_CONSTANT(KEY_F16);
- BIND_CORE_ENUM_CONSTANT(KEY_KP_MULTIPLY);
- BIND_CORE_ENUM_CONSTANT(KEY_KP_DIVIDE);
- BIND_CORE_ENUM_CONSTANT(KEY_KP_SUBTRACT);
- BIND_CORE_ENUM_CONSTANT(KEY_KP_PERIOD);
- BIND_CORE_ENUM_CONSTANT(KEY_KP_ADD);
- BIND_CORE_ENUM_CONSTANT(KEY_KP_0);
- BIND_CORE_ENUM_CONSTANT(KEY_KP_1);
- BIND_CORE_ENUM_CONSTANT(KEY_KP_2);
- BIND_CORE_ENUM_CONSTANT(KEY_KP_3);
- BIND_CORE_ENUM_CONSTANT(KEY_KP_4);
- BIND_CORE_ENUM_CONSTANT(KEY_KP_5);
- BIND_CORE_ENUM_CONSTANT(KEY_KP_6);
- BIND_CORE_ENUM_CONSTANT(KEY_KP_7);
- BIND_CORE_ENUM_CONSTANT(KEY_KP_8);
- BIND_CORE_ENUM_CONSTANT(KEY_KP_9);
- BIND_CORE_ENUM_CONSTANT(KEY_SUPER_L);
- BIND_CORE_ENUM_CONSTANT(KEY_SUPER_R);
- BIND_CORE_ENUM_CONSTANT(KEY_MENU);
- BIND_CORE_ENUM_CONSTANT(KEY_HYPER_L);
- BIND_CORE_ENUM_CONSTANT(KEY_HYPER_R);
- BIND_CORE_ENUM_CONSTANT(KEY_HELP);
- BIND_CORE_ENUM_CONSTANT(KEY_DIRECTION_L);
- BIND_CORE_ENUM_CONSTANT(KEY_DIRECTION_R);
- BIND_CORE_ENUM_CONSTANT(KEY_BACK);
- BIND_CORE_ENUM_CONSTANT(KEY_FORWARD);
- BIND_CORE_ENUM_CONSTANT(KEY_STOP);
- BIND_CORE_ENUM_CONSTANT(KEY_REFRESH);
- BIND_CORE_ENUM_CONSTANT(KEY_VOLUMEDOWN);
- BIND_CORE_ENUM_CONSTANT(KEY_VOLUMEMUTE);
- BIND_CORE_ENUM_CONSTANT(KEY_VOLUMEUP);
- BIND_CORE_ENUM_CONSTANT(KEY_BASSBOOST);
- BIND_CORE_ENUM_CONSTANT(KEY_BASSUP);
- BIND_CORE_ENUM_CONSTANT(KEY_BASSDOWN);
- BIND_CORE_ENUM_CONSTANT(KEY_TREBLEUP);
- BIND_CORE_ENUM_CONSTANT(KEY_TREBLEDOWN);
- BIND_CORE_ENUM_CONSTANT(KEY_MEDIAPLAY);
- BIND_CORE_ENUM_CONSTANT(KEY_MEDIASTOP);
- BIND_CORE_ENUM_CONSTANT(KEY_MEDIAPREVIOUS);
- BIND_CORE_ENUM_CONSTANT(KEY_MEDIANEXT);
- BIND_CORE_ENUM_CONSTANT(KEY_MEDIARECORD);
- BIND_CORE_ENUM_CONSTANT(KEY_HOMEPAGE);
- BIND_CORE_ENUM_CONSTANT(KEY_FAVORITES);
- BIND_CORE_ENUM_CONSTANT(KEY_SEARCH);
- BIND_CORE_ENUM_CONSTANT(KEY_STANDBY);
- BIND_CORE_ENUM_CONSTANT(KEY_OPENURL);
- BIND_CORE_ENUM_CONSTANT(KEY_LAUNCHMAIL);
- BIND_CORE_ENUM_CONSTANT(KEY_LAUNCHMEDIA);
- BIND_CORE_ENUM_CONSTANT(KEY_LAUNCH0);
- BIND_CORE_ENUM_CONSTANT(KEY_LAUNCH1);
- BIND_CORE_ENUM_CONSTANT(KEY_LAUNCH2);
- BIND_CORE_ENUM_CONSTANT(KEY_LAUNCH3);
- BIND_CORE_ENUM_CONSTANT(KEY_LAUNCH4);
- BIND_CORE_ENUM_CONSTANT(KEY_LAUNCH5);
- BIND_CORE_ENUM_CONSTANT(KEY_LAUNCH6);
- BIND_CORE_ENUM_CONSTANT(KEY_LAUNCH7);
- BIND_CORE_ENUM_CONSTANT(KEY_LAUNCH8);
- BIND_CORE_ENUM_CONSTANT(KEY_LAUNCH9);
- BIND_CORE_ENUM_CONSTANT(KEY_LAUNCHA);
- BIND_CORE_ENUM_CONSTANT(KEY_LAUNCHB);
- BIND_CORE_ENUM_CONSTANT(KEY_LAUNCHC);
- BIND_CORE_ENUM_CONSTANT(KEY_LAUNCHD);
- BIND_CORE_ENUM_CONSTANT(KEY_LAUNCHE);
- BIND_CORE_ENUM_CONSTANT(KEY_LAUNCHF);
-
- BIND_CORE_ENUM_CONSTANT(KEY_UNKNOWN);
- BIND_CORE_ENUM_CONSTANT(KEY_SPACE);
- BIND_CORE_ENUM_CONSTANT(KEY_EXCLAM);
- BIND_CORE_ENUM_CONSTANT(KEY_QUOTEDBL);
- BIND_CORE_ENUM_CONSTANT(KEY_NUMBERSIGN);
- BIND_CORE_ENUM_CONSTANT(KEY_DOLLAR);
- BIND_CORE_ENUM_CONSTANT(KEY_PERCENT);
- BIND_CORE_ENUM_CONSTANT(KEY_AMPERSAND);
- BIND_CORE_ENUM_CONSTANT(KEY_APOSTROPHE);
- BIND_CORE_ENUM_CONSTANT(KEY_PARENLEFT);
- BIND_CORE_ENUM_CONSTANT(KEY_PARENRIGHT);
- BIND_CORE_ENUM_CONSTANT(KEY_ASTERISK);
- BIND_CORE_ENUM_CONSTANT(KEY_PLUS);
- BIND_CORE_ENUM_CONSTANT(KEY_COMMA);
- BIND_CORE_ENUM_CONSTANT(KEY_MINUS);
- BIND_CORE_ENUM_CONSTANT(KEY_PERIOD);
- BIND_CORE_ENUM_CONSTANT(KEY_SLASH);
- BIND_CORE_ENUM_CONSTANT(KEY_0);
- BIND_CORE_ENUM_CONSTANT(KEY_1);
- BIND_CORE_ENUM_CONSTANT(KEY_2);
- BIND_CORE_ENUM_CONSTANT(KEY_3);
- BIND_CORE_ENUM_CONSTANT(KEY_4);
- BIND_CORE_ENUM_CONSTANT(KEY_5);
- BIND_CORE_ENUM_CONSTANT(KEY_6);
- BIND_CORE_ENUM_CONSTANT(KEY_7);
- BIND_CORE_ENUM_CONSTANT(KEY_8);
- BIND_CORE_ENUM_CONSTANT(KEY_9);
- BIND_CORE_ENUM_CONSTANT(KEY_COLON);
- BIND_CORE_ENUM_CONSTANT(KEY_SEMICOLON);
- BIND_CORE_ENUM_CONSTANT(KEY_LESS);
- BIND_CORE_ENUM_CONSTANT(KEY_EQUAL);
- BIND_CORE_ENUM_CONSTANT(KEY_GREATER);
- BIND_CORE_ENUM_CONSTANT(KEY_QUESTION);
- BIND_CORE_ENUM_CONSTANT(KEY_AT);
- BIND_CORE_ENUM_CONSTANT(KEY_A);
- BIND_CORE_ENUM_CONSTANT(KEY_B);
- BIND_CORE_ENUM_CONSTANT(KEY_C);
- BIND_CORE_ENUM_CONSTANT(KEY_D);
- BIND_CORE_ENUM_CONSTANT(KEY_E);
- BIND_CORE_ENUM_CONSTANT(KEY_F);
- BIND_CORE_ENUM_CONSTANT(KEY_G);
- BIND_CORE_ENUM_CONSTANT(KEY_H);
- BIND_CORE_ENUM_CONSTANT(KEY_I);
- BIND_CORE_ENUM_CONSTANT(KEY_J);
- BIND_CORE_ENUM_CONSTANT(KEY_K);
- BIND_CORE_ENUM_CONSTANT(KEY_L);
- BIND_CORE_ENUM_CONSTANT(KEY_M);
- BIND_CORE_ENUM_CONSTANT(KEY_N);
- BIND_CORE_ENUM_CONSTANT(KEY_O);
- BIND_CORE_ENUM_CONSTANT(KEY_P);
- BIND_CORE_ENUM_CONSTANT(KEY_Q);
- BIND_CORE_ENUM_CONSTANT(KEY_R);
- BIND_CORE_ENUM_CONSTANT(KEY_S);
- BIND_CORE_ENUM_CONSTANT(KEY_T);
- BIND_CORE_ENUM_CONSTANT(KEY_U);
- BIND_CORE_ENUM_CONSTANT(KEY_V);
- BIND_CORE_ENUM_CONSTANT(KEY_W);
- BIND_CORE_ENUM_CONSTANT(KEY_X);
- BIND_CORE_ENUM_CONSTANT(KEY_Y);
- BIND_CORE_ENUM_CONSTANT(KEY_Z);
- BIND_CORE_ENUM_CONSTANT(KEY_BRACKETLEFT);
- BIND_CORE_ENUM_CONSTANT(KEY_BACKSLASH);
- BIND_CORE_ENUM_CONSTANT(KEY_BRACKETRIGHT);
- BIND_CORE_ENUM_CONSTANT(KEY_ASCIICIRCUM);
- BIND_CORE_ENUM_CONSTANT(KEY_UNDERSCORE);
- BIND_CORE_ENUM_CONSTANT(KEY_QUOTELEFT);
- BIND_CORE_ENUM_CONSTANT(KEY_BRACELEFT);
- BIND_CORE_ENUM_CONSTANT(KEY_BAR);
- BIND_CORE_ENUM_CONSTANT(KEY_BRACERIGHT);
- BIND_CORE_ENUM_CONSTANT(KEY_ASCIITILDE);
- BIND_CORE_ENUM_CONSTANT(KEY_NOBREAKSPACE);
- BIND_CORE_ENUM_CONSTANT(KEY_EXCLAMDOWN);
- BIND_CORE_ENUM_CONSTANT(KEY_CENT);
- BIND_CORE_ENUM_CONSTANT(KEY_STERLING);
- BIND_CORE_ENUM_CONSTANT(KEY_CURRENCY);
- BIND_CORE_ENUM_CONSTANT(KEY_YEN);
- BIND_CORE_ENUM_CONSTANT(KEY_BROKENBAR);
- BIND_CORE_ENUM_CONSTANT(KEY_SECTION);
- BIND_CORE_ENUM_CONSTANT(KEY_DIAERESIS);
- BIND_CORE_ENUM_CONSTANT(KEY_COPYRIGHT);
- BIND_CORE_ENUM_CONSTANT(KEY_ORDFEMININE);
- BIND_CORE_ENUM_CONSTANT(KEY_GUILLEMOTLEFT);
- BIND_CORE_ENUM_CONSTANT(KEY_NOTSIGN);
- BIND_CORE_ENUM_CONSTANT(KEY_HYPHEN);
- BIND_CORE_ENUM_CONSTANT(KEY_REGISTERED);
- BIND_CORE_ENUM_CONSTANT(KEY_MACRON);
- BIND_CORE_ENUM_CONSTANT(KEY_DEGREE);
- BIND_CORE_ENUM_CONSTANT(KEY_PLUSMINUS);
- BIND_CORE_ENUM_CONSTANT(KEY_TWOSUPERIOR);
- BIND_CORE_ENUM_CONSTANT(KEY_THREESUPERIOR);
- BIND_CORE_ENUM_CONSTANT(KEY_ACUTE);
- BIND_CORE_ENUM_CONSTANT(KEY_MU);
- BIND_CORE_ENUM_CONSTANT(KEY_PARAGRAPH);
- BIND_CORE_ENUM_CONSTANT(KEY_PERIODCENTERED);
- BIND_CORE_ENUM_CONSTANT(KEY_CEDILLA);
- BIND_CORE_ENUM_CONSTANT(KEY_ONESUPERIOR);
- BIND_CORE_ENUM_CONSTANT(KEY_MASCULINE);
- BIND_CORE_ENUM_CONSTANT(KEY_GUILLEMOTRIGHT);
- BIND_CORE_ENUM_CONSTANT(KEY_ONEQUARTER);
- BIND_CORE_ENUM_CONSTANT(KEY_ONEHALF);
- BIND_CORE_ENUM_CONSTANT(KEY_THREEQUARTERS);
- BIND_CORE_ENUM_CONSTANT(KEY_QUESTIONDOWN);
- BIND_CORE_ENUM_CONSTANT(KEY_AGRAVE);
- BIND_CORE_ENUM_CONSTANT(KEY_AACUTE);
- BIND_CORE_ENUM_CONSTANT(KEY_ACIRCUMFLEX);
- BIND_CORE_ENUM_CONSTANT(KEY_ATILDE);
- BIND_CORE_ENUM_CONSTANT(KEY_ADIAERESIS);
- BIND_CORE_ENUM_CONSTANT(KEY_ARING);
- BIND_CORE_ENUM_CONSTANT(KEY_AE);
- BIND_CORE_ENUM_CONSTANT(KEY_CCEDILLA);
- BIND_CORE_ENUM_CONSTANT(KEY_EGRAVE);
- BIND_CORE_ENUM_CONSTANT(KEY_EACUTE);
- BIND_CORE_ENUM_CONSTANT(KEY_ECIRCUMFLEX);
- BIND_CORE_ENUM_CONSTANT(KEY_EDIAERESIS);
- BIND_CORE_ENUM_CONSTANT(KEY_IGRAVE);
- BIND_CORE_ENUM_CONSTANT(KEY_IACUTE);
- BIND_CORE_ENUM_CONSTANT(KEY_ICIRCUMFLEX);
- BIND_CORE_ENUM_CONSTANT(KEY_IDIAERESIS);
- BIND_CORE_ENUM_CONSTANT(KEY_ETH);
- BIND_CORE_ENUM_CONSTANT(KEY_NTILDE);
- BIND_CORE_ENUM_CONSTANT(KEY_OGRAVE);
- BIND_CORE_ENUM_CONSTANT(KEY_OACUTE);
- BIND_CORE_ENUM_CONSTANT(KEY_OCIRCUMFLEX);
- BIND_CORE_ENUM_CONSTANT(KEY_OTILDE);
- BIND_CORE_ENUM_CONSTANT(KEY_ODIAERESIS);
- BIND_CORE_ENUM_CONSTANT(KEY_MULTIPLY);
- BIND_CORE_ENUM_CONSTANT(KEY_OOBLIQUE);
- BIND_CORE_ENUM_CONSTANT(KEY_UGRAVE);
- BIND_CORE_ENUM_CONSTANT(KEY_UACUTE);
- BIND_CORE_ENUM_CONSTANT(KEY_UCIRCUMFLEX);
- BIND_CORE_ENUM_CONSTANT(KEY_UDIAERESIS);
- BIND_CORE_ENUM_CONSTANT(KEY_YACUTE);
- BIND_CORE_ENUM_CONSTANT(KEY_THORN);
- BIND_CORE_ENUM_CONSTANT(KEY_SSHARP);
-
- BIND_CORE_ENUM_CONSTANT(KEY_DIVISION);
- BIND_CORE_ENUM_CONSTANT(KEY_YDIAERESIS);
-
- BIND_CORE_ENUM_CONSTANT(KEY_CODE_MASK);
- BIND_CORE_ENUM_CONSTANT(KEY_MODIFIER_MASK);
-
- BIND_CORE_ENUM_CONSTANT(KEY_MASK_SHIFT);
- BIND_CORE_ENUM_CONSTANT(KEY_MASK_ALT);
- BIND_CORE_ENUM_CONSTANT(KEY_MASK_META);
- BIND_CORE_ENUM_CONSTANT(KEY_MASK_CTRL);
- BIND_CORE_ENUM_CONSTANT_NO_VAL(KEY_MASK_CMD);
- BIND_CORE_ENUM_CONSTANT(KEY_MASK_KPAD);
- BIND_CORE_ENUM_CONSTANT(KEY_MASK_GROUP_SWITCH);
-
- // mouse
- BIND_CORE_ENUM_CONSTANT(MOUSE_BUTTON_LEFT);
- BIND_CORE_ENUM_CONSTANT(MOUSE_BUTTON_RIGHT);
- BIND_CORE_ENUM_CONSTANT(MOUSE_BUTTON_MIDDLE);
- BIND_CORE_ENUM_CONSTANT(MOUSE_BUTTON_XBUTTON1);
- BIND_CORE_ENUM_CONSTANT(MOUSE_BUTTON_XBUTTON2);
- BIND_CORE_ENUM_CONSTANT(MOUSE_BUTTON_WHEEL_UP);
- BIND_CORE_ENUM_CONSTANT(MOUSE_BUTTON_WHEEL_DOWN);
- BIND_CORE_ENUM_CONSTANT(MOUSE_BUTTON_WHEEL_LEFT);
- BIND_CORE_ENUM_CONSTANT(MOUSE_BUTTON_WHEEL_RIGHT);
- BIND_CORE_ENUM_CONSTANT(MOUSE_BUTTON_MASK_LEFT);
- BIND_CORE_ENUM_CONSTANT(MOUSE_BUTTON_MASK_RIGHT);
- BIND_CORE_ENUM_CONSTANT(MOUSE_BUTTON_MASK_MIDDLE);
- BIND_CORE_ENUM_CONSTANT(MOUSE_BUTTON_MASK_XBUTTON1);
- BIND_CORE_ENUM_CONSTANT(MOUSE_BUTTON_MASK_XBUTTON2);
-
- // Joypad buttons
- BIND_CORE_ENUM_CONSTANT(JOY_BUTTON_INVALID);
- BIND_CORE_ENUM_CONSTANT(JOY_BUTTON_A);
- BIND_CORE_ENUM_CONSTANT(JOY_BUTTON_B);
- BIND_CORE_ENUM_CONSTANT(JOY_BUTTON_X);
- BIND_CORE_ENUM_CONSTANT(JOY_BUTTON_Y);
- BIND_CORE_ENUM_CONSTANT(JOY_BUTTON_BACK);
- BIND_CORE_ENUM_CONSTANT(JOY_BUTTON_GUIDE);
- BIND_CORE_ENUM_CONSTANT(JOY_BUTTON_START);
- BIND_CORE_ENUM_CONSTANT(JOY_BUTTON_LEFT_STICK);
- BIND_CORE_ENUM_CONSTANT(JOY_BUTTON_RIGHT_STICK);
- BIND_CORE_ENUM_CONSTANT(JOY_BUTTON_LEFT_SHOULDER);
- BIND_CORE_ENUM_CONSTANT(JOY_BUTTON_RIGHT_SHOULDER);
- BIND_CORE_ENUM_CONSTANT(JOY_BUTTON_DPAD_UP);
- BIND_CORE_ENUM_CONSTANT(JOY_BUTTON_DPAD_DOWN);
- BIND_CORE_ENUM_CONSTANT(JOY_BUTTON_DPAD_LEFT);
- BIND_CORE_ENUM_CONSTANT(JOY_BUTTON_DPAD_RIGHT);
- BIND_CORE_ENUM_CONSTANT(JOY_BUTTON_MISC1);
- BIND_CORE_ENUM_CONSTANT(JOY_BUTTON_PADDLE1);
- BIND_CORE_ENUM_CONSTANT(JOY_BUTTON_PADDLE2);
- BIND_CORE_ENUM_CONSTANT(JOY_BUTTON_PADDLE3);
- BIND_CORE_ENUM_CONSTANT(JOY_BUTTON_PADDLE4);
- BIND_CORE_ENUM_CONSTANT(JOY_BUTTON_TOUCHPAD);
- BIND_CORE_ENUM_CONSTANT(JOY_BUTTON_SDL_MAX);
- BIND_CORE_ENUM_CONSTANT(JOY_BUTTON_MAX);
-
- // Joypad axes
- BIND_CORE_ENUM_CONSTANT(JOY_AXIS_INVALID);
- BIND_CORE_ENUM_CONSTANT(JOY_AXIS_LEFT_X);
- BIND_CORE_ENUM_CONSTANT(JOY_AXIS_LEFT_Y);
- BIND_CORE_ENUM_CONSTANT(JOY_AXIS_RIGHT_X);
- BIND_CORE_ENUM_CONSTANT(JOY_AXIS_RIGHT_Y);
- BIND_CORE_ENUM_CONSTANT(JOY_AXIS_TRIGGER_LEFT);
- BIND_CORE_ENUM_CONSTANT(JOY_AXIS_TRIGGER_RIGHT);
- BIND_CORE_ENUM_CONSTANT(JOY_AXIS_SDL_MAX);
- BIND_CORE_ENUM_CONSTANT(JOY_AXIS_MAX);
-
- // midi
- BIND_CORE_ENUM_CONSTANT(MIDI_MESSAGE_NOTE_OFF);
- BIND_CORE_ENUM_CONSTANT(MIDI_MESSAGE_NOTE_ON);
- BIND_CORE_ENUM_CONSTANT(MIDI_MESSAGE_AFTERTOUCH);
- BIND_CORE_ENUM_CONSTANT(MIDI_MESSAGE_CONTROL_CHANGE);
- BIND_CORE_ENUM_CONSTANT(MIDI_MESSAGE_PROGRAM_CHANGE);
- BIND_CORE_ENUM_CONSTANT(MIDI_MESSAGE_CHANNEL_PRESSURE);
- BIND_CORE_ENUM_CONSTANT(MIDI_MESSAGE_PITCH_BEND);
+ BIND_CORE_ENUM_CONSTANT(HORIZONTAL_ALIGNMENT_LEFT);
+ BIND_CORE_ENUM_CONSTANT(HORIZONTAL_ALIGNMENT_CENTER);
+ BIND_CORE_ENUM_CONSTANT(HORIZONTAL_ALIGNMENT_RIGHT);
+ BIND_CORE_ENUM_CONSTANT(HORIZONTAL_ALIGNMENT_FILL);
+
+ BIND_CORE_ENUM_CONSTANT(VERTICAL_ALIGNMENT_TOP);
+ BIND_CORE_ENUM_CONSTANT(VERTICAL_ALIGNMENT_CENTER);
+ BIND_CORE_ENUM_CONSTANT(VERTICAL_ALIGNMENT_BOTTOM);
+ BIND_CORE_ENUM_CONSTANT(VERTICAL_ALIGNMENT_FILL);
+
+ BIND_CORE_ENUM_CONSTANT(INLINE_ALIGNMENT_TOP_TO);
+ BIND_CORE_ENUM_CONSTANT(INLINE_ALIGNMENT_CENTER_TO);
+ BIND_CORE_ENUM_CONSTANT(INLINE_ALIGNMENT_BOTTOM_TO);
+
+ BIND_CORE_ENUM_CONSTANT(INLINE_ALIGNMENT_TO_TOP);
+ BIND_CORE_ENUM_CONSTANT(INLINE_ALIGNMENT_TO_CENTER);
+ BIND_CORE_ENUM_CONSTANT(INLINE_ALIGNMENT_TO_BASELINE);
+ BIND_CORE_ENUM_CONSTANT(INLINE_ALIGNMENT_TO_BOTTOM);
+
+ BIND_CORE_ENUM_CONSTANT(INLINE_ALIGNMENT_TOP);
+ BIND_CORE_ENUM_CONSTANT(INLINE_ALIGNMENT_CENTER);
+ BIND_CORE_ENUM_CONSTANT(INLINE_ALIGNMENT_BOTTOM);
+
+ BIND_CORE_ENUM_CLASS_CONSTANT(Key, KEY, SPECIAL);
+ BIND_CORE_ENUM_CLASS_CONSTANT(Key, KEY, ESCAPE);
+ BIND_CORE_ENUM_CLASS_CONSTANT(Key, KEY, TAB);
+ BIND_CORE_ENUM_CLASS_CONSTANT(Key, KEY, BACKTAB);
+ BIND_CORE_ENUM_CLASS_CONSTANT(Key, KEY, BACKSPACE);
+ BIND_CORE_ENUM_CLASS_CONSTANT(Key, KEY, ENTER);
+ BIND_CORE_ENUM_CLASS_CONSTANT(Key, KEY, KP_ENTER);
+ BIND_CORE_ENUM_CLASS_CONSTANT(Key, KEY, INSERT);
+ BIND_CORE_ENUM_CLASS_CONSTANT_CUSTOM(Key, KEY_DELETE, KEY_DELETE);
+ BIND_CORE_ENUM_CLASS_CONSTANT(Key, KEY, PAUSE);
+ BIND_CORE_ENUM_CLASS_CONSTANT(Key, KEY, PRINT);
+ BIND_CORE_ENUM_CLASS_CONSTANT(Key, KEY, SYSREQ);
+ BIND_CORE_ENUM_CLASS_CONSTANT(Key, KEY, CLEAR);
+ BIND_CORE_ENUM_CLASS_CONSTANT(Key, KEY, HOME);
+ BIND_CORE_ENUM_CLASS_CONSTANT(Key, KEY, END);
+ BIND_CORE_ENUM_CLASS_CONSTANT(Key, KEY, LEFT);
+ BIND_CORE_ENUM_CLASS_CONSTANT(Key, KEY, UP);
+ BIND_CORE_ENUM_CLASS_CONSTANT(Key, KEY, RIGHT);
+ BIND_CORE_ENUM_CLASS_CONSTANT(Key, KEY, DOWN);
+ BIND_CORE_ENUM_CLASS_CONSTANT(Key, KEY, PAGEUP);
+ BIND_CORE_ENUM_CLASS_CONSTANT(Key, KEY, PAGEDOWN);
+ BIND_CORE_ENUM_CLASS_CONSTANT(Key, KEY, SHIFT);
+ BIND_CORE_ENUM_CLASS_CONSTANT(Key, KEY, CTRL);
+ BIND_CORE_ENUM_CLASS_CONSTANT(Key, KEY, META);
+ BIND_CORE_ENUM_CLASS_CONSTANT(Key, KEY, ALT);
+ BIND_CORE_ENUM_CLASS_CONSTANT(Key, KEY, CAPSLOCK);
+ BIND_CORE_ENUM_CLASS_CONSTANT(Key, KEY, NUMLOCK);
+ BIND_CORE_ENUM_CLASS_CONSTANT(Key, KEY, SCROLLLOCK);
+ BIND_CORE_ENUM_CLASS_CONSTANT(Key, KEY, F1);
+ BIND_CORE_ENUM_CLASS_CONSTANT(Key, KEY, F2);
+ BIND_CORE_ENUM_CLASS_CONSTANT(Key, KEY, F3);
+ BIND_CORE_ENUM_CLASS_CONSTANT(Key, KEY, F4);
+ BIND_CORE_ENUM_CLASS_CONSTANT(Key, KEY, F5);
+ BIND_CORE_ENUM_CLASS_CONSTANT(Key, KEY, F6);
+ BIND_CORE_ENUM_CLASS_CONSTANT(Key, KEY, F7);
+ BIND_CORE_ENUM_CLASS_CONSTANT(Key, KEY, F8);
+ BIND_CORE_ENUM_CLASS_CONSTANT(Key, KEY, F9);
+ BIND_CORE_ENUM_CLASS_CONSTANT(Key, KEY, F10);
+ BIND_CORE_ENUM_CLASS_CONSTANT(Key, KEY, F11);
+ BIND_CORE_ENUM_CLASS_CONSTANT(Key, KEY, F12);
+ BIND_CORE_ENUM_CLASS_CONSTANT(Key, KEY, F13);
+ BIND_CORE_ENUM_CLASS_CONSTANT(Key, KEY, F14);
+ BIND_CORE_ENUM_CLASS_CONSTANT(Key, KEY, F15);
+ BIND_CORE_ENUM_CLASS_CONSTANT(Key, KEY, F16);
+ BIND_CORE_ENUM_CLASS_CONSTANT(Key, KEY, KP_MULTIPLY);
+ BIND_CORE_ENUM_CLASS_CONSTANT(Key, KEY, KP_DIVIDE);
+ BIND_CORE_ENUM_CLASS_CONSTANT(Key, KEY, KP_SUBTRACT);
+ BIND_CORE_ENUM_CLASS_CONSTANT(Key, KEY, KP_PERIOD);
+ BIND_CORE_ENUM_CLASS_CONSTANT(Key, KEY, KP_ADD);
+ BIND_CORE_ENUM_CLASS_CONSTANT(Key, KEY, KP_0);
+ BIND_CORE_ENUM_CLASS_CONSTANT(Key, KEY, KP_1);
+ BIND_CORE_ENUM_CLASS_CONSTANT(Key, KEY, KP_2);
+ BIND_CORE_ENUM_CLASS_CONSTANT(Key, KEY, KP_3);
+ BIND_CORE_ENUM_CLASS_CONSTANT(Key, KEY, KP_4);
+ BIND_CORE_ENUM_CLASS_CONSTANT(Key, KEY, KP_5);
+ BIND_CORE_ENUM_CLASS_CONSTANT(Key, KEY, KP_6);
+ BIND_CORE_ENUM_CLASS_CONSTANT(Key, KEY, KP_7);
+ BIND_CORE_ENUM_CLASS_CONSTANT(Key, KEY, KP_8);
+ BIND_CORE_ENUM_CLASS_CONSTANT(Key, KEY, KP_9);
+ BIND_CORE_ENUM_CLASS_CONSTANT(Key, KEY, SUPER_L);
+ BIND_CORE_ENUM_CLASS_CONSTANT(Key, KEY, SUPER_R);
+ BIND_CORE_ENUM_CLASS_CONSTANT(Key, KEY, MENU);
+ BIND_CORE_ENUM_CLASS_CONSTANT(Key, KEY, HYPER_L);
+ BIND_CORE_ENUM_CLASS_CONSTANT(Key, KEY, HYPER_R);
+ BIND_CORE_ENUM_CLASS_CONSTANT(Key, KEY, HELP);
+ BIND_CORE_ENUM_CLASS_CONSTANT(Key, KEY, DIRECTION_L);
+ BIND_CORE_ENUM_CLASS_CONSTANT(Key, KEY, DIRECTION_R);
+ BIND_CORE_ENUM_CLASS_CONSTANT(Key, KEY, BACK);
+ BIND_CORE_ENUM_CLASS_CONSTANT(Key, KEY, FORWARD);
+ BIND_CORE_ENUM_CLASS_CONSTANT(Key, KEY, STOP);
+ BIND_CORE_ENUM_CLASS_CONSTANT(Key, KEY, REFRESH);
+ BIND_CORE_ENUM_CLASS_CONSTANT(Key, KEY, VOLUMEDOWN);
+ BIND_CORE_ENUM_CLASS_CONSTANT(Key, KEY, VOLUMEMUTE);
+ BIND_CORE_ENUM_CLASS_CONSTANT(Key, KEY, VOLUMEUP);
+ BIND_CORE_ENUM_CLASS_CONSTANT(Key, KEY, BASSBOOST);
+ BIND_CORE_ENUM_CLASS_CONSTANT(Key, KEY, BASSUP);
+ BIND_CORE_ENUM_CLASS_CONSTANT(Key, KEY, BASSDOWN);
+ BIND_CORE_ENUM_CLASS_CONSTANT(Key, KEY, TREBLEUP);
+ BIND_CORE_ENUM_CLASS_CONSTANT(Key, KEY, TREBLEDOWN);
+ BIND_CORE_ENUM_CLASS_CONSTANT(Key, KEY, MEDIAPLAY);
+ BIND_CORE_ENUM_CLASS_CONSTANT(Key, KEY, MEDIASTOP);
+ BIND_CORE_ENUM_CLASS_CONSTANT(Key, KEY, MEDIAPREVIOUS);
+ BIND_CORE_ENUM_CLASS_CONSTANT(Key, KEY, MEDIANEXT);
+ BIND_CORE_ENUM_CLASS_CONSTANT(Key, KEY, MEDIARECORD);
+ BIND_CORE_ENUM_CLASS_CONSTANT(Key, KEY, HOMEPAGE);
+ BIND_CORE_ENUM_CLASS_CONSTANT(Key, KEY, FAVORITES);
+ BIND_CORE_ENUM_CLASS_CONSTANT(Key, KEY, SEARCH);
+ BIND_CORE_ENUM_CLASS_CONSTANT(Key, KEY, STANDBY);
+ BIND_CORE_ENUM_CLASS_CONSTANT(Key, KEY, OPENURL);
+ BIND_CORE_ENUM_CLASS_CONSTANT(Key, KEY, LAUNCHMAIL);
+ BIND_CORE_ENUM_CLASS_CONSTANT(Key, KEY, LAUNCHMEDIA);
+ BIND_CORE_ENUM_CLASS_CONSTANT(Key, KEY, LAUNCH0);
+ BIND_CORE_ENUM_CLASS_CONSTANT(Key, KEY, LAUNCH1);
+ BIND_CORE_ENUM_CLASS_CONSTANT(Key, KEY, LAUNCH2);
+ BIND_CORE_ENUM_CLASS_CONSTANT(Key, KEY, LAUNCH3);
+ BIND_CORE_ENUM_CLASS_CONSTANT(Key, KEY, LAUNCH4);
+ BIND_CORE_ENUM_CLASS_CONSTANT(Key, KEY, LAUNCH5);
+ BIND_CORE_ENUM_CLASS_CONSTANT(Key, KEY, LAUNCH6);
+ BIND_CORE_ENUM_CLASS_CONSTANT(Key, KEY, LAUNCH7);
+ BIND_CORE_ENUM_CLASS_CONSTANT(Key, KEY, LAUNCH8);
+ BIND_CORE_ENUM_CLASS_CONSTANT(Key, KEY, LAUNCH9);
+ BIND_CORE_ENUM_CLASS_CONSTANT(Key, KEY, LAUNCHA);
+ BIND_CORE_ENUM_CLASS_CONSTANT(Key, KEY, LAUNCHB);
+ BIND_CORE_ENUM_CLASS_CONSTANT(Key, KEY, LAUNCHC);
+ BIND_CORE_ENUM_CLASS_CONSTANT(Key, KEY, LAUNCHD);
+ BIND_CORE_ENUM_CLASS_CONSTANT(Key, KEY, LAUNCHE);
+ BIND_CORE_ENUM_CLASS_CONSTANT(Key, KEY, LAUNCHF);
+ BIND_CORE_ENUM_CLASS_CONSTANT(Key, KEY, UNKNOWN);
+ BIND_CORE_ENUM_CLASS_CONSTANT(Key, KEY, SPACE);
+ BIND_CORE_ENUM_CLASS_CONSTANT(Key, KEY, EXCLAM);
+ BIND_CORE_ENUM_CLASS_CONSTANT(Key, KEY, QUOTEDBL);
+ BIND_CORE_ENUM_CLASS_CONSTANT(Key, KEY, NUMBERSIGN);
+ BIND_CORE_ENUM_CLASS_CONSTANT(Key, KEY, DOLLAR);
+ BIND_CORE_ENUM_CLASS_CONSTANT(Key, KEY, PERCENT);
+ BIND_CORE_ENUM_CLASS_CONSTANT(Key, KEY, AMPERSAND);
+ BIND_CORE_ENUM_CLASS_CONSTANT(Key, KEY, APOSTROPHE);
+ BIND_CORE_ENUM_CLASS_CONSTANT(Key, KEY, PARENLEFT);
+ BIND_CORE_ENUM_CLASS_CONSTANT(Key, KEY, PARENRIGHT);
+ BIND_CORE_ENUM_CLASS_CONSTANT(Key, KEY, ASTERISK);
+ BIND_CORE_ENUM_CLASS_CONSTANT(Key, KEY, PLUS);
+ BIND_CORE_ENUM_CLASS_CONSTANT(Key, KEY, COMMA);
+ BIND_CORE_ENUM_CLASS_CONSTANT(Key, KEY, MINUS);
+ BIND_CORE_ENUM_CLASS_CONSTANT(Key, KEY, PERIOD);
+ BIND_CORE_ENUM_CLASS_CONSTANT(Key, KEY, SLASH);
+ BIND_CORE_ENUM_CLASS_CONSTANT_CUSTOM(Key, KEY_0, KEY_0);
+ BIND_CORE_ENUM_CLASS_CONSTANT_CUSTOM(Key, KEY_1, KEY_1);
+ BIND_CORE_ENUM_CLASS_CONSTANT_CUSTOM(Key, KEY_2, KEY_2);
+ BIND_CORE_ENUM_CLASS_CONSTANT_CUSTOM(Key, KEY_3, KEY_3);
+ BIND_CORE_ENUM_CLASS_CONSTANT_CUSTOM(Key, KEY_4, KEY_4);
+ BIND_CORE_ENUM_CLASS_CONSTANT_CUSTOM(Key, KEY_5, KEY_5);
+ BIND_CORE_ENUM_CLASS_CONSTANT_CUSTOM(Key, KEY_6, KEY_6);
+ BIND_CORE_ENUM_CLASS_CONSTANT_CUSTOM(Key, KEY_7, KEY_7);
+ BIND_CORE_ENUM_CLASS_CONSTANT_CUSTOM(Key, KEY_8, KEY_8);
+ BIND_CORE_ENUM_CLASS_CONSTANT_CUSTOM(Key, KEY_9, KEY_9);
+ BIND_CORE_ENUM_CLASS_CONSTANT(Key, KEY, COLON);
+ BIND_CORE_ENUM_CLASS_CONSTANT(Key, KEY, SEMICOLON);
+ BIND_CORE_ENUM_CLASS_CONSTANT(Key, KEY, LESS);
+ BIND_CORE_ENUM_CLASS_CONSTANT(Key, KEY, EQUAL);
+ BIND_CORE_ENUM_CLASS_CONSTANT(Key, KEY, GREATER);
+ BIND_CORE_ENUM_CLASS_CONSTANT(Key, KEY, QUESTION);
+ BIND_CORE_ENUM_CLASS_CONSTANT(Key, KEY, AT);
+ BIND_CORE_ENUM_CLASS_CONSTANT(Key, KEY, A);
+ BIND_CORE_ENUM_CLASS_CONSTANT(Key, KEY, B);
+ BIND_CORE_ENUM_CLASS_CONSTANT(Key, KEY, C);
+ BIND_CORE_ENUM_CLASS_CONSTANT(Key, KEY, D);
+ BIND_CORE_ENUM_CLASS_CONSTANT(Key, KEY, E);
+ BIND_CORE_ENUM_CLASS_CONSTANT(Key, KEY, F);
+ BIND_CORE_ENUM_CLASS_CONSTANT(Key, KEY, G);
+ BIND_CORE_ENUM_CLASS_CONSTANT(Key, KEY, H);
+ BIND_CORE_ENUM_CLASS_CONSTANT(Key, KEY, I);
+ BIND_CORE_ENUM_CLASS_CONSTANT(Key, KEY, J);
+ BIND_CORE_ENUM_CLASS_CONSTANT(Key, KEY, K);
+ BIND_CORE_ENUM_CLASS_CONSTANT(Key, KEY, L);
+ BIND_CORE_ENUM_CLASS_CONSTANT(Key, KEY, M);
+ BIND_CORE_ENUM_CLASS_CONSTANT(Key, KEY, N);
+ BIND_CORE_ENUM_CLASS_CONSTANT(Key, KEY, O);
+ BIND_CORE_ENUM_CLASS_CONSTANT(Key, KEY, P);
+ BIND_CORE_ENUM_CLASS_CONSTANT(Key, KEY, Q);
+ BIND_CORE_ENUM_CLASS_CONSTANT(Key, KEY, R);
+ BIND_CORE_ENUM_CLASS_CONSTANT(Key, KEY, S);
+ BIND_CORE_ENUM_CLASS_CONSTANT(Key, KEY, T);
+ BIND_CORE_ENUM_CLASS_CONSTANT(Key, KEY, U);
+ BIND_CORE_ENUM_CLASS_CONSTANT(Key, KEY, V);
+ BIND_CORE_ENUM_CLASS_CONSTANT(Key, KEY, W);
+ BIND_CORE_ENUM_CLASS_CONSTANT(Key, KEY, X);
+ BIND_CORE_ENUM_CLASS_CONSTANT(Key, KEY, Y);
+ BIND_CORE_ENUM_CLASS_CONSTANT(Key, KEY, Z);
+ BIND_CORE_ENUM_CLASS_CONSTANT(Key, KEY, BRACKETLEFT);
+ BIND_CORE_ENUM_CLASS_CONSTANT(Key, KEY, BACKSLASH);
+ BIND_CORE_ENUM_CLASS_CONSTANT(Key, KEY, BRACKETRIGHT);
+ BIND_CORE_ENUM_CLASS_CONSTANT(Key, KEY, ASCIICIRCUM);
+ BIND_CORE_ENUM_CLASS_CONSTANT(Key, KEY, UNDERSCORE);
+ BIND_CORE_ENUM_CLASS_CONSTANT(Key, KEY, QUOTELEFT);
+ BIND_CORE_ENUM_CLASS_CONSTANT(Key, KEY, BRACELEFT);
+ BIND_CORE_ENUM_CLASS_CONSTANT(Key, KEY, BAR);
+ BIND_CORE_ENUM_CLASS_CONSTANT(Key, KEY, BRACERIGHT);
+ BIND_CORE_ENUM_CLASS_CONSTANT(Key, KEY, ASCIITILDE);
+ BIND_CORE_ENUM_CLASS_CONSTANT(Key, KEY, NOBREAKSPACE);
+ BIND_CORE_ENUM_CLASS_CONSTANT(Key, KEY, EXCLAMDOWN);
+ BIND_CORE_ENUM_CLASS_CONSTANT(Key, KEY, CENT);
+ BIND_CORE_ENUM_CLASS_CONSTANT(Key, KEY, STERLING);
+ BIND_CORE_ENUM_CLASS_CONSTANT(Key, KEY, CURRENCY);
+ BIND_CORE_ENUM_CLASS_CONSTANT(Key, KEY, YEN);
+ BIND_CORE_ENUM_CLASS_CONSTANT(Key, KEY, BROKENBAR);
+ BIND_CORE_ENUM_CLASS_CONSTANT(Key, KEY, SECTION);
+ BIND_CORE_ENUM_CLASS_CONSTANT(Key, KEY, DIAERESIS);
+ BIND_CORE_ENUM_CLASS_CONSTANT(Key, KEY, COPYRIGHT);
+ BIND_CORE_ENUM_CLASS_CONSTANT(Key, KEY, ORDFEMININE);
+ BIND_CORE_ENUM_CLASS_CONSTANT(Key, KEY, GUILLEMOTLEFT);
+ BIND_CORE_ENUM_CLASS_CONSTANT(Key, KEY, NOTSIGN);
+ BIND_CORE_ENUM_CLASS_CONSTANT(Key, KEY, HYPHEN);
+ BIND_CORE_ENUM_CLASS_CONSTANT_CUSTOM(Key, KEY_REGISTERED, KEY_REGISTERED);
+ BIND_CORE_ENUM_CLASS_CONSTANT(Key, KEY, MACRON);
+ BIND_CORE_ENUM_CLASS_CONSTANT(Key, KEY, DEGREE);
+ BIND_CORE_ENUM_CLASS_CONSTANT(Key, KEY, PLUSMINUS);
+ BIND_CORE_ENUM_CLASS_CONSTANT(Key, KEY, TWOSUPERIOR);
+ BIND_CORE_ENUM_CLASS_CONSTANT(Key, KEY, THREESUPERIOR);
+ BIND_CORE_ENUM_CLASS_CONSTANT(Key, KEY, ACUTE);
+ BIND_CORE_ENUM_CLASS_CONSTANT(Key, KEY, MU);
+ BIND_CORE_ENUM_CLASS_CONSTANT(Key, KEY, PARAGRAPH);
+ BIND_CORE_ENUM_CLASS_CONSTANT(Key, KEY, PERIODCENTERED);
+ BIND_CORE_ENUM_CLASS_CONSTANT(Key, KEY, CEDILLA);
+ BIND_CORE_ENUM_CLASS_CONSTANT(Key, KEY, ONESUPERIOR);
+ BIND_CORE_ENUM_CLASS_CONSTANT(Key, KEY, MASCULINE);
+ BIND_CORE_ENUM_CLASS_CONSTANT(Key, KEY, GUILLEMOTRIGHT);
+ BIND_CORE_ENUM_CLASS_CONSTANT(Key, KEY, ONEQUARTER);
+ BIND_CORE_ENUM_CLASS_CONSTANT(Key, KEY, ONEHALF);
+ BIND_CORE_ENUM_CLASS_CONSTANT(Key, KEY, THREEQUARTERS);
+ BIND_CORE_ENUM_CLASS_CONSTANT(Key, KEY, QUESTIONDOWN);
+ BIND_CORE_ENUM_CLASS_CONSTANT(Key, KEY, AGRAVE);
+ BIND_CORE_ENUM_CLASS_CONSTANT(Key, KEY, AACUTE);
+ BIND_CORE_ENUM_CLASS_CONSTANT(Key, KEY, ACIRCUMFLEX);
+ BIND_CORE_ENUM_CLASS_CONSTANT(Key, KEY, ATILDE);
+ BIND_CORE_ENUM_CLASS_CONSTANT(Key, KEY, ADIAERESIS);
+ BIND_CORE_ENUM_CLASS_CONSTANT(Key, KEY, ARING);
+ BIND_CORE_ENUM_CLASS_CONSTANT(Key, KEY, AE);
+ BIND_CORE_ENUM_CLASS_CONSTANT(Key, KEY, CCEDILLA);
+ BIND_CORE_ENUM_CLASS_CONSTANT(Key, KEY, EGRAVE);
+ BIND_CORE_ENUM_CLASS_CONSTANT(Key, KEY, EACUTE);
+ BIND_CORE_ENUM_CLASS_CONSTANT(Key, KEY, ECIRCUMFLEX);
+ BIND_CORE_ENUM_CLASS_CONSTANT(Key, KEY, EDIAERESIS);
+ BIND_CORE_ENUM_CLASS_CONSTANT(Key, KEY, IGRAVE);
+ BIND_CORE_ENUM_CLASS_CONSTANT(Key, KEY, IACUTE);
+ BIND_CORE_ENUM_CLASS_CONSTANT(Key, KEY, ICIRCUMFLEX);
+ BIND_CORE_ENUM_CLASS_CONSTANT(Key, KEY, IDIAERESIS);
+ BIND_CORE_ENUM_CLASS_CONSTANT(Key, KEY, ETH);
+ BIND_CORE_ENUM_CLASS_CONSTANT(Key, KEY, NTILDE);
+ BIND_CORE_ENUM_CLASS_CONSTANT(Key, KEY, OGRAVE);
+ BIND_CORE_ENUM_CLASS_CONSTANT(Key, KEY, OACUTE);
+ BIND_CORE_ENUM_CLASS_CONSTANT(Key, KEY, OCIRCUMFLEX);
+ BIND_CORE_ENUM_CLASS_CONSTANT(Key, KEY, OTILDE);
+ BIND_CORE_ENUM_CLASS_CONSTANT(Key, KEY, ODIAERESIS);
+ BIND_CORE_ENUM_CLASS_CONSTANT(Key, KEY, MULTIPLY);
+ BIND_CORE_ENUM_CLASS_CONSTANT(Key, KEY, OOBLIQUE);
+ BIND_CORE_ENUM_CLASS_CONSTANT(Key, KEY, UGRAVE);
+ BIND_CORE_ENUM_CLASS_CONSTANT(Key, KEY, UACUTE);
+ BIND_CORE_ENUM_CLASS_CONSTANT(Key, KEY, UCIRCUMFLEX);
+ BIND_CORE_ENUM_CLASS_CONSTANT(Key, KEY, UDIAERESIS);
+ BIND_CORE_ENUM_CLASS_CONSTANT(Key, KEY, YACUTE);
+ BIND_CORE_ENUM_CLASS_CONSTANT(Key, KEY, THORN);
+ BIND_CORE_ENUM_CLASS_CONSTANT(Key, KEY, SSHARP);
+ BIND_CORE_ENUM_CLASS_CONSTANT(Key, KEY, DIVISION);
+ BIND_CORE_ENUM_CLASS_CONSTANT(Key, KEY, YDIAERESIS);
+
+ BIND_CORE_ENUM_CLASS_CONSTANT_CUSTOM(KeyModifierMask, KEY_CODE_MASK, CODE_MASK);
+ BIND_CORE_ENUM_CLASS_CONSTANT_CUSTOM(KeyModifierMask, KEY_MODIFIER_MASK, MODIFIER_MASK);
+ BIND_CORE_ENUM_CLASS_CONSTANT(KeyModifierMask, KEY_MASK, SHIFT);
+ BIND_CORE_ENUM_CLASS_CONSTANT(KeyModifierMask, KEY_MASK, ALT);
+ BIND_CORE_ENUM_CLASS_CONSTANT(KeyModifierMask, KEY_MASK, META);
+ BIND_CORE_ENUM_CLASS_CONSTANT(KeyModifierMask, KEY_MASK, CTRL);
+ BIND_CORE_ENUM_CLASS_CONSTANT_NO_VAL(KeyModifierMask, KEY_MASK, CMD);
+ BIND_CORE_ENUM_CLASS_CONSTANT(KeyModifierMask, KEY_MASK, KPAD);
+ BIND_CORE_ENUM_CLASS_CONSTANT(KeyModifierMask, KEY_MASK, GROUP_SWITCH);
+
+ BIND_CORE_ENUM_CLASS_CONSTANT(MouseButton, MOUSE_BUTTON, LEFT);
+ BIND_CORE_ENUM_CLASS_CONSTANT(MouseButton, MOUSE_BUTTON, RIGHT);
+ BIND_CORE_ENUM_CLASS_CONSTANT(MouseButton, MOUSE_BUTTON, MIDDLE);
+ BIND_CORE_ENUM_CLASS_CONSTANT(MouseButton, MOUSE_BUTTON, WHEEL_UP);
+ BIND_CORE_ENUM_CLASS_CONSTANT(MouseButton, MOUSE_BUTTON, WHEEL_DOWN);
+ BIND_CORE_ENUM_CLASS_CONSTANT(MouseButton, MOUSE_BUTTON, WHEEL_LEFT);
+ BIND_CORE_ENUM_CLASS_CONSTANT(MouseButton, MOUSE_BUTTON, WHEEL_RIGHT);
+ BIND_CORE_ENUM_CLASS_CONSTANT_CUSTOM(MouseButton, MOUSE_BUTTON_XBUTTON1, MB_XBUTTON1);
+ BIND_CORE_ENUM_CLASS_CONSTANT_CUSTOM(MouseButton, MOUSE_BUTTON_XBUTTON2, MB_XBUTTON2);
+ BIND_CORE_ENUM_CLASS_CONSTANT(MouseButton, MOUSE_BUTTON, MASK_LEFT);
+ BIND_CORE_ENUM_CLASS_CONSTANT(MouseButton, MOUSE_BUTTON, MASK_RIGHT);
+ BIND_CORE_ENUM_CLASS_CONSTANT(MouseButton, MOUSE_BUTTON, MASK_MIDDLE);
+ BIND_CORE_ENUM_CLASS_CONSTANT(MouseButton, MOUSE_BUTTON, MASK_XBUTTON1);
+ BIND_CORE_ENUM_CLASS_CONSTANT(MouseButton, MOUSE_BUTTON, MASK_XBUTTON2);
+
+ BIND_CORE_ENUM_CLASS_CONSTANT(JoyButton, JOY_BUTTON, INVALID);
+ BIND_CORE_ENUM_CLASS_CONSTANT(JoyButton, JOY_BUTTON, A);
+ BIND_CORE_ENUM_CLASS_CONSTANT(JoyButton, JOY_BUTTON, B);
+ BIND_CORE_ENUM_CLASS_CONSTANT(JoyButton, JOY_BUTTON, X);
+ BIND_CORE_ENUM_CLASS_CONSTANT(JoyButton, JOY_BUTTON, Y);
+ BIND_CORE_ENUM_CLASS_CONSTANT(JoyButton, JOY_BUTTON, BACK);
+ BIND_CORE_ENUM_CLASS_CONSTANT(JoyButton, JOY_BUTTON, GUIDE);
+ BIND_CORE_ENUM_CLASS_CONSTANT(JoyButton, JOY_BUTTON, START);
+ BIND_CORE_ENUM_CLASS_CONSTANT(JoyButton, JOY_BUTTON, LEFT_STICK);
+ BIND_CORE_ENUM_CLASS_CONSTANT(JoyButton, JOY_BUTTON, RIGHT_STICK);
+ BIND_CORE_ENUM_CLASS_CONSTANT(JoyButton, JOY_BUTTON, LEFT_SHOULDER);
+ BIND_CORE_ENUM_CLASS_CONSTANT(JoyButton, JOY_BUTTON, RIGHT_SHOULDER);
+ BIND_CORE_ENUM_CLASS_CONSTANT(JoyButton, JOY_BUTTON, DPAD_UP);
+ BIND_CORE_ENUM_CLASS_CONSTANT(JoyButton, JOY_BUTTON, DPAD_DOWN);
+ BIND_CORE_ENUM_CLASS_CONSTANT(JoyButton, JOY_BUTTON, DPAD_LEFT);
+ BIND_CORE_ENUM_CLASS_CONSTANT(JoyButton, JOY_BUTTON, DPAD_RIGHT);
+ BIND_CORE_ENUM_CLASS_CONSTANT(JoyButton, JOY_BUTTON, MISC1);
+ BIND_CORE_ENUM_CLASS_CONSTANT(JoyButton, JOY_BUTTON, PADDLE1);
+ BIND_CORE_ENUM_CLASS_CONSTANT(JoyButton, JOY_BUTTON, PADDLE2);
+ BIND_CORE_ENUM_CLASS_CONSTANT(JoyButton, JOY_BUTTON, PADDLE3);
+ BIND_CORE_ENUM_CLASS_CONSTANT(JoyButton, JOY_BUTTON, PADDLE4);
+ BIND_CORE_ENUM_CLASS_CONSTANT(JoyButton, JOY_BUTTON, TOUCHPAD);
+ BIND_CORE_ENUM_CLASS_CONSTANT(JoyButton, JOY_BUTTON, SDL_MAX);
+ BIND_CORE_ENUM_CLASS_CONSTANT(JoyButton, JOY_BUTTON, MAX);
+
+ BIND_CORE_ENUM_CLASS_CONSTANT(JoyAxis, JOY_AXIS, INVALID);
+ BIND_CORE_ENUM_CLASS_CONSTANT(JoyAxis, JOY_AXIS, LEFT_X);
+ BIND_CORE_ENUM_CLASS_CONSTANT(JoyAxis, JOY_AXIS, LEFT_Y);
+ BIND_CORE_ENUM_CLASS_CONSTANT(JoyAxis, JOY_AXIS, RIGHT_X);
+ BIND_CORE_ENUM_CLASS_CONSTANT(JoyAxis, JOY_AXIS, RIGHT_Y);
+ BIND_CORE_ENUM_CLASS_CONSTANT(JoyAxis, JOY_AXIS, TRIGGER_LEFT);
+ BIND_CORE_ENUM_CLASS_CONSTANT(JoyAxis, JOY_AXIS, TRIGGER_RIGHT);
+ BIND_CORE_ENUM_CLASS_CONSTANT(JoyAxis, JOY_AXIS, SDL_MAX);
+ BIND_CORE_ENUM_CLASS_CONSTANT(JoyAxis, JOY_AXIS, MAX);
+
+ BIND_CORE_ENUM_CLASS_CONSTANT(MIDIMessage, MIDI_MESSAGE, NOTE_OFF);
+ BIND_CORE_ENUM_CLASS_CONSTANT(MIDIMessage, MIDI_MESSAGE, NOTE_ON);
+ BIND_CORE_ENUM_CLASS_CONSTANT(MIDIMessage, MIDI_MESSAGE, AFTERTOUCH);
+ BIND_CORE_ENUM_CLASS_CONSTANT(MIDIMessage, MIDI_MESSAGE, CONTROL_CHANGE);
+ BIND_CORE_ENUM_CLASS_CONSTANT(MIDIMessage, MIDI_MESSAGE, PROGRAM_CHANGE);
+ BIND_CORE_ENUM_CLASS_CONSTANT(MIDIMessage, MIDI_MESSAGE, CHANNEL_PRESSURE);
+ BIND_CORE_ENUM_CLASS_CONSTANT(MIDIMessage, MIDI_MESSAGE, PITCH_BEND);
// error list
@@ -598,7 +610,7 @@ void register_global_constants() {
BIND_CORE_ENUM_CONSTANT(PROPERTY_USAGE_DEFAULT);
BIND_CORE_ENUM_CONSTANT(PROPERTY_USAGE_DEFAULT_INTL);
- BIND_CORE_ENUM_CONSTANT(PROPERTY_USAGE_NOEDITOR);
+ BIND_CORE_ENUM_CONSTANT(PROPERTY_USAGE_NO_EDITOR);
BIND_CORE_ENUM_CONSTANT(METHOD_FLAG_NORMAL);
BIND_CORE_ENUM_CONSTANT(METHOD_FLAG_EDITOR);
diff --git a/core/debugger/engine_debugger.h b/core/debugger/engine_debugger.h
index 22c6ef943e..41142bf305 100644
--- a/core/debugger/engine_debugger.h
+++ b/core/debugger/engine_debugger.h
@@ -128,7 +128,7 @@ public:
virtual void poll_events(bool p_is_idle) {}
virtual void send_message(const String &p_msg, const Array &p_data) = 0;
- virtual void send_error(const String &p_func, const String &p_file, int p_line, const String &p_err, const String &p_descr, ErrorHandlerType p_type) = 0;
+ virtual void send_error(const String &p_func, const String &p_file, int p_line, const String &p_err, const String &p_descr, bool p_editor_notify, ErrorHandlerType p_type) = 0;
virtual void debug(bool p_can_continue = true, bool p_is_error_breakpoint = false) = 0;
virtual ~EngineDebugger();
diff --git a/core/debugger/local_debugger.cpp b/core/debugger/local_debugger.cpp
index f7e56351b0..7b397e88a3 100644
--- a/core/debugger/local_debugger.cpp
+++ b/core/debugger/local_debugger.cpp
@@ -139,7 +139,7 @@ void LocalDebugger::debug(bool p_can_continue, bool p_is_error_breakpoint) {
// Cache options
String variable_prefix = options["variable_prefix"];
- if (line == "") {
+ if (line.is_empty()) {
print_line("\nDebugger Break, Reason: '" + script_lang->debug_get_error() + "'");
print_line("*Frame " + itos(current_frame) + " - " + script_lang->debug_get_stack_level_source(current_frame) + ":" + itos(script_lang->debug_get_stack_level_line(current_frame)) + " in function '" + script_lang->debug_get_stack_level_function(current_frame) + "'");
print_line("Enter \"help\" for assistance.");
@@ -358,7 +358,7 @@ void LocalDebugger::send_message(const String &p_message, const Array &p_args) {
// print_line("MESSAGE: '" + p_message + "' - " + String(Variant(p_args)));
}
-void LocalDebugger::send_error(const String &p_func, const String &p_file, int p_line, const String &p_err, const String &p_descr, ErrorHandlerType p_type) {
+void LocalDebugger::send_error(const String &p_func, const String &p_file, int p_line, const String &p_err, const String &p_descr, bool p_editor_notify, ErrorHandlerType p_type) {
print_line("ERROR: '" + (p_descr.is_empty() ? p_err : p_descr) + "'");
}
diff --git a/core/debugger/local_debugger.h b/core/debugger/local_debugger.h
index e793b2a859..cb59eb82e9 100644
--- a/core/debugger/local_debugger.h
+++ b/core/debugger/local_debugger.h
@@ -50,7 +50,7 @@ private:
public:
void debug(bool p_can_continue, bool p_is_error_breakpoint);
void send_message(const String &p_message, const Array &p_args);
- void send_error(const String &p_func, const String &p_file, int p_line, const String &p_err, const String &p_descr, ErrorHandlerType p_type);
+ void send_error(const String &p_func, const String &p_file, int p_line, const String &p_err, const String &p_descr, bool p_editor_notify, ErrorHandlerType p_type);
LocalDebugger();
~LocalDebugger();
diff --git a/core/debugger/remote_debugger.cpp b/core/debugger/remote_debugger.cpp
index 032c7d55c0..87e65e592a 100644
--- a/core/debugger/remote_debugger.cpp
+++ b/core/debugger/remote_debugger.cpp
@@ -79,8 +79,8 @@ public:
ERR_FAIL_COND_V(p_buffer.size() == 0, 0);
int total_bandwidth = 0;
- uint32_t timestamp = OS::get_singleton()->get_ticks_msec();
- uint32_t final_timestamp = timestamp - 1000;
+ uint64_t timestamp = OS::get_singleton()->get_ticks_msec();
+ uint64_t final_timestamp = timestamp - 1000;
int i = (p_pointer + p_buffer.size() - 1) % p_buffer.size();
@@ -455,7 +455,7 @@ Error RemoteDebugger::_put_msg(String p_message, Array p_data) {
return err;
}
-void RemoteDebugger::_err_handler(void *p_this, const char *p_func, const char *p_file, int p_line, const char *p_err, const char *p_descr, ErrorHandlerType p_type) {
+void RemoteDebugger::_err_handler(void *p_this, const char *p_func, const char *p_file, int p_line, const char *p_err, const char *p_descr, bool p_editor_notify, ErrorHandlerType p_type) {
if (p_type == ERR_HANDLER_SCRIPT) {
return; //ignore script errors, those go through debugger
}
@@ -475,7 +475,7 @@ void RemoteDebugger::_err_handler(void *p_this, const char *p_func, const char *
}
// send_error will lock internally.
- rd->script_debugger->send_error(p_func, p_file, p_line, p_err, p_descr, p_type, si);
+ rd->script_debugger->send_error(String::utf8(p_func), String::utf8(p_file), p_line, String::utf8(p_err), String::utf8(p_descr), p_editor_notify, p_type, si);
}
void RemoteDebugger::_print_handler(void *p_this, const String &p_string, bool p_error) {
@@ -605,7 +605,7 @@ void RemoteDebugger::send_message(const String &p_message, const Array &p_args)
}
}
-void RemoteDebugger::send_error(const String &p_func, const String &p_file, int p_line, const String &p_err, const String &p_descr, ErrorHandlerType p_type) {
+void RemoteDebugger::send_error(const String &p_func, const String &p_file, int p_line, const String &p_err, const String &p_descr, bool p_editor_notify, ErrorHandlerType p_type) {
ErrorMessage oe;
oe.error = p_err;
oe.error_descr = p_descr;
diff --git a/core/debugger/remote_debugger.h b/core/debugger/remote_debugger.h
index 28e670747e..73799e3f81 100644
--- a/core/debugger/remote_debugger.h
+++ b/core/debugger/remote_debugger.h
@@ -89,7 +89,7 @@ private:
PrintHandlerList phl;
static void _print_handler(void *p_this, const String &p_string, bool p_error);
ErrorHandlerList eh;
- static void _err_handler(void *p_this, const char *p_func, const char *p_file, int p_line, const char *p_err, const char *p_descr, ErrorHandlerType p_type);
+ static void _err_handler(void *p_this, const char *p_func, const char *p_file, int p_line, const char *p_err, const char *p_descr, bool p_editor_notify, ErrorHandlerType p_type);
ErrorMessage _create_overflow_error(const String &p_what, const String &p_descr);
Error _put_msg(String p_message, Array p_data);
@@ -111,7 +111,7 @@ public:
// Overrides
void poll_events(bool p_is_idle);
void send_message(const String &p_message, const Array &p_args);
- void send_error(const String &p_func, const String &p_file, int p_line, const String &p_err, const String &p_descr, ErrorHandlerType p_type);
+ void send_error(const String &p_func, const String &p_file, int p_line, const String &p_err, const String &p_descr, bool p_editor_notify, ErrorHandlerType p_type);
void debug(bool p_can_continue = true, bool p_is_error_breakpoint = false);
RemoteDebugger(Ref<RemoteDebuggerPeer> p_peer);
diff --git a/core/debugger/script_debugger.cpp b/core/debugger/script_debugger.cpp
index 6d1e4ed101..70ec101a03 100644
--- a/core/debugger/script_debugger.cpp
+++ b/core/debugger/script_debugger.cpp
@@ -100,10 +100,10 @@ void ScriptDebugger::debug(ScriptLanguage *p_lang, bool p_can_continue, bool p_i
break_lang = prev;
}
-void ScriptDebugger::send_error(const String &p_func, const String &p_file, int p_line, const String &p_err, const String &p_descr, ErrorHandlerType p_type, const Vector<StackInfo> &p_stack_info) {
+void ScriptDebugger::send_error(const String &p_func, const String &p_file, int p_line, const String &p_err, const String &p_descr, bool p_editor_notify, ErrorHandlerType p_type, const Vector<StackInfo> &p_stack_info) {
// Store stack info, this is ugly, but allows us to separate EngineDebugger and ScriptDebugger. There might be a better way.
error_stack_info.append_array(p_stack_info);
- EngineDebugger::get_singleton()->send_error(p_func, p_file, p_line, p_err, p_descr, p_type);
+ EngineDebugger::get_singleton()->send_error(p_func, p_file, p_line, p_err, p_descr, p_editor_notify, p_type);
error_stack_info.resize(0);
}
diff --git a/core/debugger/script_debugger.h b/core/debugger/script_debugger.h
index 9f034a5e5d..c1d0170334 100644
--- a/core/debugger/script_debugger.h
+++ b/core/debugger/script_debugger.h
@@ -71,7 +71,7 @@ public:
void debug(ScriptLanguage *p_lang, bool p_can_continue = true, bool p_is_error_breakpoint = false);
ScriptLanguage *get_break_language() const;
- void send_error(const String &p_func, const String &p_file, int p_line, const String &p_err, const String &p_descr, ErrorHandlerType p_type, const Vector<StackInfo> &p_stack_info);
+ void send_error(const String &p_func, const String &p_file, int p_line, const String &p_err, const String &p_descr, bool p_editor_notify, ErrorHandlerType p_type, const Vector<StackInfo> &p_stack_info);
Vector<StackInfo> get_error_stack_info() const;
ScriptDebugger() {}
};
diff --git a/core/doc_data.cpp b/core/doc_data.cpp
index 4b284a30aa..7334db5cb0 100644
--- a/core/doc_data.cpp
+++ b/core/doc_data.cpp
@@ -33,7 +33,7 @@
void DocData::return_doc_from_retinfo(DocData::MethodDoc &p_method, const PropertyInfo &p_retinfo) {
if (p_retinfo.type == Variant::INT && p_retinfo.hint == PROPERTY_HINT_INT_IS_POINTER) {
p_method.return_type = p_retinfo.hint_string;
- if (p_method.return_type == "") {
+ if (p_method.return_type.is_empty()) {
p_method.return_type = "void*";
} else {
p_method.return_type += "*";
@@ -64,7 +64,7 @@ void DocData::argument_doc_from_arginfo(DocData::ArgumentDoc &p_argument, const
if (p_arginfo.type == Variant::INT && p_arginfo.hint == PROPERTY_HINT_INT_IS_POINTER) {
p_argument.type = p_arginfo.hint_string;
- if (p_argument.type == "") {
+ if (p_argument.type.is_empty()) {
p_argument.type = "void*";
} else {
p_argument.type += "*";
diff --git a/core/doc_data.h b/core/doc_data.h
index 19dec71927..db83dda8aa 100644
--- a/core/doc_data.h
+++ b/core/doc_data.h
@@ -70,18 +70,29 @@ public:
Vector<int> errors_returned;
bool operator<(const MethodDoc &p_method) const {
if (name == p_method.name) {
- // Must be a constructor since there is no overloading.
- // We want this arbitrary order for a class "Foo":
- // - 1. Default constructor: Foo()
- // - 2. Copy constructor: Foo(Foo)
- // - 3+. Other constructors Foo(Bar, ...) based on first argument's name
- if (arguments.size() == 0 || p_method.arguments.size() == 0) { // 1.
+ // Must be an operator or a constructor since there is no other overloading
+ if (name.left(8) == "operator") {
+ if (arguments.size() == p_method.arguments.size()) {
+ if (arguments.size() == 0) {
+ return false;
+ }
+ return arguments[0].type < p_method.arguments[0].type;
+ }
return arguments.size() < p_method.arguments.size();
+ } else {
+ // Must be a constructor
+ // We want this arbitrary order for a class "Foo":
+ // - 1. Default constructor: Foo()
+ // - 2. Copy constructor: Foo(Foo)
+ // - 3+. Other constructors Foo(Bar, ...) based on first argument's name
+ if (arguments.size() == 0 || p_method.arguments.size() == 0) { // 1.
+ return arguments.size() < p_method.arguments.size();
+ }
+ if (arguments[0].type == return_type || p_method.arguments[0].type == p_method.return_type) { // 2.
+ return (arguments[0].type == return_type) || (p_method.arguments[0].type != p_method.return_type);
+ }
+ return arguments[0] < p_method.arguments[0];
}
- if (arguments[0].type == return_type || p_method.arguments[0].type == p_method.return_type) { // 2.
- return (arguments[0].type == return_type) || (p_method.arguments[0].type != p_method.return_type);
- }
- return arguments[0] < p_method.arguments[0];
}
return name < p_method.name;
}
@@ -112,6 +123,7 @@ public:
String setter, getter;
String default_value;
bool overridden = false;
+ String overrides;
bool operator<(const PropertyDoc &p_prop) const {
return name < p_prop.name;
}
@@ -124,7 +136,11 @@ public:
String description;
String default_value;
bool operator<(const ThemeItemDoc &p_theme_item) const {
- return name < p_theme_item.name;
+ // First sort by the data type, then by name.
+ if (data_type == p_theme_item.data_type) {
+ return name < p_theme_item.name;
+ }
+ return data_type < p_theme_item.data_type;
}
};
@@ -140,7 +156,9 @@ public:
String brief_description;
String description;
Vector<TutorialDoc> tutorials;
+ Vector<MethodDoc> constructors;
Vector<MethodDoc> methods;
+ Vector<MethodDoc> operators;
Vector<MethodDoc> signals;
Vector<ConstantDoc> constants;
Map<String, String> enums;
diff --git a/core/error/error_macros.cpp b/core/error/error_macros.cpp
index 272dda97d8..61bb949ed4 100644
--- a/core/error/error_macros.cpp
+++ b/core/error/error_macros.cpp
@@ -65,45 +65,49 @@ void remove_error_handler(ErrorHandlerList *p_handler) {
_global_unlock();
}
-void _err_print_error(const char *p_function, const char *p_file, int p_line, const char *p_error, ErrorHandlerType p_type) {
- _err_print_error(p_function, p_file, p_line, p_error, "", p_type);
+// Errors without messages.
+void _err_print_error(const char *p_function, const char *p_file, int p_line, const char *p_error, bool p_editor_notify, ErrorHandlerType p_type) {
+ _err_print_error(p_function, p_file, p_line, p_error, "", p_editor_notify, p_type);
}
-void _err_print_error(const char *p_function, const char *p_file, int p_line, const String &p_error, ErrorHandlerType p_type) {
- _err_print_error(p_function, p_file, p_line, p_error.utf8().get_data(), "", p_type);
+void _err_print_error(const char *p_function, const char *p_file, int p_line, const String &p_error, bool p_editor_notify, ErrorHandlerType p_type) {
+ _err_print_error(p_function, p_file, p_line, p_error.utf8().get_data(), "", p_editor_notify, p_type);
}
-void _err_print_error(const char *p_function, const char *p_file, int p_line, const char *p_error, const char *p_message, ErrorHandlerType p_type) {
- OS::get_singleton()->print_error(p_function, p_file, p_line, p_error, p_message, (Logger::ErrorType)p_type);
+// Main error printing function.
+void _err_print_error(const char *p_function, const char *p_file, int p_line, const char *p_error, const char *p_message, bool p_editor_notify, ErrorHandlerType p_type) {
+ OS::get_singleton()->print_error(p_function, p_file, p_line, p_error, p_message, p_editor_notify, (Logger::ErrorType)p_type);
_global_lock();
ErrorHandlerList *l = error_handler_list;
while (l) {
- l->errfunc(l->userdata, p_function, p_file, p_line, p_error, p_message, p_type);
+ l->errfunc(l->userdata, p_function, p_file, p_line, p_error, p_message, p_editor_notify, p_type);
l = l->next;
}
_global_unlock();
}
-void _err_print_error(const char *p_function, const char *p_file, int p_line, const String &p_error, const char *p_message, ErrorHandlerType p_type) {
- _err_print_error(p_function, p_file, p_line, p_error.utf8().get_data(), p_message, p_type);
+// Errors with message. (All combinations of p_error and p_message as String or char*.)
+void _err_print_error(const char *p_function, const char *p_file, int p_line, const String &p_error, const char *p_message, bool p_editor_notify, ErrorHandlerType p_type) {
+ _err_print_error(p_function, p_file, p_line, p_error.utf8().get_data(), p_message, p_editor_notify, p_type);
}
-void _err_print_error(const char *p_function, const char *p_file, int p_line, const char *p_error, const String &p_message, ErrorHandlerType p_type) {
- _err_print_error(p_function, p_file, p_line, p_error, p_message.utf8().get_data(), p_type);
+void _err_print_error(const char *p_function, const char *p_file, int p_line, const char *p_error, const String &p_message, bool p_editor_notify, ErrorHandlerType p_type) {
+ _err_print_error(p_function, p_file, p_line, p_error, p_message.utf8().get_data(), p_editor_notify, p_type);
}
-void _err_print_error(const char *p_function, const char *p_file, int p_line, const String &p_error, const String &p_message, ErrorHandlerType p_type) {
- _err_print_error(p_function, p_file, p_line, p_error.utf8().get_data(), p_message.utf8().get_data(), p_type);
+void _err_print_error(const char *p_function, const char *p_file, int p_line, const String &p_error, const String &p_message, bool p_editor_notify, ErrorHandlerType p_type) {
+ _err_print_error(p_function, p_file, p_line, p_error.utf8().get_data(), p_message.utf8().get_data(), p_editor_notify, p_type);
}
-void _err_print_index_error(const char *p_function, const char *p_file, int p_line, int64_t p_index, int64_t p_size, const char *p_index_str, const char *p_size_str, const char *p_message, bool fatal) {
- String fstr(fatal ? "FATAL: " : "");
+// Index errors. (All combinations of p_message as String or char*.)
+void _err_print_index_error(const char *p_function, const char *p_file, int p_line, int64_t p_index, int64_t p_size, const char *p_index_str, const char *p_size_str, const char *p_message, bool p_editor_notify, bool p_fatal) {
+ String fstr(p_fatal ? "FATAL: " : "");
String err(fstr + "Index " + p_index_str + " = " + itos(p_index) + " is out of bounds (" + p_size_str + " = " + itos(p_size) + ").");
_err_print_error(p_function, p_file, p_line, err.utf8().get_data(), p_message);
}
-void _err_print_index_error(const char *p_function, const char *p_file, int p_line, int64_t p_index, int64_t p_size, const char *p_index_str, const char *p_size_str, const String &p_message, bool fatal) {
- _err_print_index_error(p_function, p_file, p_line, p_index, p_size, p_index_str, p_size_str, p_message.utf8().get_data(), fatal);
+void _err_print_index_error(const char *p_function, const char *p_file, int p_line, int64_t p_index, int64_t p_size, const char *p_index_str, const char *p_size_str, const String &p_message, bool p_editor_notify, bool p_fatal) {
+ _err_print_index_error(p_function, p_file, p_line, p_index, p_size, p_index_str, p_size_str, p_message.utf8().get_data(), p_fatal);
}
diff --git a/core/error/error_macros.h b/core/error/error_macros.h
index 1bed8d366b..4eb862dce2 100644
--- a/core/error/error_macros.h
+++ b/core/error/error_macros.h
@@ -46,7 +46,7 @@ enum ErrorHandlerType {
// Pointer to the error handler printing function. Reassign to any function to have errors printed.
// Parameters: userdata, function, file, line, error, explanation, type.
-typedef void (*ErrorHandlerFunc)(void *, const char *, const char *, int p_line, const char *, const char *, ErrorHandlerType p_type);
+typedef void (*ErrorHandlerFunc)(void *, const char *, const char *, int p_line, const char *, const char *, bool p_editor_notify, ErrorHandlerType p_type);
struct ErrorHandlerList {
ErrorHandlerFunc errfunc = nullptr;
@@ -61,14 +61,14 @@ void add_error_handler(ErrorHandlerList *p_handler);
void remove_error_handler(ErrorHandlerList *p_handler);
// Functions used by the error macros.
-void _err_print_error(const char *p_function, const char *p_file, int p_line, const char *p_error, ErrorHandlerType p_type = ERR_HANDLER_ERROR);
-void _err_print_error(const char *p_function, const char *p_file, int p_line, const String &p_error, ErrorHandlerType p_type = ERR_HANDLER_ERROR);
-void _err_print_error(const char *p_function, const char *p_file, int p_line, const char *p_error, const char *p_message, ErrorHandlerType p_type = ERR_HANDLER_ERROR);
-void _err_print_error(const char *p_function, const char *p_file, int p_line, const String &p_error, const char *p_message, ErrorHandlerType p_type = ERR_HANDLER_ERROR);
-void _err_print_error(const char *p_function, const char *p_file, int p_line, const char *p_error, const String &p_message, ErrorHandlerType p_type = ERR_HANDLER_ERROR);
-void _err_print_error(const char *p_function, const char *p_file, int p_line, const String &p_error, const String &p_message, ErrorHandlerType p_type = ERR_HANDLER_ERROR);
-void _err_print_index_error(const char *p_function, const char *p_file, int p_line, int64_t p_index, int64_t p_size, const char *p_index_str, const char *p_size_str, const char *p_message = "", bool fatal = false);
-void _err_print_index_error(const char *p_function, const char *p_file, int p_line, int64_t p_index, int64_t p_size, const char *p_index_str, const char *p_size_str, const String &p_message, bool fatal = false);
+void _err_print_error(const char *p_function, const char *p_file, int p_line, const char *p_error, bool p_editor_notify = false, ErrorHandlerType p_type = ERR_HANDLER_ERROR);
+void _err_print_error(const char *p_function, const char *p_file, int p_line, const String &p_error, bool p_editor_notify = false, ErrorHandlerType p_type = ERR_HANDLER_ERROR);
+void _err_print_error(const char *p_function, const char *p_file, int p_line, const char *p_error, const char *p_message, bool p_editor_notify = false, ErrorHandlerType p_type = ERR_HANDLER_ERROR);
+void _err_print_error(const char *p_function, const char *p_file, int p_line, const String &p_error, const char *p_message, bool p_editor_notify = false, ErrorHandlerType p_type = ERR_HANDLER_ERROR);
+void _err_print_error(const char *p_function, const char *p_file, int p_line, const char *p_error, const String &p_message, bool p_editor_notify = false, ErrorHandlerType p_type = ERR_HANDLER_ERROR);
+void _err_print_error(const char *p_function, const char *p_file, int p_line, const String &p_error, const String &p_message, bool p_editor_notify = false, ErrorHandlerType p_type = ERR_HANDLER_ERROR);
+void _err_print_index_error(const char *p_function, const char *p_file, int p_line, int64_t p_index, int64_t p_size, const char *p_index_str, const char *p_size_str, const char *p_message = "", bool p_editor_notify = false, bool fatal = false);
+void _err_print_index_error(const char *p_function, const char *p_file, int p_line, int64_t p_index, int64_t p_size, const char *p_index_str, const char *p_size_str, const String &p_message, bool p_editor_notify = false, bool fatal = false);
#ifdef __GNUC__
//#define FUNCTION_STR __PRETTY_FUNCTION__ - too annoying
@@ -136,6 +136,17 @@ void _err_print_index_error(const char *p_function, const char *p_file, int p_li
((void)0)
/**
+ * Ensures an integer index `m_index` is less than `m_size` and greater than or equal to 0.
+ * If not, prints `m_msg`, notifies in the editor, and the current function returns.
+ */
+#define ERR_FAIL_INDEX_EDMSG(m_index, m_size, m_msg) \
+ if (unlikely((m_index) < 0 || (m_index) >= (m_size))) { \
+ _err_print_index_error(FUNCTION_STR, __FILE__, __LINE__, m_index, m_size, _STR(m_index), _STR(m_size), m_msg, true); \
+ return; \
+ } else \
+ ((void)0)
+
+/**
* Try using `ERR_FAIL_INDEX_V_MSG`.
* Only use this macro if there is no sensible error message.
*
@@ -161,6 +172,17 @@ void _err_print_index_error(const char *p_function, const char *p_file, int p_li
((void)0)
/**
+ * Ensures an integer index `m_index` is less than `m_size` and greater than or equal to 0.
+ * If not, prints `m_msg`, notifies in the editor, and the current function returns `m_retval`.
+ */
+#define ERR_FAIL_INDEX_V_EDMSG(m_index, m_size, m_retval, m_msg) \
+ if (unlikely((m_index) < 0 || (m_index) >= (m_size))) { \
+ _err_print_index_error(FUNCTION_STR, __FILE__, __LINE__, m_index, m_size, _STR(m_index), _STR(m_size), m_msg, true); \
+ return m_retval; \
+ } else \
+ ((void)0)
+
+/**
* Try using `ERR_FAIL_INDEX_MSG` or `ERR_FAIL_INDEX_V_MSG`.
* Only use this macro if there is no sensible fallback i.e. the error is unrecoverable, and
* there is no sensible error message.
@@ -215,6 +237,16 @@ void _err_print_index_error(const char *p_function, const char *p_file, int p_li
return; \
} else \
((void)0)
+/**
+ * Ensures an unsigned integer index `m_index` is less than `m_size`.
+ * If not, prints `m_msg`, notifies in the editor, and the current function returns.
+ */
+#define ERR_FAIL_UNSIGNED_INDEX_EDMSG(m_index, m_size, m_msg) \
+ if (unlikely((m_index) >= (m_size))) { \
+ _err_print_index_error(FUNCTION_STR, __FILE__, __LINE__, m_index, m_size, _STR(m_index), _STR(m_size), m_msg, true); \
+ return; \
+ } else \
+ ((void)0)
/**
* Try using `ERR_FAIL_UNSIGNED_INDEX_V_MSG`.
@@ -242,6 +274,17 @@ void _err_print_index_error(const char *p_function, const char *p_file, int p_li
((void)0)
/**
+ * Ensures an unsigned integer index `m_index` is less than `m_size`.
+ * If not, prints `m_msg`, notifies in the editor, and the current function returns `m_retval`.
+ */
+#define ERR_FAIL_UNSIGNED_INDEX_V_EDMSG(m_index, m_size, m_retval, m_msg) \
+ if (unlikely((m_index) >= (m_size))) { \
+ _err_print_index_error(FUNCTION_STR, __FILE__, __LINE__, m_index, m_size, _STR(m_index), _STR(m_size), m_msg, true); \
+ return m_retval; \
+ } else \
+ ((void)0)
+
+/**
* Try using `ERR_FAIL_UNSIGNED_INDEX_MSG` or `ERR_FAIL_UNSIGNED_INDEX_V_MSG`.
* Only use this macro if there is no sensible fallback i.e. the error is unrecoverable, and
* there is no sensible error message.
@@ -298,6 +341,17 @@ void _err_print_index_error(const char *p_function, const char *p_file, int p_li
((void)0)
/**
+ * Ensures a pointer `m_param` is not null.
+ * If it is null, prints `m_msg`, notifies in the editor, and the current function returns.
+ */
+#define ERR_FAIL_NULL_EDMSG(m_param, m_msg) \
+ if (unlikely(m_param == nullptr)) { \
+ _err_print_error(FUNCTION_STR, __FILE__, __LINE__, "Parameter \"" _STR(m_param) "\" is null.", m_msg, true); \
+ return; \
+ } else \
+ ((void)0)
+
+/**
* Try using `ERR_FAIL_NULL_V_MSG`.
* Only use this macro if there is no sensible error message.
*
@@ -323,6 +377,17 @@ void _err_print_index_error(const char *p_function, const char *p_file, int p_li
((void)0)
/**
+ * Ensures a pointer `m_param` is not null.
+ * If it is null, prints `m_msg`, notifies in the editor, and the current function returns `m_retval`.
+ */
+#define ERR_FAIL_NULL_V_EDMSG(m_param, m_retval, m_msg) \
+ if (unlikely(m_param == nullptr)) { \
+ _err_print_error(FUNCTION_STR, __FILE__, __LINE__, "Parameter \"" _STR(m_param) "\" is null.", m_msg, true); \
+ return m_retval; \
+ } else \
+ ((void)0)
+
+/**
* Try using `ERR_FAIL_COND_MSG`.
* Only use this macro if there is no sensible error message.
* If checking for null use ERR_FAIL_NULL_MSG instead.
@@ -353,6 +418,20 @@ void _err_print_index_error(const char *p_function, const char *p_file, int p_li
((void)0)
/**
+ * Ensures `m_cond` is false.
+ * If `m_cond` is true, prints `m_msg`, notifies in the editor, and the current function returns.
+ *
+ * If checking for null use ERR_FAIL_NULL_MSG instead.
+ * If checking index bounds use ERR_FAIL_INDEX_MSG instead.
+ */
+#define ERR_FAIL_COND_EDMSG(m_cond, m_msg) \
+ if (unlikely(m_cond)) { \
+ _err_print_error(FUNCTION_STR, __FILE__, __LINE__, "Condition \"" _STR(m_cond) "\" is true.", m_msg, true); \
+ return; \
+ } else \
+ ((void)0)
+
+/**
* Try using `ERR_FAIL_COND_V_MSG`.
* Only use this macro if there is no sensible error message.
* If checking for null use ERR_FAIL_NULL_V_MSG instead.
@@ -383,6 +462,20 @@ void _err_print_index_error(const char *p_function, const char *p_file, int p_li
((void)0)
/**
+ * Ensures `m_cond` is false.
+ * If `m_cond` is true, prints `m_msg`, notifies in the editor, and the current function returns `m_retval`.
+ *
+ * If checking for null use ERR_FAIL_NULL_V_MSG instead.
+ * If checking index bounds use ERR_FAIL_INDEX_V_MSG instead.
+ */
+#define ERR_FAIL_COND_V_EDMSG(m_cond, m_retval, m_msg) \
+ if (unlikely(m_cond)) { \
+ _err_print_error(FUNCTION_STR, __FILE__, __LINE__, "Condition \"" _STR(m_cond) "\" is true. Returning: " _STR(m_retval), m_msg, true); \
+ return m_retval; \
+ } else \
+ ((void)0)
+
+/**
* Try using `ERR_CONTINUE_MSG`.
* Only use this macro if there is no sensible error message.
*
@@ -408,6 +501,17 @@ void _err_print_index_error(const char *p_function, const char *p_file, int p_li
((void)0)
/**
+ * Ensures `m_cond` is false.
+ * If `m_cond` is true, prints `m_msg`, notifies in the editor, and the current loop continues.
+ */
+#define ERR_CONTINUE_EDMSG(m_cond, m_msg) \
+ if (unlikely(m_cond)) { \
+ _err_print_error(FUNCTION_STR, __FILE__, __LINE__, "Condition \"" _STR(m_cond) "\" is true. Continuing.", m_msg, true); \
+ continue; \
+ } else \
+ ((void)0)
+
+/**
* Try using `ERR_BREAK_MSG`.
* Only use this macro if there is no sensible error message.
*
@@ -433,6 +537,17 @@ void _err_print_index_error(const char *p_function, const char *p_file, int p_li
((void)0)
/**
+ * Ensures `m_cond` is false.
+ * If `m_cond` is true, prints `m_msg`, notifies in the editor, and the current loop breaks.
+ */
+#define ERR_BREAK_EDMSG(m_cond, m_msg) \
+ if (unlikely(m_cond)) { \
+ _err_print_error(FUNCTION_STR, __FILE__, __LINE__, "Condition \"" _STR(m_cond) "\" is true. Breaking.", m_msg, true); \
+ break; \
+ } else \
+ ((void)0)
+
+/**
* Try using `ERR_FAIL_COND_MSG` or `ERR_FAIL_COND_V_MSG`.
* Only use this macro if there is no sensible fallback i.e. the error is unrecoverable, and
* there is no sensible error message.
@@ -491,6 +606,19 @@ void _err_print_index_error(const char *p_function, const char *p_file, int p_li
((void)0)
/**
+ * Try using `ERR_FAIL_COND_MSG`.
+ * Only use this macro if more complex error detection or recovery is required.
+ *
+ * Prints `m_msg`, notifies in the editor, and the current function returns.
+ */
+#define ERR_FAIL_EDMSG(m_msg) \
+ if (true) { \
+ _err_print_error(FUNCTION_STR, __FILE__, __LINE__, "Method/function failed.", m_msg, true); \
+ return; \
+ } else \
+ ((void)0)
+
+/**
* Try using `ERR_FAIL_COND_V_MSG` or `ERR_FAIL_V_MSG`.
* Only use this macro if more complex error detection or recovery is required, and
* there is no sensible error message.
@@ -518,6 +646,19 @@ void _err_print_index_error(const char *p_function, const char *p_file, int p_li
((void)0)
/**
+ * Try using `ERR_FAIL_COND_V_MSG`.
+ * Only use this macro if more complex error detection or recovery is required.
+ *
+ * Prints `m_msg`, notifies in the editor, and the current function returns `m_retval`.
+ */
+#define ERR_FAIL_V_EDMSG(m_retval, m_msg) \
+ if (true) { \
+ _err_print_error(FUNCTION_STR, __FILE__, __LINE__, "Method/function failed. Returning: " _STR(m_retval), m_msg, true); \
+ return m_retval; \
+ } else \
+ ((void)0)
+
+/**
* Try using `ERR_FAIL_COND_MSG`, `ERR_FAIL_COND_V_MSG`, `ERR_CONTINUE_MSG` or ERR_BREAK_MSG.
* Only use this macro at the start of a function that has not been implemented yet, or
* if more complex error detection or recovery is required.
@@ -528,6 +669,16 @@ void _err_print_index_error(const char *p_function, const char *p_file, int p_li
_err_print_error(FUNCTION_STR, __FILE__, __LINE__, m_msg)
/**
+ * Try using `ERR_FAIL_COND_MSG`, `ERR_FAIL_COND_V_MSG`, `ERR_CONTINUE_MSG` or ERR_BREAK_MSG.
+ * Only use this macro at the start of a function that has not been implemented yet, or
+ * if more complex error detection or recovery is required.
+ *
+ * Prints `m_msg` and notifies the editor.
+ */
+#define ERR_PRINT_ED(m_msg) \
+ _err_print_error(FUNCTION_STR, __FILE__, __LINE__, m_msg, )
+
+/**
* Prints `m_msg` once during the application lifetime.
*/
#define ERR_PRINT_ONCE(m_msg) \
@@ -540,6 +691,19 @@ void _err_print_index_error(const char *p_function, const char *p_file, int p_li
} else \
((void)0)
+/**
+ * Prints `m_msg` and notifies the editor once during the application lifetime.
+ */
+#define ERR_PRINT_ONCE_ED(m_msg) \
+ if (true) { \
+ static bool first_print = true; \
+ if (first_print) { \
+ _err_print_error(FUNCTION_STR, __FILE__, __LINE__, m_msg, true); \
+ first_print = false; \
+ } \
+ } else \
+ ((void)0)
+
// Print warning message macros.
/**
@@ -548,52 +712,75 @@ void _err_print_index_error(const char *p_function, const char *p_file, int p_li
* If warning about deprecated usage, use `WARN_DEPRECATED` or `WARN_DEPRECATED_MSG` instead.
*/
#define WARN_PRINT(m_msg) \
- _err_print_error(FUNCTION_STR, __FILE__, __LINE__, m_msg, ERR_HANDLER_WARNING)
+ _err_print_error(FUNCTION_STR, __FILE__, __LINE__, m_msg, false, ERR_HANDLER_WARNING)
+
+/**
+ * Prints `m_msg` and notifies the editor.
+ *
+ * If warning about deprecated usage, use `WARN_DEPRECATED` or `WARN_DEPRECATED_MSG` instead.
+ */
+#define WARN_PRINT_ED(m_msg) \
+ _err_print_error(FUNCTION_STR, __FILE__, __LINE__, m_msg, true, ERR_HANDLER_WARNING)
/**
* Prints `m_msg` once during the application lifetime.
*
* If warning about deprecated usage, use `WARN_DEPRECATED` or `WARN_DEPRECATED_MSG` instead.
*/
-#define WARN_PRINT_ONCE(m_msg) \
- if (true) { \
- static bool first_print = true; \
- if (first_print) { \
- _err_print_error(FUNCTION_STR, __FILE__, __LINE__, m_msg, ERR_HANDLER_WARNING); \
- first_print = false; \
- } \
- } else \
+#define WARN_PRINT_ONCE(m_msg) \
+ if (true) { \
+ static bool first_print = true; \
+ if (first_print) { \
+ _err_print_error(FUNCTION_STR, __FILE__, __LINE__, m_msg, false, ERR_HANDLER_WARNING); \
+ first_print = false; \
+ } \
+ } else \
((void)0)
-// Print deprecated warning message macros.
-
/**
- * Warns that the current function is deprecated.
+ * Prints `m_msg` and notifies the editor once during the application lifetime.
+ *
+ * If warning about deprecated usage, use `WARN_DEPRECATED` or `WARN_DEPRECATED_MSG` instead.
*/
-#define WARN_DEPRECATED \
- if (true) { \
- static SafeFlag warning_shown; \
- if (!warning_shown.is_set()) { \
- _err_print_error(FUNCTION_STR, __FILE__, __LINE__, "This method has been deprecated and will be removed in the future.", ERR_HANDLER_WARNING); \
- warning_shown.set(); \
- } \
- } else \
+#define WARN_PRINT_ONCE_ED(m_msg) \
+ if (true) { \
+ static bool first_print = true; \
+ if (first_print) { \
+ _err_print_error(FUNCTION_STR, __FILE__, __LINE__, m_msg, true, ERR_HANDLER_WARNING); \
+ first_print = false; \
+ } \
+ } else \
((void)0)
+// Print deprecated warning message macros.
+
/**
- * Warns that the current function is deprecated and prints `m_msg`.
+ * Warns that the current function is deprecated.
*/
-#define WARN_DEPRECATED_MSG(m_msg) \
+#define WARN_DEPRECATED \
if (true) { \
static SafeFlag warning_shown; \
if (!warning_shown.is_set()) { \
- _err_print_error(FUNCTION_STR, __FILE__, __LINE__, "This method has been deprecated and will be removed in the future.", m_msg, ERR_HANDLER_WARNING); \
+ _err_print_error(FUNCTION_STR, __FILE__, __LINE__, "This method has been deprecated and will be removed in the future.", false, ERR_HANDLER_WARNING); \
warning_shown.set(); \
} \
} else \
((void)0)
/**
+ * Warns that the current function is deprecated and prints `m_msg`.
+ */
+#define WARN_DEPRECATED_MSG(m_msg) \
+ if (true) { \
+ static SafeFlag warning_shown; \
+ if (!warning_shown.is_set()) { \
+ _err_print_error(FUNCTION_STR, __FILE__, __LINE__, "This method has been deprecated and will be removed in the future.", m_msg, false, ERR_HANDLER_WARNING); \
+ warning_shown.set(); \
+ } \
+ } else \
+ ((void)0)
+
+/**
* Do not use.
* If the application should never reach this point use CRASH_NOW_MSG(m_msg) to explain why.
*
diff --git a/core/extension/extension_api_dump.cpp b/core/extension/extension_api_dump.cpp
index 03b2426370..fc74293d0d 100644
--- a/core/extension/extension_api_dump.cpp
+++ b/core/extension/extension_api_dump.cpp
@@ -40,7 +40,7 @@
static String get_type_name(const PropertyInfo &p_info) {
if (p_info.type == Variant::INT && (p_info.hint == PROPERTY_HINT_INT_IS_POINTER)) {
- if (p_info.hint_string == "") {
+ if (p_info.hint_string.is_empty()) {
return "void*";
} else {
return p_info.hint_string + "*";
@@ -340,7 +340,7 @@ Dictionary NativeExtensionAPIDump::generate_extension_api() {
int value = CoreConstants::get_global_constant_value(i);
String enum_name = CoreConstants::get_global_constant_enum(i);
String name = CoreConstants::get_global_constant_name(i);
- if (enum_name != String()) {
+ if (!enum_name.is_empty()) {
enum_list[enum_name].push_back(Pair<String, int>(name, value));
} else {
Dictionary d;
diff --git a/core/extension/gdnative_interface.cpp b/core/extension/gdnative_interface.cpp
index ff09b0b86c..0c9b344a37 100644
--- a/core/extension/gdnative_interface.cpp
+++ b/core/extension/gdnative_interface.cpp
@@ -51,13 +51,13 @@ static void gdnative_free(void *p_mem) {
// Helper print functions.
static void gdnative_print_error(const char *p_description, const char *p_function, const char *p_file, int32_t p_line) {
- _err_print_error(p_function, p_file, p_line, p_description, ERR_HANDLER_ERROR);
+ _err_print_error(p_function, p_file, p_line, p_description, false, ERR_HANDLER_ERROR);
}
static void gdnative_print_warning(const char *p_description, const char *p_function, const char *p_file, int32_t p_line) {
- _err_print_error(p_function, p_file, p_line, p_description, ERR_HANDLER_WARNING);
+ _err_print_error(p_function, p_file, p_line, p_description, false, ERR_HANDLER_WARNING);
}
static void gdnative_print_script_error(const char *p_description, const char *p_function, const char *p_file, int32_t p_line) {
- _err_print_error(p_function, p_file, p_line, p_description, ERR_HANDLER_SCRIPT);
+ _err_print_error(p_function, p_file, p_line, p_description, false, ERR_HANDLER_SCRIPT);
}
// Variant functions
@@ -774,13 +774,25 @@ static GDNativeTypePtr gdnative_packed_vector3_array_operator_index_const(const
static GDNativeVariantPtr gdnative_array_operator_index(GDNativeTypePtr p_self, GDNativeInt p_index) {
Array *self = (Array *)p_self;
ERR_FAIL_INDEX_V(p_index, self->size(), nullptr);
- return (GDNativeTypePtr)&self[p_index];
+ return (GDNativeVariantPtr)&self->operator[](p_index);
}
static GDNativeVariantPtr gdnative_array_operator_index_const(const GDNativeTypePtr p_self, GDNativeInt p_index) {
const Array *self = (const Array *)p_self;
ERR_FAIL_INDEX_V(p_index, self->size(), nullptr);
- return (GDNativeTypePtr)&self[p_index];
+ return (GDNativeVariantPtr)&self->operator[](p_index);
+}
+
+/* Dictionary functions */
+
+static GDNativeVariantPtr gdnative_dictionary_operator_index(GDNativeTypePtr p_self, const GDNativeVariantPtr p_key) {
+ Dictionary *self = (Dictionary *)p_self;
+ return (GDNativeVariantPtr)&self->operator[](*(const Variant *)p_key);
+}
+
+static GDNativeVariantPtr gdnative_dictionary_operator_index_const(const GDNativeTypePtr p_self, const GDNativeVariantPtr p_key) {
+ const Dictionary *self = (const Dictionary *)p_self;
+ return (GDNativeVariantPtr)&self->operator[](*(const Variant *)p_key);
}
/* OBJECT API */
@@ -815,16 +827,21 @@ static GDNativeObjectPtr gdnative_global_get_singleton(const char *p_name) {
return (GDNativeObjectPtr)Engine::get_singleton()->get_singleton_object(String(p_name));
}
-static void *gdnative_object_get_instance_binding(GDNativeObjectPtr p_instance, void *p_token, const GDNativeInstanceBindingCallbacks *p_callbacks) {
- Object *o = (Object *)p_instance;
+static void *gdnative_object_get_instance_binding(GDNativeObjectPtr p_object, void *p_token, const GDNativeInstanceBindingCallbacks *p_callbacks) {
+ Object *o = (Object *)p_object;
return o->get_instance_binding(p_token, p_callbacks);
}
-static void gdnative_object_set_instance_binding(GDNativeObjectPtr p_instance, void *p_token, void *p_binding, const GDNativeInstanceBindingCallbacks *p_callbacks) {
- Object *o = (Object *)p_instance;
+static void gdnative_object_set_instance_binding(GDNativeObjectPtr p_object, void *p_token, void *p_binding, const GDNativeInstanceBindingCallbacks *p_callbacks) {
+ Object *o = (Object *)p_object;
o->set_instance_binding(p_token, p_binding, p_callbacks);
}
+static void gdnative_object_set_instance(GDNativeObjectPtr p_object, const char *p_classname, GDExtensionClassInstancePtr p_instance) {
+ Object *o = (Object *)p_object;
+ ClassDB::set_object_extension_instance(o, p_classname, p_instance);
+}
+
static GDNativeObjectPtr gdnative_object_get_instance_from_id(GDObjectInstanceID p_instance_id) {
return (GDNativeObjectPtr)ObjectDB::get_instance(ObjectID(p_instance_id));
}
@@ -854,19 +871,8 @@ static GDNativeMethodBindPtr gdnative_classdb_get_method_bind(const char *p_clas
return (GDNativeMethodBindPtr)mb;
}
-static GDNativeClassConstructor gdnative_classdb_get_constructor(const char *p_classname, GDNativeExtensionPtr *r_extension) {
- ClassDB::ClassInfo *class_info = ClassDB::classes.getptr(StringName(p_classname));
- if (class_info) {
- if (r_extension) {
- *r_extension = class_info->native_extension;
- }
- return (GDNativeClassConstructor)class_info->creation_func;
- }
- return nullptr;
-}
-
-static GDNativeObjectPtr gdnative_classdb_construct_object(GDNativeClassConstructor p_constructor, GDNativeExtensionPtr p_extension) {
- return (GDNativeObjectPtr)ClassDB::construct_object((Object * (*)()) p_constructor, (ObjectNativeExtension *)p_extension);
+static GDNativeObjectPtr gdnative_classdb_construct_object(const char *p_classname) {
+ return (GDNativeObjectPtr)ClassDB::instantiate(p_classname);
}
static void *gdnative_classdb_get_class_tag(const char *p_classname) {
@@ -1001,6 +1007,11 @@ void gdnative_setup_interface(GDNativeInterface *p_interface) {
gdni.array_operator_index = gdnative_array_operator_index;
gdni.array_operator_index_const = gdnative_array_operator_index_const;
+ /* Dictionary functions */
+
+ gdni.dictionary_operator_index = gdnative_dictionary_operator_index;
+ gdni.dictionary_operator_index_const = gdnative_dictionary_operator_index_const;
+
/* OBJECT */
gdni.object_method_bind_call = gdnative_object_method_bind_call;
@@ -1009,6 +1020,7 @@ void gdnative_setup_interface(GDNativeInterface *p_interface) {
gdni.global_get_singleton = gdnative_global_get_singleton;
gdni.object_get_instance_binding = gdnative_object_get_instance_binding;
gdni.object_set_instance_binding = gdnative_object_set_instance_binding;
+ gdni.object_set_instance = gdnative_object_set_instance;
gdni.object_cast_to = gdnative_object_cast_to;
gdni.object_get_instance_from_id = gdnative_object_get_instance_from_id;
@@ -1016,7 +1028,6 @@ void gdnative_setup_interface(GDNativeInterface *p_interface) {
/* CLASSDB */
- gdni.classdb_get_constructor = gdnative_classdb_get_constructor;
gdni.classdb_construct_object = gdnative_classdb_construct_object;
gdni.classdb_get_method_bind = gdnative_classdb_get_method_bind;
gdni.classdb_get_class_tag = gdnative_classdb_get_class_tag;
diff --git a/core/extension/gdnative_interface.h b/core/extension/gdnative_interface.h
index 8f8cb5a3e0..2191d99dea 100644
--- a/core/extension/gdnative_interface.h
+++ b/core/extension/gdnative_interface.h
@@ -211,7 +211,7 @@ typedef const char *(*GDNativeExtensionClassToString)(GDExtensionClassInstancePt
typedef void (*GDNativeExtensionClassReference)(GDExtensionClassInstancePtr p_instance);
typedef void (*GDNativeExtensionClassUnreference)(GDExtensionClassInstancePtr p_instance);
typedef void (*GDNativeExtensionClassCallVirtual)(GDExtensionClassInstancePtr p_instance, const GDNativeTypePtr *p_args, GDNativeTypePtr r_ret);
-typedef GDExtensionClassInstancePtr (*GDNativeExtensionClassCreateInstance)(void *p_userdata);
+typedef GDNativeObjectPtr (*GDNativeExtensionClassCreateInstance)(void *p_userdata);
typedef void (*GDNativeExtensionClassFreeInstance)(void *p_userdata, GDExtensionClassInstancePtr p_instance);
typedef void (*GDNativeExtensionClassObjectInstance)(GDExtensionClassInstancePtr p_instance, GDNativeObjectPtr p_object_instance);
typedef GDNativeExtensionClassCallVirtual (*GDNativeExtensionClassGetVirtual)(void *p_userdata, const char *p_name);
@@ -227,7 +227,6 @@ typedef struct {
GDNativeExtensionClassUnreference unreference_func;
GDNativeExtensionClassCreateInstance create_instance_func; /* this one is mandatory */
GDNativeExtensionClassFreeInstance free_instance_func; /* this one is mandatory */
- GDNativeExtensionClassObjectInstance object_instance_func; /* this one is mandatory */
GDNativeExtensionClassGetVirtual get_virtual_func;
void *class_userdata;
} GDNativeExtensionClassCreationInfo;
@@ -417,23 +416,29 @@ typedef struct {
GDNativeVariantPtr (*array_operator_index)(GDNativeTypePtr p_self, GDNativeInt p_index); // p_self should be an Array ptr
GDNativeVariantPtr (*array_operator_index_const)(const GDNativeTypePtr p_self, GDNativeInt p_index); // p_self should be an Array ptr
+ /* Dictionary functions */
+
+ GDNativeVariantPtr (*dictionary_operator_index)(GDNativeTypePtr p_self, const GDNativeVariantPtr p_key); // p_self should be an Dictionary ptr
+ GDNativeVariantPtr (*dictionary_operator_index_const)(const GDNativeTypePtr p_self, const GDNativeVariantPtr p_key); // p_self should be an Dictionary ptr
+
/* OBJECT */
void (*object_method_bind_call)(const GDNativeMethodBindPtr p_method_bind, GDNativeObjectPtr p_instance, const GDNativeVariantPtr *p_args, GDNativeInt p_arg_count, GDNativeVariantPtr r_ret, GDNativeCallError *r_error);
void (*object_method_bind_ptrcall)(const GDNativeMethodBindPtr p_method_bind, GDNativeObjectPtr p_instance, const GDNativeTypePtr *p_args, GDNativeTypePtr r_ret);
void (*object_destroy)(GDNativeObjectPtr p_o);
GDNativeObjectPtr (*global_get_singleton)(const char *p_name);
+
void *(*object_get_instance_binding)(GDNativeObjectPtr p_o, void *p_token, const GDNativeInstanceBindingCallbacks *p_callbacks);
void (*object_set_instance_binding)(GDNativeObjectPtr p_o, void *p_token, void *p_binding, const GDNativeInstanceBindingCallbacks *p_callbacks);
+ void (*object_set_instance)(GDNativeObjectPtr p_o, const char *p_classname, GDExtensionClassInstancePtr p_instance); /* p_classname should be a registered extension class and should extend the p_o object's class. */
+
GDNativeObjectPtr (*object_cast_to)(const GDNativeObjectPtr p_object, void *p_class_tag);
GDNativeObjectPtr (*object_get_instance_from_id)(GDObjectInstanceID p_instance_id);
GDObjectInstanceID (*object_get_instance_id)(const GDNativeObjectPtr p_object);
/* CLASSDB */
-
- GDNativeClassConstructor (*classdb_get_constructor)(const char *p_classname, GDNativeExtensionPtr *r_extension);
- GDNativeObjectPtr (*classdb_construct_object)(GDNativeClassConstructor p_constructor, GDNativeExtensionPtr p_extension);
+ GDNativeObjectPtr (*classdb_construct_object)(const char *p_classname); /* The passed class must be a built-in godot class, or an already-registered extension class. In both case, object_set_instance should be called to fully initialize the object. */
GDNativeMethodBindPtr (*classdb_get_method_bind)(const char *p_classname, const char *p_methodname, GDNativeInt p_hash);
void *(*classdb_get_class_tag)(const char *p_classname);
diff --git a/core/extension/native_extension.cpp b/core/extension/native_extension.cpp
index a6b0a708c3..cfd3ac8099 100644
--- a/core/extension/native_extension.cpp
+++ b/core/extension/native_extension.cpp
@@ -156,7 +156,6 @@ void NativeExtension::_register_extension_class(const GDNativeExtensionClassLibr
extension->native_extension.unreference = p_extension_funcs->unreference_func;
extension->native_extension.class_userdata = p_extension_funcs->class_userdata;
extension->native_extension.create_instance = p_extension_funcs->create_instance_func;
- extension->native_extension.set_object_instance = p_extension_funcs->object_instance_func;
extension->native_extension.free_instance = p_extension_funcs->free_instance_func;
extension->native_extension.get_virtual = p_extension_funcs->get_virtual_func;
@@ -398,7 +397,7 @@ RES NativeExtensionResourceLoader::load(const String &p_path, const String &p_or
}
}
- if (library_path == String()) {
+ if (library_path.is_empty()) {
if (r_error) {
*r_error = ERR_FILE_NOT_FOUND;
}
diff --git a/core/extension/native_extension_manager.cpp b/core/extension/native_extension_manager.cpp
index c8755250d5..043843ea31 100644
--- a/core/extension/native_extension_manager.cpp
+++ b/core/extension/native_extension_manager.cpp
@@ -115,7 +115,7 @@ void NativeExtensionManager::load_extensions() {
FileAccessRef f = FileAccess::open(NativeExtension::get_extension_list_config_file(), FileAccess::READ);
while (f && !f->eof_reached()) {
String s = f->get_line().strip_edges();
- if (s != String()) {
+ if (!s.is_empty()) {
LoadStatus err = load_extension(s);
ERR_CONTINUE_MSG(err == LOAD_STATUS_FAILED, "Error loading extension: " + s);
}
diff --git a/core/input/gamecontrollerdb.txt b/core/input/gamecontrollerdb.txt
index f136d83496..0da8f8dfdb 100644
--- a/core/input/gamecontrollerdb.txt
+++ b/core/input/gamecontrollerdb.txt
@@ -1,11 +1,15 @@
-# Game Controller DB for SDL in 2.0.9 format
+# Game Controller DB for SDL in 2.0.16 format
# Source: https://github.com/gabomdq/SDL_GameControllerDB
# 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,
+03000000d0160000600a000000000000,4Play,a:b1,b:b3,back:b4,dpdown:b11,dpleft:b12,dpright:b13,dpup:b10,leftshoulder:b6,leftstick:b14,lefttrigger:b8,leftx:a0,lefty:a1,rightshoulder:b7,rightstick:b15,righttrigger:b9,rightx:a3,righty:a4,start:b5,x:b0,y:b2,platform:Windows,
+03000000d0160000040d000000000000,4Play,a:b1,b:b3,back:b4,dpdown:b11,dpleft:b12,dpright:b13,dpup:b10,leftshoulder:b6,leftstick:b14,lefttrigger:b8,leftx:a0,lefty:a1,rightshoulder:b7,rightstick:b15,righttrigger:b9,rightx:a3,righty:a4,start:b5,x:b0,y:b2,platform:Windows,
+03000000d0160000050d000000000000,4Play,a:b1,b:b3,back:b4,dpdown:b11,dpleft:b12,dpright:b13,dpup:b10,leftshoulder:b6,leftstick:b14,lefttrigger:b8,leftx:a0,lefty:a1,rightshoulder:b7,rightstick:b15,righttrigger:b9,rightx:a3,righty:a4,start:b5,x:b0,y:b2,platform:Windows,
+03000000d0160000060d000000000000,4Play,a:b1,b:b3,back:b4,dpdown:b11,dpleft:b12,dpright:b13,dpup:b10,leftshoulder:b6,leftstick:b14,lefttrigger:b8,leftx:a0,lefty:a1,rightshoulder:b7,rightstick:b15,righttrigger:b9,rightx:a3,righty:a4,start:b5,x:b0,y:b2,platform:Windows,
+03000000d0160000070d000000000000,4Play,a:b1,b:b3,back:b4,dpdown:b11,dpleft:b12,dpright:b13,dpup:b10,leftshoulder:b6,leftstick:b14,lefttrigger:b8,leftx:a0,lefty:a1,rightshoulder:b7,rightstick:b15,righttrigger:b9,rightx:a3,righty:a4,start:b5,x:b0,y:b2,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,
+03000000c82d000011ab000000000000,8BitDo F30 Arcade Joystick,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,
@@ -14,12 +18,16 @@
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,
+03000000c82d0000e002000000000000,8BitDo N30,a:b0,b:b1,back:b7,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftx:a0,lefty:a1,start:b6,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,
+03000000c82d000012ab000000000000,8BitDo NES30,a:b1,b:b0,back:b10,leftshoulder:b6,leftx:a0,lefty:a1,rightshoulder:b7,start:b11,x:b4,y:b3,platform:Windows,
+03000000c82d00002038000000000000,8Bitdo NES30 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,
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,
+03000000c82d00000751000000000000,8BitDo P30,a:b0,b:b1,back:b10,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b6,lefttrigger:b8,leftx:a0,lefty:a1,rightshoulder:b7,righttrigger:b9,start:b11,x:b3,y:b4,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,
@@ -36,6 +44,7 @@
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,
+03000000c82d00000021000000000000,8BitDo SN30 Pro,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:a5,start:b11,x:b3,y:b4,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,
@@ -43,12 +52,19 @@
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,
+03000000d81d00000e00000000000000,AC02,a:b0,b:b1,back:b9,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b6,leftstick:b10,lefttrigger:b7,leftx:a0,lefty:a1,rightshoulder:b2,rightstick:b11,righttrigger:b3,rightx:a2,righty:a5,start:b8,x:b4,y:b5,platform:Windows,
+030000008f0e00001200000000000000,Acme GA02,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,
+03000000c01100000355000000000000,Acrux,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,
+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,
+030000006d0400000bc2000000000000,Action Pad,a:b0,b:b1,back:b2,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b6,leftstick:b8,lefttrigger:a5~,leftx:a0,lefty:a1,rightshoulder:b7,rightstick:b5,righttrigger:a2~,start:b8,x:b3,y:b4,platform:Windows,
+03000000d1180000402c000000000000,ADT1,a:b0,b:b1,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:a3,rightx:a2,righty:a5,x:b3,y:b4,platform:Windows,
030000006f0e00001413000000000000,Afterglow,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,
+030000006f0e00001301000000000000,Afterglow,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,
+030000006f0e00003901000000000000,Afterglow,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,
+030000006f0e00001302000000000000,Afterglow,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,
+03000000ab1200000103000000000000,Afterglow,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,
+030000006f0e00001304000000000000,Afterglow,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,
+03000000ad1b000000f9000000000000,Afterglow,a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b8,lefttrigger:b10,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b9,righttrigger:b11,rightx:a3,righty:a4,start:b7,x:b2,y:b3,platform:Windows,
03000000341a00003608000000000000,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,
030000006f0e00000263000000000000,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,
030000006f0e00001101000000000000,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,
@@ -56,68 +72,147 @@
030000006f0e00001402000000000000,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,
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,
+03000000120c00000288000000000000,Nyko Air Flo Xbox Controller,a:b0,b:b1,back:b7,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b8,lefttrigger:b10,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b9,righttrigger:b11,rightx:a3,righty:a4,start:b6,x:b2,y:b3,platform:Windows,
+03000000d62000001d57000000000000,Nyko Airflo PS3 Controller,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b0,y:b3,platform:Windows,
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,
+03000000830500000160000000000000,Arcade,a:b0,b:b1,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b6,lefttrigger:b7,leftx:a0,lefty:a1,rightshoulder:b2,righttrigger:b3,x:b4,y:b4,platform:Windows,
+03000000120c0000100e000000000000,Armor 3,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,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,
+03000000869800002500000000000000,Astro C40 TR PS4 Controller,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b10,lefttrigger:a3,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:a4,rightx:a2,righty:a5,start:b9,x:b0,y:b3,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,
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,
+03000000fd0500000230000000000000,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:a2,righty:a5,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,
+03000000e4150000103f000000000000,Batarang,a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b8,lefttrigger:b10,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b9,righttrigger:b11,rightx:a3,righty:a4,start:b7,x:b2,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,
+03000000ad1b000001f9000000000000,BB 070,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,
03000000d62000002a79000000000000,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:Windows,
+030000000d0500000208000000000000,Belkin Nostromo N40,a:b0,b:b1,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:a5,righty:a2,start:b9,x:b2,y:b3,platform:Windows,
03000000bc2000006012000000000000,Betop 2126F,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,
03000000bc2000000055000000000000,Betop BFM Gamepad,a:b0,b:b1,back:b10,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b6,leftstick:b13,lefttrigger:b8,leftx:a0,lefty:a1,rightshoulder:b7,rightstick:b14,righttrigger:b9,rightx:a3,righty:a4,start:b11,x:b3,y:b4,platform:Windows,
03000000bc2000006312000000000000,Betop Controller,a:b2,b:b1,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b3,y:b0,platform:Windows,
-03000000bc2000006321000000000000,BETOP CONTROLLER,a:b2,b:b1,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b3,y:b0,platform:Windows,
+03000000bc2000006321000000000000,Betop Controller,a:b2,b:b1,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b3,y:b0,platform:Windows,
03000000bc2000006412000000000000,Betop Controller,a:b2,b:b1,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b3,y:b0,platform:Windows,
03000000c01100000555000000000000,Betop Controller,a:b2,b:b1,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b3,y:b0,platform:Windows,
03000000c01100000655000000000000,Betop Controller,a:b2,b:b1,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b3,y:b0,platform:Windows,
03000000790000000700000000000000,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,
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,
+030000006f0e00006401000000000000,BF One,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,rightx:a2,righty:a5,start:b7,x:b2,y:b3,platform:Windows,
+03000000300f00000202000000000000,Bigben,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:a5,righty:a2,start:b7,x:b2,y:b3,platform:Windows,
+030000006b1400000209000000000000,Bigben,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b0,y:b3,platform: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,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,
+03000000380700008232000000000000,Brawlpad,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,rightx:a2,righty:a3,start:b9,x:b0,y:b3,platform:Windows,
+03000000120c0000210e000000000000,Brook Mars PS4 Controller,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b0,y:b3,platform:Windows,
+03000000120c0000200e000000000000,Brook Mars PS4 Controller,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b0,y:b3,platform:Windows,
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,
+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,
+030000006d04000042c2000000000000,ChillStream,a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b8,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b9,rightx:a3,righty:a4,start:b7,x:b2,y:b3,platform:Windows,
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,
03000000457500000401000000000000,Cobra,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a5,start:b9,x:b0,y:b3,platform:Windows,
-030000005e0400008e02000000000000,Controller (XBOX 360 For Windows),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,
-030000005e040000a102000000000000,Controller (Xbox 360 Wireless Receiver for Windows),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,
-030000005e040000ff02000000000000,Controller (Xbox One For Windows) - Wired,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,
-030000005e040000ea02000000000000,Controller (Xbox One For Windows) - Wireless,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,
+030000000b0400003365000000000000,Competition Pro,a:b0,b:b1,back:b2,leftx:a0,lefty:a1,start:b3,platform:Windows,
+030000005e0400008e02000000000000,Xbox 360 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,
+030000005e040000a102000000000000,Xbox 360 Wireless Receiver,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,
+030000005e040000ff02000000000000,Wired Xbox One 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,
+030000005e040000ea02000000000000,Wireless Xbox One 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,
+030000004c050000c505000000000000,CronusMax Adapter,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,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,
+03000000d8140000cefa000000000000,Cthulhu,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a5,start:b9,x:b0,y:b3,platform:Windows,
+03000000d814000007cd000000000000,Cthulhu,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a5,start:b9,x:b0,y:b3,platform:Windows,
+03000000380700006352000000000000,Mad Catz CTRLR,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a5,start:b9,x:b0,y:b3,platform:Windows,
03000000260900008888000000000000,Cyber Gadget GameCube Controller,a:b0,b:b1,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,lefttrigger:a5,leftx:a0,lefty:a1,rightshoulder:b6,righttrigger:a4,rightx:a2,righty:a3~,start:b7,x:b2,y:b3,platform:Windows,
+030000003807000002cb000000000000,Cyborg,a:b0,b:b1,back:b6,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:a2,rightx:a3,righty:a4,start:b7,x:b2,y:b3,platform:Windows,
03000000a306000022f6000000000000,Cyborg V.3 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:+a3,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:-a3,rightx:a2,righty:a4,start:b9,x:b0,y:b3,platform:Windows,
+03000000f806000000a3000000000000,DA Leader,a:b7,b:b6,back:b10,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b0,leftstick:b8,lefttrigger:b1,leftx:a0,lefty:a1,rightshoulder:b2,rightstick:b9,righttrigger:b3,rightx:a2,righty:a3,start:b12,x:b4,y:b5,platform:Windows,
+030000001a1c00000001000000000000,Datel,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,rightx:a2,righty:a5,start:b9,x:b0,y:b3,platform:Windows,
03000000451300000830000000000000,Defender Game Racer X7,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,
030000007d0400000840000000000000,Destroyer Tiltpad,+leftx:h0.2,+lefty:h0.4,-leftx:h0.8,-lefty:h0.1,a:b1,b:b2,dpdown:+a1,dpleft:-a0,dpright:+a0,dpup:-a1,leftshoulder:b4,rightshoulder:b5,x:b0,y:b3,platform:Windows,
+03000000c0160000e105000000000000,Dual,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a3,righty:a4,start:b9,x:b0,y:b3,platform:Windows,
03000000791d00000103000000000000,Dual Box WII,a:b2,b:b1,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b10,leftshoulder:b6,lefttrigger:b4,leftx:a0,lefty:a1,rightshoulder:b7,righttrigger:b5,rightx:a2,righty:a3,start:b9,x:b3,y:b0,platform:Windows,
+030000007c1800000006000000000000,Dual Compat,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,
+030000004f040000070f000000000000,Dual Power,a:b8,b:b9,back:b4,dpdown:b1,dpleft:b2,dpright:b3,dpup:b0,leftshoulder:b13,leftstick:b6,lefttrigger:b14,leftx:a0,lefty:a1,rightshoulder:b12,rightstick:b7,righttrigger:b15,start:b5,x:b10,y:b11,platform:Windows,
+030000004f04000012b3000000000000,Dual Power 3,a:b0,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b10,lefttrigger:b5,leftx:a0,lefty:a1,rightshoulder:b6,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b1,y:b3,platform:Windows,
+030000004f04000020b3000000000000,Dual Trigger,a:b0,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b10,lefttrigger:b5,leftx:a0,lefty:a1,rightshoulder:b6,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b1,y:b3,platform:Windows,
03000000bd12000002e0000000000000,Dual USB Vibration Joystick,a:b2,b:b1,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b6,leftstick:b9,lefttrigger:b4,leftx:a0,lefty:a1,rightshoulder:b7,rightstick:b10,righttrigger:b5,rightx:a3,righty:a2,start:b11,x:b3,y:b0,platform:Windows,
+03000000ff1100003133000000000000,DualForce,a:b2,b:b3,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:b0,y:b1,platform:Windows,
030000008f0e00000910000000000000,DualShock 2,a:b2,b:b1,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b6,leftstick:b9,lefttrigger:b4,leftx:a0,lefty:a1,rightshoulder:b7,rightstick:b10,righttrigger:b5,rightx:a3,righty:a2,start:b11,x:b3,y:b0,platform:Windows,
-030000006f0e00003001000000000000,EA SPORTS 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,
+03000000317300000100000000000000,DualShock 3,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:a5,start:b11,x:b3,y:b4,platform:Windows,
+030000006f0e00003001000000000000,EA Sports 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,
+03000000fc0400000250000000000000,Easy Grip,a:b0,b:b1,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b6,lefttrigger:b7,leftx:a0,lefty:a1,rightshoulder:b5,righttrigger:b2,start:b9,x:b3,y:b4,platform:Windows,
+030000006e0500000a20000000000000,Elecom DUX60 MMO Gamepad,a:b2,b:b3,back:b17,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b8,leftstick:b14,lefttrigger:b12,leftx:a0,lefty:a1,rightshoulder:b11,rightstick:b15,righttrigger:b13,rightx:a3,righty:a4,start:b20,x:b0,y:b1,platform:Windows,
03000000b80500000410000000000000,Elecom Gamepad,a:b2,b:b3,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:b1,platform:Windows,
03000000b80500000610000000000000,Elecom Gamepad,a:b2,b:b3,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:b1,platform:Windows,
+030000006e0500000520000000000000,Elecom P301U,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:a2,righty:a3,start:b11,x:b0,y:b1,platform:Windows,
+03000000411200004450000000000000,Elecom U1012,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:a2,righty:a3,start:b11,x:b0,y:b1,platform:Windows,
+030000006e0500000320000000000000,Elecom U3613M (DInput),a:b2,b:b3,back:b10,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b8,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b9,righttrigger:b7,rightx:a2,righty:a3,start:b11,x:b0,y:b1,platform:Windows,
+030000006e0500000e20000000000000,Elecom U3912T,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:a2,righty:a3,start:b11,x:b0,y:b1,platform:Windows,
+030000006e0500000f20000000000000,Elecom U4013S,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:a2,righty:a3,start:b11,x:b0,y:b1,platform:Windows,
+030000006e0500001320000000000000,Elecom U4113,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,
+030000006e0500001020000000000000,Elecom U4113S,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,
+030000006e0500000720000000000000,Elecom W01U,a:b2,b:b3,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,rightx:a2,righty:a3,start:b9,x:b0,y:b1,platform:Windows,
03000000120c0000f61c000000000000,Elite,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,
+03000000242f000000b7000000000000,ESM 9110,a:b0,b:b1,back:b7,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b8,lefttrigger:b4,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b9,righttrigger:b5,rightx:a2,righty:a3,start:b6,x:b2,y:b3,platform:Windows,
+03000000101c0000181c000000000000,Essential,a:b2,b:b1,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b10,lefttrigger:b4,leftx:a1,lefty:a0,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a3,righty:a2,start:b9,x:b3,y:b0,platform:Windows,
030000008f0e00000f31000000000000,EXEQ,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:b3,y:b2,platform:Windows,
03000000341a00000108000000000000,EXEQ RF USB Gamepad 8206,a:b0,b:b1,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b8,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b7,rightx:a2,righty:a3,start:b9,x:b2,y:b3,platform:Windows,
-030000006f0e00008401000000000000,Faceoff Deluxe+ Audio Wired Controller for Nintendo Switch,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,
+03000000801000000900000000000000,8BitDo F30 Arcade Stick,a:b0,b:b1,back:b10,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b6,lefttrigger:b8,leftx:a0,lefty:a1,rightshoulder:b7,righttrigger:b9,rightx:a2,righty:a5,start:b11,x:b3,y:b4,platform:Windows,
+03000000008000000210000000000000,8BitDo F30,a:b0,b:b1,back:b10,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b6,lefttrigger:b8,leftx:a0,lefty:a1,rightshoulder:b7,righttrigger:b9,rightx:a2,righty:a5,start:b11,x:b3,y:b4,platform:Windows,
+03000000c82d00001028000000000000,8BitDo F30 Arcade Joystick,a:b0,b:b1,back:b10,leftshoulder:b6,leftx:a0,lefty:a1,rightshoulder:b7,start:b11,x:b3,y:b4,platform:Windows,
+030000003512000011ab000000000000,8BitDo F30 Arcade Joystick,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a5,start:b9,x:b0,y:b3,platform:Windows,
+03000000790000003018000000000000,F300,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:b9,x:b0,y:b3,platform:Windows,
+03000000242f00003900000000000000,F300 Elite,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a5,start:b9,x:b0,y:b3,platform:Windows,
+030000006d0400001dc2000000000000,Logitech F310,a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b8,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b9,rightx:a3,righty:a4,start:b7,x:b2,y:b3,platform:Windows,
+030000006d0400001ec2000000000000,Logitech F510,a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b8,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b9,rightx:a3,righty:a4,start:b7,x:b2,y:b3,platform:Windows,
+030000006d0400001fc2000000000000,Logitech F710,a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b8,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b9,rightx:a3,righty:a4,start:b7,x:b2,y:b3,platform:Windows,
+030000006f0e00008401000000000000,Faceoff Deluxe Audio Wired Controller for Nintendo Switch,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,
030000006f0e00008001000000000000,Faceoff Wired Pro Controller for Nintendo Switch,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,
-03000000852100000201000000000000,FF-GP1,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,
+03000000021000000090000000000000,FC30 Pro,a:b1,b:b0,back:b10,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b8,leftstick:b13,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b9,rightstick:b14,righttrigger:b7,rightx:a3,righty:a4,start:b11,x:b4,y:b3,platform:Windows,
+0300000011040000c600000000000000,FC801,a:b0,b:b1,back:b6,leftshoulder:b4,leftx:a0,lefty:a1,rightshoulder:b5,start:b7,x:b2,y:b3,platform:Windows,
+030000004f04000008d0000000000000,Ferrari 150,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b10,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,rightx:a2,righty:a5,start:b9,x:b0,y:b3,platform:Windows,
+03000000852100000201000000000000,FF GP1,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,
030000000d0f00008500000000000000,Fighting Commander 2016 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:Windows,
030000000d0f00008400000000000000,Fighting Commander 5,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a5,start:b9,x:b0,y:b3,platform:Windows,
030000000d0f00008700000000000000,Fighting Stick mini 4,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,
030000000d0f00008800000000000000,Fighting Stick mini 4,a:b1,b:b2,back:b9,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,lefttrigger:b6,rightshoulder:b5,righttrigger:b7,start:b8,x:b0,y:b3,platform:Windows,
030000000d0f00002700000000000000,FIGHTING STICK V3,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,
+03000000ad1b000028f0000000000000,Fightpad,a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,lefttrigger:b10,leftx:a0,lefty:a1,rightshoulder:b5,righttrigger:b11,rightx:a3,righty:a4,start:b7,x:b2,y:b3,platform:Windows,
+03000000ad1b00002ef0000000000000,Fightpad,a:b0,b:b1,back:b6,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:a4,start:b7,x:b2,y:b3,platform:Windows,
+03000000380700002847000000000000,FightPad,a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,lefttrigger:b10,leftx:a0,lefty:a1,rightshoulder:b5,righttrigger:b11,rightx:a3,righty:a4,start:b7,x:b2,y:b3,platform:Windows,
+03000000ad1b000038f0000000000000,Fightpad TE,a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,lefttrigger:b8,rightshoulder:b5,righttrigger:b9,start:b7,x:b2,y:b3,platform:Windows,
+03000000380700008031000000000000,FightStick,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,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,
+03000000380700008731000000000000,FightStick,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,rightx:a2,righty:a3,start:b9,x:b0,y:b3,platform:Windows,
+03000000380700001847000000000000,FightStick,a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,lefttrigger:b8,rightshoulder:b5,righttrigger:b9,start:b7,x:b2,y:b3,platform:Windows,
+030000003807000038b7000000000000,FightStick TE,a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,lefttrigger:b8,rightshoulder:b5,righttrigger:b9,start:b7,x:b2,y:b3,platform:Windows,
78696e70757403000000000000000000,Fightstick TES,a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b10,leftshoulder:b4,lefttrigger:a2,rightshoulder:b5,righttrigger:a5,start:b7,x:b2,y:b3,platform:Windows,
+03000000f806000001a3000000000000,Firestorm,a:b9,b:b7,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b0,leftstick:b10,lefttrigger:b1,leftx:a0,lefty:a1,rightshoulder:b2,rightstick:b11,righttrigger:b3,start:b12,x:b8,y:b4,platform:Windows,
+03000000b50700000399000000000000,Firestorm 2,a:b2,b:b4,back:b10,leftshoulder:b6,lefttrigger:b7,leftx:a0,lefty:a1,rightshoulder:b8,righttrigger:b9,start:b11,x:b3,y:b5,platform:Windows,
+03000000b50700001302000000000000,Firestorm D3,a:b0,b:b2,leftshoulder:b4,lefttrigger:b5,leftx:a0,lefty:a1,rightshoulder:b6,righttrigger:b7,x:b1,y:b3,platform:Windows,
+03000000b40400001024000000000000,Flydigi Apex,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:a5,start:b11,x:b3,y:b4,platform:Windows,
+03000000151900004000000000000000,Flydigi Vader 2,a:b11,b:b10,back:b3,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b7,leftstick:b1,lefttrigger:b5,leftx:a0,lefty:a1,rightshoulder:b6,rightstick:b0,righttrigger:b4,rightx:a3,righty:a4,start:b2,x:b9,y:b8,platform:Windows,
+03000000b40400001124000000000000,Flydigi Vader 2,a:b0,b:b1,back:b10,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b6,leftstick:b12,lefttrigger:b8,leftx:a0,lefty:a1,paddle1:b4,paddle2:b5,paddle4:b17,rightshoulder:b7,rightstick:b13,righttrigger:b9,rightx:a3,righty:a4,start:b11,x:b2,y:b3,platform:Windows,
+030000008305000000a0000000000000,G08XU,a:b0,b:b1,back:b4,leftshoulder:b6,leftx:a0,lefty:a1,rightshoulder:b7,start:b5,x:b2,y:b3,platform:Windows,
+03000000ac0500002d02000000000000,G2U,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:a5,start:b11,x:b3,y:b4,platform:Windows,
03000000790000002201000000000000,Game Controller for PC,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,
0300000066f700000100000000000000,Game VIB Joystick,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,
+03000000430b00000500000000000000,GameCube,a:b0,b:b2,dpdown:b10,dpleft:b8,dpright:b9,dpup:b11,lefttrigger:a4,leftx:a0,lefty:a1,rightshoulder:b6,righttrigger:a3,rightx:a5,righty:a2,start:b7,x:b1,y:b3,platform:Windows,
+03000000341a000005f7000000000000,GameCube,a:b2,b:b3,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:b1,y:b0,platform:Windows,
+03000000790000004718000000000000,GameCube,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:Windows,
03000000260900002625000000000000,Gamecube Controller,a:b0,b:b1,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b6,lefttrigger:a4,leftx:a0,lefty:a1,righttrigger:a5,rightx:a2,righty:a3,start:b7,x:b2,y:b3,platform:Windows,
-03000000790000004618000000000000,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:Windows,
-030000008f0e00000d31000000000000,GAMEPAD 3 TURBO,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,
+03000000790000004618000000000000,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:Windows,
+030000008f0e00000d31000000000000,Gamepad 3 Turbo,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,
03000000280400000140000000000000,GamePad Pro USB,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:Windows,
03000000ac0500003d03000000000000,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,
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,
+030000004c0e00001035000000000000,Gamester,a:b0,b:b1,back:b7,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b8,lefttrigger:b10,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b9,righttrigger:b11,rightx:a3,righty:a4,start:b6,x:b2,y:b3,platform:Windows,
+030000000d0f00001110000000000000,GameStick Bluetooth Controller,a:b0,b:b1,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b6,leftstick:b13,leftx:a0,lefty:a1,rightshoulder:b7,rightstick:b14,rightx:a2,righty:a5,start:b11,x:b3,y:b4,platform:Windows,
+0300000047530000616d000000000000,GameStop,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,
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,
-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,
+03000000b62500000100000000000000,Gametel GT004 01,a:b3,b:b0,dpdown:b10,dpleft:b9,dpright:b8,dpup:b11,leftshoulder:b4,rightshoulder:b5,start:b7,x:b1,y:b2,platform:Windows,
+030000008f0e00001411000000000000,Gamo2 Divaller PS4 Controller,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b0,y:b3,platform:Windows,
+03000000120c0000a857000000000000,Gator Claw,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,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,
+03000000c9110000f055000000000000,GC100XF,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,
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,
030000008305000031b0000000000000,Genius Maxfire Blaze 3,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,
03000000451300000010000000000000,Genius Maxfire Grandias 12,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,
@@ -127,50 +222,96 @@
03000000f025000021c1000000000000,Gioteck PS3 Controller,a:b2,b:b1,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b3,y:b0,platform:Windows,
03000000f0250000c383000000000000,Gioteck VX2 Controller,a:b2,b:b1,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b3,y:b0,platform:Windows,
03000000f0250000c483000000000000,Gioteck VX2 Controller,a:b2,b:b1,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b3,y:b0,platform:Windows,
+030000004f04000026b3000000000000,GP XID,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,
+0300000079000000d418000000000000,GPD Win,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,
+03000000c6240000025b000000000000,GPX,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,
030000007d0400000540000000000000,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:Windows,
+030000007d0400000340000000000000,Gravis G44011 Xterminator,a:b0,b:b1,back:b10,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b6,lefttrigger:b7,leftx:a0,lefty:a1,rightshoulder:b5,righttrigger:b2,rightx:a2,start:b9,x:b3,y:b4,platform:Windows,
+030000008f0e00000610000000000000,GreenAsia,a:b2,b:b1,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b6,leftstick:b9,lefttrigger:b4,leftx:a0,lefty:a1,rightshoulder:b7,rightstick:b10,righttrigger:b5,rightx:a5,righty:a2,start:b11,x:b3,y:b0,platform:Windows,
+03000000ac0500006b05000000000000,GT2a,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:a5,start:b11,x:b3,y:b4,platform:Windows,
03000000341a00000302000000000000,Hama Scorpad,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,
+03000000fd0500003902000000000000,Hammerhead,a:b3,b:b4,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b6,leftstick:b2,lefttrigger:b8,rightshoulder:b7,rightstick:b5,righttrigger:b9,start:b10,x:b0,y:b1,platform:Windows,
+03000000fd0500002a26000000000000,Hammerhead FX,a:b3,b:b4,back:b10,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b6,lefttrigger:b8,leftx:a0,lefty:a1,rightshoulder:b7,righttrigger:b9,rightx:a2,righty:a5,start:b11,x:b0,y:b1,platform:Windows,
+03000000fd0500002f26000000000000,Hammerhead FX,a:b4,b:b5,back:b10,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b6,lefttrigger:b8,leftx:a0,lefty:a1,rightshoulder:b7,righttrigger:b9,rightx:a2,righty:a5,start:b11,x:b1,y:b2,platform:Windows,
030000000d0f00004900000000000000,Hatsune Miku Sho 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,
-030000001008000001e1000000000000,Havit HV-G60,a:b2,b:b1,back:b8,dpdown:+a1,dpleft:-a0,dpright:+a0,dpup:-a1,leftshoulder:b4,lefttrigger:b6,rightshoulder:b5,righttrigger:b7,start:b9,x:b3,y:b0,platform:Windows,
-03000000d81400000862000000000000,HitBox Edition Cthulhu+,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b5,lefttrigger:b4,rightshoulder:b7,righttrigger:b6,start:b9,x:b0,y:b3,platform:Windows,
-03000000632500002605000000000000,HJD-X,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,
+030000001008000001e1000000000000,Havit HV G60,a:b2,b:b1,back:b8,dpdown:+a1,dpleft:-a0,dpright:+a0,dpup:-a1,leftshoulder:b4,lefttrigger:b6,rightshoulder:b5,righttrigger:b7,start:b9,x:b3,y:b0,platform:Windows,
+030000000d0f00000c00000000000000,HEXT,a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b8,lefttrigger:b10,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b9,righttrigger:b11,rightx:a3,righty:a4,start:b7,x:b2,y:b3,platform:Windows,
+030000000d0f00000d00000000000000,Hori Fighting Stick EX2,a:b0,b:b1,back:b7,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b8,lefttrigger:b10,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b9,righttrigger:b11,rightx:a3,righty:a4,start:b6,x:b2,y:b3,platform:Windows,
+030000000d0f00003701000000000000,Hori Fighting Stick Mini,a:b1,b:b0,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b8,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b9,rightx:a3,righty:a4,start:b7,x:b3,y:b2,platform:Windows,
+030000000d0f00002100000000000000,Hori Fighting Stick V3,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a5,start:b9,x:b0,y:b3,platform:Windows,
+030000000d0f00001000000000000000,Hori Fighting Stick,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a5,start:b9,x:b0,y:b3,platform:Windows,
+030000000f0d00000010000000000000,Hori Fighting Stick 3,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b10,lefttrigger:b6,rightshoulder:b5,rightstick:b11,righttrigger:b7,start:b9,x:b0,y:b3,platform:Windows,
+03000000d81400000862000000000000,HitBox Edition Cthulhu,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b5,lefttrigger:b4,rightshoulder:b7,righttrigger:b6,start:b9,x:b0,y:b3,platform:Windows,
+03000000632500002605000000000000,HJD X,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,
+030000000d0f00000a00000000000000,Hori DOA,a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,lefttrigger:b8,leftx:a0,lefty:a1,rightshoulder:b5,righttrigger:b9,rightx:a3,righty:a4,start:b7,x:b2,y:b3,platform:Windows,
+030000000d0f00008600000000000000,Hori Fighting Commander,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,
+030000000d0f0000ba00000000000000,Hori Fighting Commander,a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b8,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b9,rightx:a3,righty:a4,start:b7,x:b2,y:b3,platform:Windows,
030000000d0f00002d00000000000000,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:Windows,
-030000000d0f00005f00000000000000,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:Windows,
-030000000d0f00005e00000000000000,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:Windows,
+030000000d0f00005f00000000000000,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:Windows,
+030000000d0f00005e00000000000000,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:Windows,
+030000000d0f00005100000000000000,Hori Fighting 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:a2,righty:a5,start:b9,x:b0,y:b3,platform:Windows,
+030000000d0f00003200000000000000,Hori Fighting Stick 3W,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a5,start:b9,x:b0,y:b3,platform:Windows,
+030000000d0f0000c000000000000000,Hori Fighting Stick 4,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,
030000000d0f00004000000000000000,Hori Fighting Stick Mini 3,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b5,lefttrigger:b4,rightshoulder:b7,righttrigger:b6,start:b9,x:b0,y:b3,platform:Windows,
+030000000d0f0000a000000000000000,Hori Grip TAC4,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b10,lefttrigger:a3,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:a4,rightx:a2,righty:a5,start:b13,x:b0,y:b3,platform:Windows,
+030000000d0f00000101000000000000,Hori Mini Hatsune Miku FT,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,
030000000d0f00005400000000000000,Hori Pad 3,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,
030000000d0f00000900000000000000,Hori Pad 3 Turbo,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,
030000000d0f00004d00000000000000,Hori Pad A,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,
+030000000d0f00003801000000000000,Hori PC Engine Mini Controller,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,start:b9,platform:Windows,
030000000d0f00009200000000000000,Hori Pokken Tournament DX Pro Pad,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:Windows,
-030000000d0f00001600000000007803,HORI Real Arcade Pro EX-SE (Xbox 360),a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b10,leftshoulder:b4,lefttrigger:a2,rightshoulder:b5,righttrigger:a5,start:b7,x:b2,y:b3,platform:Windows,
030000000d0f00009c00000000000000,Hori TAC Pro,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:a3,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:a4,rightx:a2,righty:a5,start:b9,x:b0,y:b3,platform:Windows,
+030000000d0f0000c900000000000000,Hori Taiko Controller,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b0,y:b3,platform:Windows,
+030000000d0f00002301000000000000,Hori Wired PS4 Controller Light,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:a5,start:b11,x:b3,y:b4,platform:Windows,
030000000d0f0000c100000000000000,Horipad,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,
-030000000d0f00006e00000000000000,HORIPAD 4 (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:Windows,
-030000000d0f00006600000000000000,HORIPAD 4 (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:Windows,
+030000000d0f00006400000000000000,Horipad 3TP,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a5,start:b9,x:b0,y:b3,platform:Windows,
+030000000d0f00001300000000000000,Horipad 3W,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a5,start:b9,x:b0,y:b3,platform:Windows,
+030000000d0f00006e00000000000000,Horipad 4 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:Windows,
+030000000d0f00006600000000000000,Horipad 4 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:Windows,
030000000d0f00005500000000000000,Horipad 4 FPS,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,
-030000000d0f0000ee00000000000000,HORIPAD mini4,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a5,start:b9,x:b0,y:b3,platform:Windows,
-03000000250900000017000000000000,HRAP2 on PS/SS/N64 Joypad to USB BOX,a:b2,b:b1,back:b9,leftshoulder:b5,lefttrigger:b4,leftx:a0,lefty:a1,rightshoulder:b7,righttrigger:b6,start:b8,x:b3,y:b0,platform:Windows,
+030000000d0f00004200000000000000,Horipad A,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a5,start:b9,x:b0,y:b3,platform:Windows,
+030000005b1c00002400000000000000,Horipad Mini,a:b3,b:b4,back:b7,leftshoulder:b2,leftx:a0,lefty:a1,rightshoulder:b5,start:b6,x:b0,y:b1,platform:Windows,
+030000000d0f0000ee00000000000000,Horipad Mini 4,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a5,start:b9,x:b0,y:b3,platform:Windows,
+030000000d0f00006700000000000000,Horipad One,a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,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:Windows,
+030000000d0f0000dc00000000000000,Horipad Switch,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,
+03000000ad1b000001f5000000000000,Horipad EXT2,a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b8,lefttrigger:b10,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b9,righttrigger:b11,rightx:a3,righty:a4,start:b7,x:b2,y:b3,platform:Windows,
+030000000d0f00002600000000000000,Hori Real Arcade Pro 3P,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a5,start:b9,x:b0,y:b3,platform:Windows,
+030000000d0f00004b00000000000000,Hori Real Arcade Pro 3W,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a5,start:b9,x:b0,y:b3,platform:Windows,
+030000000d0f00003d00000000000000,Hori Real Arcade Pro N3,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b10,leftstick:b4,lefttrigger:b11,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b6,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b0,y:b3,platform:Windows,
+030000000d0f0000ae00000000000000,Hori Real Arcade Pro N4,a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b8,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b9,rightx:a3,righty:a4,start:b7,x:b2,y:b3,platform:Windows,
+030000000d0f0000d800000000000000,Hori Real Arcade Pro S,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:Windows,
+030000000d0f0000aa00000000000000,Hori Real Arcade Pro S,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a5,start:b9,x:b0,y:b3,platform:Windows,
+030000000d0f0000af00000000000000,Hori Real Arcade Pro VHS,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:a5,rightx:a3,righty:a4,start:b9,x:b0,y:b3,platform:Windows,
+030000000d0f00001b00000000000000,Hori Real Arcade Pro VX,a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,lefttrigger:b8,leftx:a0,lefty:a1,rightshoulder:b5,righttrigger:b9,rightx:a3,righty:a4,start:b7,x:b2,y:b3,platform:Windows,
+03000000ad1b000002f5000000000000,Hori Real Arcade Pro VX,a:b0,b:b1,back:b7,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b07,lefttrigger:b10,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b08,righttrigger:b11,rightx:a2,righty:a5,start:b6,x:b2,y:b3,platform:Windows,
+03000000250900000017000000000000,Joypad to USB Adapter,a:b2,b:b1,back:b9,leftshoulder:b5,lefttrigger:b4,leftx:a0,lefty:a1,rightshoulder:b7,righttrigger:b6,start:b8,x:b3,y:b0,platform:Windows,
+030000000d0f00008c00000000000000,Hori Real Arcade Pro P4,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,
+030000000d0f00006f00000000000000,Hori Real Arcade Pro 4 VLX,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b10,lefttrigger:a3,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:a4,rightx:a2,righty:a3,start:b9,x:b0,y:b3,platform:Windows,
030000008f0e00001330000000000000,HuiJia SNES Controller,a:b2,b:b1,back:b8,dpdown:+a1,dpleft:-a0,dpright:+a0,dpup:-a1,leftshoulder:b6,rightshoulder:b7,start:b9,x:b3,y:b0,platform:Windows,
03000000d81d00000f00000000000000,iBUFFALO BSGP1204 Series,a:b2,b:b1,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b6,leftstick:b10,lefttrigger:b4,leftx:a0,lefty:a1,rightshoulder:b7,rightstick:b11,righttrigger:b5,rightx:a2,righty:a3,start:b9,x:b3,y:b0,platform:Windows,
03000000d81d00001000000000000000,iBUFFALO BSGP1204P Series,a:b2,b:b1,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b6,leftstick:b10,lefttrigger:b4,leftx:a0,lefty:a1,rightshoulder:b7,rightstick:b11,righttrigger:b5,rightx:a2,righty:a3,start:b9,x:b3,y:b0,platform:Windows,
-03000000830500006020000000000000,iBuffalo SNES Controller,a:b1,b:b0,back:b6,dpdown:+a1,dpleft:-a0,dpright:+a0,dpup:-a1,leftshoulder:b4,rightshoulder:b5,start:b7,x:b3,y:b2,platform:Windows,
+030000005c0a00000285000000000000,iDroidCon,a:b0,b:b1,back:b10,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b6,lefttrigger:b8,leftx:a0,lefty:a1,rightshoulder:b7,righttrigger:b9,rightx:a2,righty:a5,start:b11,x:b4,y:b6,platform:Windows,
+03000000696400006964000000000000,iDroidCon Bluetooth Controller,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b0,y:b3,platform:Windows,
03000000b50700001403000000000000,Impact Black,a:b2,b:b3,back:b8,leftshoulder:b4,leftstick:b10,lefttrigger:b5,leftx:a0,lefty:a1,rightshoulder:b6,rightstick:b11,righttrigger:b7,rightx:a3,righty:a2,start:b9,x:b0,y:b1,platform:Windows,
-030000006f0e00002401000000000000,INJUSTICE FightStick PS3 Controller,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,
-03000000ac0500002c02000000000000,IPEGA,a:b0,b:b1,back:b10,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b8,leftstick:b13,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b9,rightstick:b14,righttrigger:b7,rightx:a3,righty:a4,start:b11,x:b3,y:b4,platform:Windows,
-03000000491900000204000000000000,Ipega PG-9023,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,
-03000000491900000304000000000000,Ipega PG-9087 - Bluetooth Gamepad,+righty:+a5,-righty:-a4,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,start:b11,x:b3,y:b4,platform:Windows,
-030000006e0500000a20000000000000,JC-DUX60 ELECOM MMO Gamepad,a:b2,b:b3,back:b17,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b8,leftstick:b14,lefttrigger:b12,leftx:a0,lefty:a1,rightshoulder:b11,rightstick:b15,righttrigger:b13,rightx:a3,righty:a4,start:b20,x:b0,y:b1,platform:Windows,
-030000006e0500000520000000000000,JC-P301U,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:a2,righty:a3,start:b11,x:b0,y:b1,platform:Windows,
-030000006e0500000320000000000000,JC-U3613M (DInput),a:b2,b:b3,back:b10,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b8,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b9,righttrigger:b7,rightx:a2,righty:a3,start:b11,x:b0,y:b1,platform:Windows,
-030000006e0500000720000000000000,JC-W01U,a:b2,b:b3,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,rightx:a2,righty:a3,start:b9,x:b0,y:b1,platform:Windows,
+030000006f0e00002401000000000000,Injustice FightStick PS3 Controller,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,
+03000000830500005130000000000000,InterAct ActionPad,a:b0,b:b1,back:b8,leftshoulder:b6,lefttrigger:b7,leftx:a0,lefty:a1,rightshoulder:b5,righttrigger:b2,start:b9,x:b3,y:b4,platform:Windows,
+03000000fd0500005302000000000000,InterAct ProPad,a:b3,b:b4,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b6,lefttrigger:b7,leftx:a0,lefty:a1,rightshoulder:b2,righttrigger:b5,x:b0,y:b1,platform:Windows,
+03000000ac0500002c02000000000000,Ipega Controller,a:b0,b:b1,back:b10,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b8,leftstick:b13,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b9,rightstick:b14,righttrigger:b7,rightx:a3,righty:a4,start:b11,x:b3,y:b4,platform:Windows,
+03000000491900000204000000000000,Ipega PG9023,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,
+03000000491900000304000000000000,Ipega PG9087 - Bluetooth Gamepad,+righty:+a5,-righty:-a4,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,start:b11,x:b3,y:b4,platform:Windows,
030000007e0500000620000000000000,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,
-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,
+03000000bd12000003c0000000000000,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,
+03000000ff1100004033000000000000,JPD FFB,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:a2,start:b15,x:b3,y:b0,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,
+03000000c4100000c082000000000000,KADE,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a5,start:b9,x:b0,y:b3,platform:Windows,
+03000000828200000180000000000000,Keio,a:b4,b:b5,back:b8,leftshoulder:b2,lefttrigger:b3,leftx:a0,lefty:a1,rightshoulder:b6,righttrigger:b7,start:b9,x:b0,y:b1,platform:Windows,
03000000790000000200000000000000,King 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:a4,start:b9,x:b3,y:b0,platform:Windows,
+03000000bd12000001e0000000000000,Leadership,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,
+030000008f0e00001300000000000000,Logic3,a:b2,b:b1,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,rightx:a2,righty:a3,start:b9,x:b3,y:b0,platform:Windows,
+030000006f0e00000103000000000000,Logic3,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,
+030000006f0e00000104000000000000,Logic3,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,
030000006d040000d1ca000000000000,Logitech ChillStream,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,
030000006d040000d2ca000000000000,Logitech Cordless Precision,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b0,y:b3,platform:Windows,
030000006d04000011c2000000000000,Logitech Cordless Wingman,a:b0,b:b1,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b9,leftstick:b5,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b10,rightstick:b2,righttrigger:b7,rightx:a3,righty:a4,x:b4,platform:Windows,
@@ -178,21 +319,24 @@
030000006d04000018c2000000000000,Logitech F510 Gamepad,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,
030000006d04000019c2000000000000,Logitech F710 Gamepad,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,
030000006d0400001ac2000000000000,Logitech Precision Gamepad,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:Windows,
+030000006d04000009c2000000000000,Logitech WingMan,a:b0,b:b1,back:b10,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b6,lefttrigger:b7,leftx:a0,lefty:a1,rightshoulder:b5,righttrigger:b2,start:b8,x:b3,y:b4,platform:Windows,
030000006d0400000ac2000000000000,Logitech WingMan RumblePad,a:b0,b:b1,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b6,lefttrigger:b7,leftx:a0,lefty:a1,rightshoulder:b5,righttrigger:b2,rightx:a3,righty:a4,x:b3,y:b4,platform:Windows,
-03000000380700006652000000000000,Mad Catz C.T.R.L.R,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:a3,righty:a4,start:b9,x:b0,y:b3,platform:Windows,
-03000000380700005032000000000000,Mad Catz FightPad PRO (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:Windows,
-03000000380700005082000000000000,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:Windows,
-03000000380700008433000000000000,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:Windows,
-03000000380700008483000000000000,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:Windows,
-03000000380700008134000000000000,Mad Catz FightStick TE2+ PS3,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b7,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b4,rightx:a2,righty:a3,start:b9,x:b0,y:b3,platform:Windows,
-03000000380700008184000000000000,Mad Catz FightStick TE2+ PS4,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b5,leftstick:b10,lefttrigger:a4,leftx:a0,lefty:a1,rightshoulder:b4,rightstick:b11,righttrigger:b7,rightx:a2,righty:a5,start:b9,x:b0,y:b3,platform:Windows,
-03000000380700006252000000000000,Mad Catz Micro C.T.R.L.R,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:a3,righty:a4,start:b9,x:b0,y:b3,platform:Windows,
+03000000380700005645000000000000,Lynx,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,
+03000000222200006000000000000000,Macally,a:b1,b:b2,back:b7,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b33,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,
+03000000380700006652000000000000,Mad Catz CTRLR,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:a3,righty:a4,start:b9,x:b0,y:b3,platform:Windows,
+03000000380700005032000000000000,Mad Catz FightPad Pro 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:Windows,
+03000000380700005082000000000000,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:Windows,
+03000000380700008433000000000000,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:Windows,
+03000000380700008483000000000000,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:Windows,
+03000000380700008134000000000000,Mad Catz FightStick TE2 PS3,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b7,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b4,rightx:a2,righty:a3,start:b9,x:b0,y:b3,platform:Windows,
+03000000380700008184000000000000,Mad Catz FightStick TE2 PS4,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b5,leftstick:b10,lefttrigger:a4,leftx:a0,lefty:a1,rightshoulder:b4,rightstick:b11,righttrigger:b7,rightx:a2,righty:a5,start:b9,x:b0,y:b3,platform:Windows,
+03000000380700006252000000000000,Mad Catz Micro CTRLR,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:a3,righty:a4,start:b9,x:b0,y:b3,platform:Windows,
03000000380700008034000000000000,Mad Catz TE2 PS3 Fightstick,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:Windows,
03000000380700008084000000000000,Mad Catz TE2 PS4 Fightstick,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:Windows,
-03000000380700008532000000000000,Madcatz Arcade 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,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b0,y:b3,platform:Windows,
-03000000380700003888000000000000,Madcatz Arcade 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,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b0,y:b3,platform:Windows,
-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,
+03000000380700008532000000000000,Mad Catz Arcade 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,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b0,y:b3,platform:Windows,
+03000000380700003888000000000000,Mad Catz Arcade Fightstick TE S Plus 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:Windows,
+03000000380700001888000000000000,Mad Catz 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,Mad Catz 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,
@@ -205,36 +349,69 @@
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:Windows,
03000000790000000018000000000000,Mayflash WiiU Pro Game Controller Adapter (DInput),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,
03000000790000002418000000000000,Mega Drive,a:b0,b:b1,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b6,rightshoulder:b2,start:b9,x:b3,y:b4,platform:Windows,
+0300000079000000ae18000000000000,Mega Drive,a:b0,b:b1,back:b7,dpdown:b14,dpleft:b15,dpright:b13,dpup:b2,rightshoulder:b6,righttrigger:b2,start:b9,x:b3,y:b4,platform:Windows,
+03000000c0160000990a000000000000,Mega Drive,a:b0,b:b1,leftx:a0,lefty:a1,righttrigger:b2,start:b3,platform:Windows,
+030000005e0400000300000000000000,Microsoft SideWinder,a:b0,b:b1,back:b9,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b6,lefttrigger:b7,leftx:a0,lefty:a1,rightshoulder:b5,righttrigger:b2,start:b8,x:b3,y:b4,platform:Windows,
+030000005e0400000700000000000000,Microsoft SideWinder,a:b0,b:b1,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b6,lefttrigger:b7,leftx:a0,lefty:a1,rightshoulder:b5,righttrigger:b2,start:b9,x:b3,y:b4,platform:Windows,
+030000005e0400002700000000000000,Microsoft SideWinder,a:b0,b:b1,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftx:a0,lefty:a1,rightshoulder:b4,righttrigger:b5,x:b2,y:b3,platform:Windows,
+030000005e0400000e00000000000000,Microsoft SideWinder Freestyle Pro,a:b0,b:b1,back:b9,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b6,lefttrigger:b7,leftx:a0,lefty:a1,rightshoulder:b2,righttrigger:b5,start:b8,x:b3,y:b4,platform:Windows,
+03000000280d00000202000000000000,Miller Lite Cantroller,a:b0,b:b1,back:b4,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftx:a0,lefty:a1,start:b5,x:b2,y:b3,platform:Windows,
+030000005b1c00002500000000000000,Mini,a:b3,b:b4,back:b7,leftshoulder:b2,leftx:a0,lefty:a1,rightshoulder:b5,start:b6,x:b0,y:b1,platform:Windows,
+03000000ad1b000023f0000000000000,MLG,a:b0,b:b1,back:b7,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b8,lefttrigger:a3,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b9,righttrigger:a6,rightx:a3,righty:a4,start:b6,x:b2,y:b3,platform:Windows,
+03000000ad1b00003ef0000000000000,MLG FightStick TE,a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,lefttrigger:b8,rightshoulder:b5,righttrigger:b9,start:b7,x:b2,y:b3,platform:Windows,
03000000380700006382000000000000,MLG GamePad 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,
-03000000c62400002a89000000000000,MOGA XP5-A Plus,a:b0,b:b1,back:b10,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b15,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,
-03000000c62400002b89000000000000,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:b8,leftx:a0,lefty:a1,rightshoulder:b7,rightstick:b14,righttrigger:b9,rightx:a3,righty:a4,start:b11,x:b3,y:b4,platform:Windows,
-03000000c62400001a89000000000000,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:b8,leftx:a0,lefty:a1,rightshoulder:b7,rightstick:b14,righttrigger:b9,rightx:a3,righty:a4,start:b11,x:b3,y:b4,platform:Windows,
-03000000c62400001b89000000000000,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:b8,leftx:a0,lefty:a1,rightshoulder:b7,rightstick:b14,righttrigger:b9,rightx:a3,righty:a4,start:b11,x:b3,y:b4,platform:Windows,
+03000000d6200000e589000000000000,Moga 2,a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b8,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b9,rightx:a2,righty:a5,start:b7,x:b2,y:b3,platform:Windows,
+03000000d62000007162000000000000,Moga Pro,a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b8,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b9,rightx:a2,righty:a5,start:b7,x:b2,y:b3,platform:Windows,
+03000000d6200000ad0d000000000000,Moga Pro,a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b8,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b9,rightx:a3,righty:a4,start:b7,x:b2,y:b3,platform:Windows,
+03000000c62400002a89000000000000,Moga XP5A Plus,a:b0,b:b1,back:b10,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b15,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,
+03000000c62400002b89000000000000,Moga XP5A 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:b8,leftx:a0,lefty:a1,rightshoulder:b7,rightstick:b14,righttrigger:b9,rightx:a3,righty:a4,start:b11,x:b3,y:b4,platform:Windows,
+03000000c62400001a89000000000000,Moga XP5X 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:b8,leftx:a0,lefty:a1,rightshoulder:b7,rightstick:b14,righttrigger:b9,rightx:a3,righty:a4,start:b11,x:b3,y:b4,platform:Windows,
+03000000c62400001b89000000000000,Moga XP5X 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:b8,leftx:a0,lefty:a1,rightshoulder:b7,rightstick:b14,righttrigger:b9,rightx:a3,righty:a4,start:b11,x:b3,y:b4,platform:Windows,
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,
+03000000f70600000100000000000000,N64 Controller,a:b1,b:b2,back:b3,dpdown:b11,dpleft:b12,dpright:b13,dpup:b10,leftshoulder:b6,lefttrigger:b0,leftx:a0,lefty:a1,rightshoulder:b7,righttrigger:b9,start:b8,x:b4,y:b5,platform:Windows,
+030000006b140000010c000000000000,Nacon GC 400ES,a:b0,b:b1,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b2,y:b3,platform:Windows,
+030000006b1400001106000000000000,Nacon Revolution 3 PS4 Controller,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a5,start:b9,x:b0,y:b3,platform:Windows,
+030000006b140000100d000000000000,Nacon Revolution Infinity PS4 Controller,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b0,y:b3,platform:Windows,
+030000006b140000080d000000000000,Nacon Revolution Unlimited Pro Controller,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b0,y:b3,platform:Windows,
+03000000bd12000001c0000000000000,Nebular,a:b2,b:b1,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a5,righty:a2,start:b9,x:b3,y:b0,platform:Windows,
+03000000eb0300000000000000000000,NeGcon USB Adapter,a:a2,b:b13,dpdown:b6,dpleft:b7,dpright:b5,dpup:b4,lefttrigger:a4,leftx:a1,righttrigger:b11,start:b3,x:a3,y:b12,platform:Windows,
+0300000038070000efbe000000000000,NEO SE,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,
+03000000000f00000100000000000000,NES Controller,a:b1,b:b0,back:b2,leftx:a0,lefty:a1,start:b3,platform:Windows,
+03000000571d00002100000000000000,NES Controller,a:b0,b:b1,back:b2,leftx:a0,lefty:a1,start:b3,platform:Windows,
+03000000921200004346000000000000,NES Controller,a:b0,b:b1,back:b2,leftx:a0,lefty:a1,start: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,a:b1,b:b0,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:b2,y:b3,platform:Windows,
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,
+03000000050b00000045000000000000,Nexus,a:b0,b:b1,back:b9,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:b10,x:b2,y:b3,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,
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:Windows,
030000000d0500000308000000000000,Nostromo N45,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:Windows,
+03000000d620000013a7000000000000,NSW 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:Windows,
03000000550900001472000000000000,NVIDIA Controller v01.04,a:b11,b:b10,back:b13,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b7,leftstick:b5,lefttrigger:a4,leftx:a0,lefty:a1,rightshoulder:b6,rightstick:b4,righttrigger:a5,rightx:a3,righty:a6,start:b3,x:b9,y:b8,platform:Windows,
-030000004b120000014d000000000000,NYKO AIRFLO,a:b0,b:b1,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b10,leftshoulder:a3,leftstick:a0,lefttrigger:b6,rightshoulder:b5,rightstick:a2,righttrigger:b7,start:b9,x:b2,y:b3,platform:Windows,
+03000000550900001072000000000000,NVIDIA Shield,a:b9,b:b8,back:b11,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b5,leftstick:b3,lefttrigger:a3,leftx:a0,lefty:a1,rightshoulder:b4,rightstick:b2,righttrigger:a4,rightx:a2,righty:a5,start:b0,x:b7,y:b6,platform:Windows,
+030000005509000000b4000000000000,NVIDIA Virtual Gamepad,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,
+030000004b120000014d000000000000,Nyko Airflo,a:b0,b:b1,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b10,leftshoulder:a3,leftstick:a0,lefttrigger:b6,rightshoulder:b5,rightstick:a2,righttrigger:b7,start:b9,x:b2,y:b3,platform:Windows,
03000000782300000a10000000000000,Onlive Wireless Controller,a:b15,b:b14,back:b7,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b5,leftshoulder:b11,leftstick:b9,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b10,rightstick:b8,righttrigger:a5,rightx:a3,righty:a4,start:b6,x:b13,y:b12,platform:Windows,
+030000000d0f00000401000000000000,Onyx,a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b8,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b9,rightx:a3,righty:a4,start:b7,x:b2,y:b3,platform:Windows,
+030000008916000001fd000000000000,Onza CE,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:a3,rightx:a3,righty:a4,start:b7,x:b2,y:b3,platform:Windows,
+030000008916000000fd000000000000,Onza TE,a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b8,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b9,righttrigger:a5,rightx:a3,righty:a4,start:b7,x:b2,y:b3,platform:Windows,
03000000d62000006d57000000000000,OPP PS3 Controller,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b0,y:b3,platform:Windows,
030000006b14000001a1000000000000,Orange Controller,a:b0,b:b1,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b10,leftshoulder:b4,leftstick:b6,lefttrigger:a3,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b7,righttrigger:a4,rightx:a5,righty:a2,start:b9,x:b2,y:b3,platform:Windows,
03000000362800000100000000000000,OUYA Game Controller,a:b0,b:b3,dpdown:b9,dpleft:b10,dpright:b11,dpup:b8,guide:b14,leftshoulder:b4,leftstick:b6,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b7,righttrigger:b13,rightx:a3,righty:a4,x:b1,y:b2,platform:Windows,
03000000120c0000f60e000000000000,P4 Wired Gamepad,a:b1,b:b2,back:b12,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b8,leftshoulder:b5,lefttrigger:b7,rightshoulder:b4,righttrigger:b6,start:b9,x:b0,y:b3,platform:Windows,
+030000006f0e00008501000000000000,PDP Fightpad Pro,a:b2,b:b3,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:b1,y:b0,platform:Windows,
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,
+03000000d9040000160f000000000000,Playstation Controller Adapter,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,
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,
+030000006d04000084ca000000000000,Precision,a:b0,b:b1,back:b7,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b5,leftstick:b8,lefttrigger:b10,leftx:a0,lefty:a1,rightshoulder:b4,rightstick:b9,righttrigger:b11,rightx:a3,righty:a4,start:b6,x:b2,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,
+03000000c62400001a53000000000000,Pro Ex Mini,a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b8,lefttrigger:b10,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b9,righttrigger:b11,rightx:a3,righty:a4,start:b7,x:b2,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,
03000000d6200000c757000000000000,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,
+03000000120c0000110e000000000000,Pro5,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,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,
03000000632500002306000000000000,PS Controller,a:b0,b:b1,back:b10,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b6,leftstick:b13,lefttrigger:b8,leftx:a0,lefty:a1,rightshoulder:b7,rightstick:b14,righttrigger:b9,rightx:a2,righty:a3,start:b11,x:b3,y:b4,platform:Windows,
03000000e30500009605000000000000,PS to USB convert cable,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,
03000000100800000100000000000000,PS1 Controller,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,
@@ -244,122 +421,281 @@
03000000666600006706000000000000,PS2 Controller,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:Windows,
030000006b1400000303000000000000,PS2 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,
030000009d0d00001330000000000000,PS2 Controller,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:a2,righty:a3,start:b9,x:b2,y:b3,platform:Windows,
+03000000250900000088000000000000,PS2 Controllera: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,
+03000000250900006888000000000000,PS2 Controllera:b2,b:b1,back:b9,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b5,leftstick:b10,lefttrigger:b4,leftx:a0,lefty:a1,rightshoulder:b7,rightstick:b11,righttrigger:b6,rightx:a2,righty:a3,start:b8,x:b3,y:b0,platform:Windows,
+03000000ba2200000701000000000000,Technology Innovation PS2 Adapter,a:b0,b:b1,x:b3,y:b2,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:a3,righty:a2,lefttrigger:b6,righttrigger:b7,platform:Windows,
+03000000430b00000300000000000000,EMS Production PS2 Adapter,a:b2,b:b1,x:b3,y:b0,back:b8,start:b9,leftstick:b10,rightstick:b11,leftshoulder:b6,rightshoulder:b7,dpup:b12,dpdown:b14,dpleft:b15,dpright:b13,leftx:a0,lefty:a1,rightx:a3,righty:a2,lefttrigger:b4,righttrigger:b5,platform:Windows,
03000000250900000500000000000000,PS3 Controller,a:b2,b:b1,back:b9,dpdown:h0.8,dpleft:h0.4,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:b0,y:b3,platform:Windows,
030000004c0500006802000000000000,PS3 Controller,a:b2,b:b1,back:b9,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b6,leftstick:b10,lefttrigger:a3~,leftx:a0,lefty:a1,rightshoulder:b7,rightstick:b11,righttrigger:a4~,rightx:a2,righty:a5,start:b8,x:b3,y:b0,platform:Windows,
03000000632500007505000000000000,PS3 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:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b3,y:b0,platform:Windows,
03000000888800000803000000000000,PS3 Controller,a:b2,b:b1,back:b8,dpdown:h0.8,dpleft:h0.4,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b9,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b10,righttrigger:b7,rightx:a3,righty:a4,start:b11,x:b0,y:b3,platform:Windows,
030000008f0e00001431000000000000,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,
+03000000120a00000100000000000000,PS3 Controller,a:b0,b:b1,back:b10,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b6,leftstick:b13,lefttrigger:b8,leftx:a0,lefty:a1,rightshoulder:b7,rightstick:b14,righttrigger:b9,rightx:a2,righty:a5,start:b11,x:b3,y:b4,platform:Windows,
+030000008f0e00000300000000000000,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:a5,start:b9,x:b3,y:b0,platform:Windows,
+030000004f1f00000800000000000000,PS3 Controller,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:b9,x:b0,y:b3,platform:Windows,
+03000000ba2200002010000000000000,PS3 Controller,a:b0,b:b1,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a5,righty:a2,start:b9,x:b3,y:b2,platform:Windows,
+03000000120c00001cf1000000000000,PS3 Controller,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,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,
+03000000888800000804000000000000,PS3 Controller,a:b14,b:b13,back:b0,dpdown:b6,dpleft:b7,dpright:b5,dpup:b4,leftshoulder:b10,leftstick:b1,leftx:a0,lefty:a1,rightshoulder:b11,rightstick:b2,rightx:a2,righty:a3,start:b3,x:b15,y:b12,platform:Windows,
+03000000120c00001307000000000000,PS3 Controller,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,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,
+03000000250900000118000000000000,PS3 Controller,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,
+03000000250900000218000000000000,PS3 Controller,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,
+03000000120c0000f90e000000000000,PS3 Controller,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,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,
030000003807000056a8000000000000,PS3 RF 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,
-03000000100000008200000000000000,PS360+ v1.66,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:h0.4,rightshoulder:b5,righttrigger:b7,start:b9,x:b0,y:b3,platform:Windows,
+03000000100000008200000000000000,PS360 v1.66,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:h0.4,rightshoulder:b5,righttrigger:b7,start:b9,x:b0,y:b3,platform:Windows,
030000004c050000a00b000000000000,PS4 Controller,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:a3,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:a4,rightx:a2,righty:a5,start:b9,x:b0,y:b3,platform:Windows,
030000004c050000c405000000000000,PS4 Controller,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:a3,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:a4,rightx:a2,righty:a5,start:b9,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,
+03000000120c00000807000000000000,PS4 Controller,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b10,lefttrigger:a3,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:a4,rightx:a2,righty:a5,start:b9,x:b0,y:b3,platform:Windows,
+03000000120c0000a957000000000000,PS4 Controller,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b10,lefttrigger:a3,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:a4,rightx:a2,righty:a5,start:b9,x:b0,y:b3,platform:Windows,
+03000000120c0000aa57000000000000,PS4 Controller,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b10,lefttrigger:a3,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:a4,rightx:a2,righty:a5,start:b9,x:b0,y:b3,platform:Windows,
+03000000120e0000120c000000000000,PS4 Controller,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b10,lefttrigger:a3,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:a4,rightx:a2,righty:a5,start:b9,x:b0,y:b3,platform:Windows,
+03000000160e0000120c000000000000,PS4 Controller,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b10,lefttrigger:a3,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:a4,rightx:a2,righty:a5,start:b9,x:b0,y:b3,platform:Windows,
+030000001a1e0000120c000000000000,PS4 Controller,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b10,lefttrigger:a3,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:a4,rightx:a2,righty:a5,start:b9,x:b0,y:b3,platform:Windows,
+03000000120c0000f21c000000000000,PS4 Controller,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b10,lefttrigger:a3,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:a4,rightx:a2,righty:a5,start:b9,x:b0,y:b3,platform:Windows,
+03000000120c0000f31c000000000000,PS4 Controller,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b10,lefttrigger:a3,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:a4,rightx:a2,righty:a5,start:b9,x:b0,y:b3,platform:Windows,
+03000000120c0000f41c000000000000,PS4 Controller,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b10,lefttrigger:a3,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:a4,rightx:a2,righty:a5,start:b9,x:b0,y:b3,platform:Windows,
+03000000120c0000f51c000000000000,PS4 Controller,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b10,lefttrigger:a3,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:a4,rightx:a2,righty:a5,start:b9,x:b0,y:b3,platform:Windows,
+03000000120c0000f10e000000000000,PS4 Controller,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b10,lefttrigger:a3,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:a4,rightx:a2,righty:a5,start:b9,x:b0,y:b3,platform:Windows,
+03000000120c0000130e000000000000,PS4 Controller,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b10,lefttrigger:a3,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:a4,rightx:a2,righty:a5,start:b9,x:b0,y:b3,platform:Windows,
+03000000120c0000150e000000000000,PS4 Controller,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b10,lefttrigger:a3,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:a4,rightx:a2,righty:a5,start:b9,x:b0,y:b3,platform:Windows,
+03000000120c0000f70e000000000000,PS4 Controller,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b10,lefttrigger:a3,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:a4,rightx:a2,righty:a5,start:b9,x:b0,y:b3,platform:Windows,
+03000000120c0000180e000000000000,PS4 Controller,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b10,lefttrigger:a3,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:a4,rightx:a2,righty:a5,start:b9,x:b0,y:b3,platform:Windows,
+03000000120c00001e0e000000000000,PS4 Controller,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b10,lefttrigger:a3,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:a4,rightx:a2,righty:a5,start:b9,x:b0,y:b3,platform:Windows,
+03000000120c0000111e000000000000,PS4 Controller,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b10,lefttrigger:a3,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:a4,rightx:a2,righty:a5,start:b9,x:b0,y:b3,platform:Windows,
+03000000120c0000121e000000000000,PS4 Controller,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b10,lefttrigger:a3,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:a4,rightx:a2,righty:a5,start:b9,x:b0,y:b3,platform:Windows,
+03000000120c0000181e000000000000,PS4 Controller,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b10,lefttrigger:a3,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:a4,rightx:a2,righty:a5,start:b9,x:b0,y:b3,platform:Windows,
+03000000120c0000191e000000000000,PS4 Controller,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b10,lefttrigger: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,
-03000000300f00001210000000000000,QanBa Joystick Plus,a:b0,b:b1,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,rightshoulder:b5,start:b9,x:b2,y:b3,platform:Windows,
-03000000341a00000104000000000000,QanBa Joystick Q4RAF,a:b5,b:b6,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b10,leftshoulder:b0,lefttrigger:b4,leftx:a0,lefty:a1,rightshoulder:b3,righttrigger:b7,start:b9,x:b1,y:b2,platform:Windows,
-03000000222c00000223000000000000,Qanba Obsidian Arcade Joystick PS3 Mode,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,
-03000000222c00000023000000000000,Qanba Obsidian Arcade Joystick PS4 Mode,a:b1,b:b2,back:b13,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,
+03000000830500005020000000000000,PSX,a:b0,b:b1,back:b10,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b8,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b9,righttrigger:b7,rightx:a2,righty:a3,start:b11,x:b2,y:b3,platform:Windows,
+03000000300f00000111000000000000,Qanba 2,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,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,
+03000000300f00000211000000000000,Qanba 2P,a:b1,b:b0,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,
+03000000300f00000011000000000000,Qanba Arcade Stick 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 Stick 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 Stick,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,
+03000000300f00001210000000000000,Qanba Joystick Plus,a:b0,b:b1,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,rightshoulder:b5,start:b9,x:b2,y:b3,platform:Windows,
+03000000341a00000104000000000000,Qanba Joystick Q4RAF,a:b5,b:b6,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b10,leftshoulder:b0,lefttrigger:b4,leftx:a0,lefty:a1,rightshoulder:b3,righttrigger:b7,start:b9,x:b1,y:b2,platform:Windows,
+03000000300f00001211000000000000,Qanba Joystick,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a5,start:b9,x:b0,y:b3,platform:Windows,
+03000000222c00000223000000000000,Qanba Obsidian Arcade Stick 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:Windows,
+03000000222c00000023000000000000,Qanba Obsidian Arcade Stick PS4,a:b1,b:b2,back:b13,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,
+030000008a2400006682000000000000,R1 Mobile Controller,a:b3,b:b1,back:b7,leftx:a0,lefty:a1,start:b6,x:b4,y:b0,platform:Windows,
+03000000086700006626000000000000,RadioShack,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:a5,start:b9,x:b3,y:b0,platform:Windows,
+030000009b2800002300000000000000,Raphnet Technologies 3DO USB Adapter,a:b0,b:b1,back:b4,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b6,lefttrigger:b5,leftx:a0,lefty:a1,rightshoulder:b2,start:b3,platform:Windows,
+030000009b2800006900000000000000,Raphnet Technologies 3DO USB Adapter,a:b0,b:b1,back:b4,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b6,lefttrigger:b5,leftx:a0,lefty:a1,rightshoulder:b2,start:b3,platform:Windows,
+030000009b2800000800000000000000,Raphnet Technologies Dreamcast USB Adapter,a:b2,b:b1,dpdown:b5,dpleft:b6,dpright:b7,dpup:b4,lefttrigger:a2,leftx:a0,righttrigger:a3,righty:a1,start:b3,x:b10,y:b9,platform:Windows,
+030000009b2800003200000000000000,Raphnet Technologies 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,Raphnet Technologies 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,
+030000009b2800001800000000000000,Raphnet Technologies Jaguar USB Adapter,a:b2,b:b1,back:b4,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b13,lefttrigger:b8,leftx:a0,lefty:a1,rightshoulder:b0,righttrigger:b10,start:b3,x:b11,y:b12,platform:Windows,
+030000009b2800000200000000000000,Raphnet Technologies NES USB Adapter,a:b7,b:b6,back:b5,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftx:a0,lefty:a1,start:b4,platform:Windows,
+030000009b2800004300000000000000,Raphnet Technologies Saturn,a:b0,b:b1,dpdown:b13,dpleft:b14,dpright:b15,dpup:b12,leftshoulder:b6,lefttrigger:b7,leftx:a0,lefty:a1,rightshoulder:b5,righttrigger:b2,start:b8,x:b3,y:b4,platform:Windows,
+030000009b2800000500000000000000,Raphnet Technologies 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,
+030000009b2800000300000000000000,Raphnet Technologies SNES USB Adapter,a:b0,b:b4,back:b2,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b6,leftx:a0,lefty:a1,rightshoulder:b7,start:b3,x:b1,y:b5,platform:Windows,
+030000009b2800005600000000000000,Raphnet Technologies SNES USB Adapter,a:b1,b:b4,back:b2,leftshoulder:b6,leftx:a0,lefty:a1,rightshoulder:b7,start:b3,x:b0,y:b5,platform:Windows,
+030000009b2800005700000000000000,Raphnet Technologies SNES USB Adapter,a:b1,b:b4,back:b2,leftshoulder:b6,leftx:a0,lefty:a1,rightshoulder:b7,start:b3,x:b0,y:b5,platform:Windows,
+030000009b2800001e00000000000000,Raphnet Technologies Vectrex USB Adapter,a:b0,b:b1,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftx:a1,lefty:a2,x:b2,y:b3,platform:Windows,
+030000009b2800002b00000000000000,Raphnet Technologies Wii Classic USB Adapter,a:b1,b:b4,back:b2,dpdown:b13,dpleft:b14,dpright:b15,dpup:b12,leftshoulder:b6,lefttrigger:b8,leftx:a0,lefty:a1,rightshoulder:b7,righttrigger:b9,rightx:a3,righty:a4,start:b3,x:b0,y:b5,platform:Windows,
+030000009b2800002c00000000000000,Raphnet Technologies Wii Classic USB Adapter,a:b1,b:b4,back:b2,dpdown:b13,dpleft:b14,dpright:b15,dpup:b12,leftshoulder:b6,lefttrigger:b8,leftx:a0,lefty:a1,rightshoulder:b7,righttrigger:b9,rightx:a3,righty:a4,start:b3,x:b0,y:b5,platform:Windows,
03000000321500000003000000000000,Razer Hydra,a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b8,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b9,righttrigger:a2,rightx:a3,righty:a4,start:b7,x:b2,y:b3,platform:Windows,
-03000000321500000204000000000000,Razer Panthera (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:Windows,
-03000000321500000104000000000000,Razer Panthera (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:Windows,
+03000000321500000204000000000000,Razer Panthera 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:Windows,
+03000000321500000104000000000000,Razer Panthera 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:Windows,
+03000000321500000010000000000000,Razer Raiju,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,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,
03000000321500000507000000000000,Razer Raiju Mobile,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,
03000000321500000707000000000000,Razer Raiju Mobile,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,
+03000000321500000710000000000000,Razer Raiju TE,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,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,
+03000000321500000a10000000000000,Razer Raiju TE,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,
+03000000321500000410000000000000,Razer Raiju UE,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,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,
+03000000321500000910000000000000,Razer Raiju UE,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,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,
03000000321500000011000000000000,Razer Raion Fightpad 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:a3,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:a4,rightx:a2,righty:a5,start:b9,x:b0,y:b3,platform:Windows,
03000000321500000009000000000000,Razer Serval,+lefty:+a2,-lefty:-a1,a:b0,b:b1,back:b12,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b10,leftshoulder:b4,leftstick:b8,leftx:a0,rightshoulder:b5,rightstick:b9,rightx:a3,righty:a4,start:b7,x:b2,y:b3,platform:Windows,
-030000000d0f00001100000000000000,REAL ARCADE PRO.3,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:Windows,
-030000000d0f00006a00000000000000,Real Arcade Pro.4,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:a3,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:a4,rightx:a2,righty:a5,start:b9,x:b0,y:b3,platform:Windows,
-030000000d0f00006b00000000000000,Real Arcade Pro.4,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b0,y:b3,platform:Windows,
-030000000d0f00008a00000000000000,Real Arcade Pro.4,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:a3,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:a4,rightx:a2,righty:a5,start:b9,x:b0,y:b3,platform:Windows,
-030000000d0f00008b00000000000000,Real Arcade Pro.4,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b0,y:b3,platform:Windows,
-030000000d0f00007000000000000000,REAL ARCADE PRO.4 VLX,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:Windows,
-030000000d0f00002200000000000000,REAL ARCADE Pro.V3,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:Windows,
-030000000d0f00005b00000000000000,Real Arcade Pro.V4,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a5,start:b9,x:b0,y:b3,platform:Windows,
-030000000d0f00005c00000000000000,Real Arcade Pro.V4,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,
-03000000790000001100000000000000,Retrolink SNES Controller,a:b2,b:b1,back:b8,dpdown:+a4,dpleft:-a3,dpright:+a3,dpup:-a4,leftshoulder:b4,rightshoulder:b5,start:b9,x:b3,y:b0,platform:Windows,
-03000000bd12000013d0000000000000,Retrolink USB SEGA Saturn Classic,a:b0,b:b1,dpdown:+a1,dpleft:-a0,dpright:+a0,dpup:-a1,leftshoulder:b5,lefttrigger:b6,rightshoulder:b2,righttrigger:b7,start:b8,x:b3,y:b4,platform:Windows,
+030000000d0f00001100000000000000,Hori Real Arcade Pro 3,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:Windows,
+030000000d0f00006a00000000000000,Hori Real Arcade Pro 4,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:a3,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:a4,rightx:a2,righty:a5,start:b9,x:b0,y:b3,platform:Windows,
+030000000d0f00006b00000000000000,Hori Real Arcade Pro 4,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b0,y:b3,platform:Windows,
+030000000d0f00008a00000000000000,Hori Real Arcade Pro 4,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:a3,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:a4,rightx:a2,righty:a5,start:b9,x:b0,y:b3,platform:Windows,
+030000000d0f00008b00000000000000,Hori Real Arcade Pro 4,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b0,y:b3,platform:Windows,
+030000000d0f00007000000000000000,Hori Real Arcade Pro 4 VLX,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:Windows,
+030000000d0f00002200000000000000,Hori Real Arcade Pro V3,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:Windows,
+030000000d0f00005b00000000000000,Hori Real Arcade Pro V4,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a5,start:b9,x:b0,y:b3,platform:Windows,
+030000000d0f00005c00000000000000,Hori Real Arcade Pro V4,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,
+03000000830500006020000000000000,Retro Controller,a:b0,b:b1,back:b6,dpdown:+a1,dpleft:-a0,dpright:+a0,dpup:-a1,leftshoulder:b4,lefttrigger:b5,rightshoulder:b8,righttrigger:b9,start:b7,x:b2,y:b3,platform:Windows,
+03000000790000001100000000000000,Retro Controller,a:b1,b:b2,back:b8,dpdown:+a4,dpleft:-a3,dpright:+a3,dpup:-a4,leftshoulder:b6,lefttrigger:b7,rightshoulder:b4,righttrigger:b5,start:b9,x:b0,y:b3,platform:Windows,
+03000000c82d00000290000000000000,Retrobit 64,a:b3,b:b9,back:b1,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b6,lefttrigger:b0,leftx:a0,lefty:a1,rightshoulder:b7,righttrigger:b10,start:b11,x:b4,y:b8,platform:Windows,
+03000000c82d00003038000000000000,Retrobit 64,a:b3,b:b9,back:b1,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b6,lefttrigger:b0,leftx:a0,lefty:a1,rightshoulder:b7,righttrigger:b10,start:b11,x:b4,y:b8,platform:Windows,
+03000000bd12000013d0000000000000,Retrolink USB Sega Saturn Classic,a:b0,b:b1,dpdown:+a1,dpleft:-a0,dpright:+a0,dpup:-a1,leftshoulder:b5,lefttrigger:b6,rightshoulder:b2,righttrigger:b7,start:b8,x:b3,y:b4,platform:Windows,
+03000000bd12000015d0000000000000,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,
0300000000f000000300000000000000,RetroUSB.com RetroPad,a:b1,b:b5,back:b2,leftshoulder:b6,leftx:a0,lefty:a1,rightshoulder:b7,start:b3,x:b0,y:b4,platform:Windows,
0300000000f00000f100000000000000,RetroUSB.com Super RetroPort,a:b1,b:b5,back:b2,leftshoulder:b6,leftx:a0,lefty:a1,rightshoulder:b7,start:b3,x:b0,y:b4,platform:Windows,
+03000000830500000960000000000000,Revenger,a:b0,b:b1,leftshoulder:b6,lefttrigger:b7,leftx:a0,lefty:a1,rightshoulder:b2,righttrigger:b3,x:b4,y:b5,platform:Windows,
030000006b140000010d000000000000,Revolution Pro 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,
-030000006b140000020d000000000000,Revolution Pro Controller 2(1/2),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,
+030000006b140000020d000000000000,Revolution Pro Controller 2,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,
030000006b140000130d000000000000,Revolution Pro Controller 3,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,
+030000006f0e00004601000000000000,Rock Candy,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,
+030000006f0e00001f01000000000000,Rock Candy,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,
030000006f0e00001e01000000000000,Rock Candy 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,
030000006f0e00002801000000000000,Rock Candy 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,
030000006f0e00002f01000000000000,Rock Candy 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,
-030000004f04000003d0000000000000,run'n'drive,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b7,leftshoulder:a3,leftstick:b10,lefttrigger:b4,leftx:a0,lefty:a1,rightshoulder:a4,rightstick:b11,righttrigger:b5,rightx:a2,righty:a5,start:b9,x:b0,y:b3,platform:Windows,
+03000000c6240000fefa000000000000,Rock Candy Controller,a:b0,b:b1,x:b2,y:b3,back:b6,guide:b8,start:b7,leftstick:b9,rightstick:b10,leftshoulder:b4,rightshoulder:b5,dpup:h0.1,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,leftx:a0,lefty:a1,rightx:a3,righty:a4,lefttrigger:a2,righttrigger:a5,platform:Windows,
+030000004f04000001d0000000000000,Rumble Force,a:b0,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b10,lefttrigger:b5,leftx:a0,lefty:a1,rightshoulder:b6,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b1,y:b3,platform:Windows,
+030000004f04000009d0000000000000,Run N Drive,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,
+030000004f04000003d0000000000000,Run N Drive,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b7,leftshoulder:a3,leftstick:b10,lefttrigger:b4,leftx:a0,lefty:a1,rightshoulder:a4,rightstick:b11,righttrigger:b5,rightx:a2,righty:a5,start:b9,x:b0,y:b3,platform:Windows,
+03000000c6240000045d000000000000,Sabertooth,a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b8,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b9,righttrigger:a5,rightx:a3,righty:a4,start:b7,x:b2,y:b3,platform:Windows,
+030000008916000000fe000000000000,Sabertooth,a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b8,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b9,righttrigger:a5,rightx:a3,righty:a4,start:b7,x:b2,y:b3,platform:Windows,
03000000a30600001af5000000000000,Saitek Cyborg,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a3,righty:a4,start:b9,x:b0,y:b3,platform:Windows,
03000000a306000023f6000000000000,Saitek Cyborg V.1 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:a4,start:b9,x:b0,y:b3,platform:Windows,
03000000300f00001201000000000000,Saitek Dual Analog Pad,a:b2,b:b3,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b10,lefttrigger:b5,leftx:a0,lefty:a1,rightshoulder:b6,rightstick:b11,righttrigger:b7,rightx:a3,righty:a2,start:b9,x:b0,y:b1,platform:Windows,
03000000a30600000701000000000000,Saitek P220,a:b2,b:b3,dpdown:+a1,dpleft:-a0,dpright:+a0,dpup:-a1,leftshoulder:b6,lefttrigger:b7,rightshoulder:b4,righttrigger:b5,x:b0,y:b1,platform:Windows,
03000000a30600000cff000000000000,Saitek P2500 Force Rumble Pad,a:b2,b:b3,back:b11,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b8,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b9,righttrigger:b7,rightx:a2,righty:a3,start:b10,x:b0,y:b1,platform:Windows,
+03000000a30600000d5f000000000000,Saitek P2600,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:a3,righty:a2,start:b8,x:b0,y:b3,platform:Windows,
+03000000a30600000dff000000000000,Saitek P2600,a:b1,b:b2,back:b9,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a5,righty:a2,start:b8,x:b0,y:b3,platform:Windows,
03000000a30600000c04000000000000,Saitek P2900,a:b1,b:b2,back:b12,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b8,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,
+03000000a306000018f5000000000000,Saitek P3200,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a3,righty:a4,start:b9,x:b0,y:b3,platform:Windows,
03000000300f00001001000000000000,Saitek P480 Rumble Pad,a:b2,b:b3,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b10,lefttrigger:b5,leftx:a0,lefty:a1,rightshoulder:b6,rightstick:b11,righttrigger:b7,rightx:a3,righty:a2,start:b9,x:b0,y:b1,platform:Windows,
+03000000a30600000901000000000000,Saitek P880,a:b2,b:b3,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b6,leftstick:b8,lefttrigger:b7,leftx:a0,lefty:a1,rightshoulder:b4,rightstick:b9,righttrigger:b5,rightx:a3,righty:a2,x:b0,y:b1,platform:Windows,
03000000a30600000b04000000000000,Saitek P990,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:a3,righty:a2,start:b9,x:b0,y:b3,platform:Windows,
-03000000a30600000b04000000010000,Saitek P990 Dual Analog Pad,a:b1,b:b2,back:b9,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:b8,x:b0,y:b3,platform:Windows,
+03000000a30600000b04000000000000,Saitek P990 Dual Analog Pad,a:b1,b:b2,back:b9,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:b8,x:b0,y:b3,platform:Windows,
03000000a30600002106000000000000,Saitek PS1000,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:Windows,
03000000a306000020f6000000000000,Saitek PS2700,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:Windows,
03000000300f00001101000000000000,Saitek Rumble Pad,a:b2,b:b3,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b8,leftshoulder:b4,leftstick:b10,lefttrigger:b5,leftx:a0,lefty:a1,rightshoulder:b6,rightstick:b11,righttrigger:b7,rightx:a3,righty:a2,start:b9,x:b0,y:b1,platform:Windows,
+03000000e804000000a0000000000000,Samsung EIGP20,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,rightx:a3,righty:a4,start:b11,x:b3,y:b4,platform:Windows,
+03000000c01100000252000000000000,Sanwa Easy Grip,a:b0,b:b1,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b6,lefttrigger:b7,leftx:a0,lefty:a1,rightshoulder:b5,righttrigger:b2,start:b9,x:b3,y:b4,platform:Windows,
+03000000bd12000003c0000000000000,Sanwa JYP70UR,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,
+03000000c01100004350000000000000,Sanwa Micro Grip P3,a:b1,b:b0,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b10,lefttrigger:b5,leftx:a0,lefty:a1,rightshoulder:b6,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,x:b3,y:b2,platform:Windows,
+03000000c01100004150000000000000,Sanwa Micro Grip Pro,a:b0,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b10,lefttrigger:b5,leftx:a0,lefty:a1,rightshoulder:b6,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b1,y:b3,platform:Windows,
+03000000411200004550000000000000,Sanwa Micro Grip Pro,a:b0,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b10,lefttrigger:b5,leftx:a0,lefty:a1,rightshoulder:b6,rightstick:b11,righttrigger:b7,rightx:a1,righty:a2,start:b9,x:b1,y:b3,platform:Windows,
+03000000c01100004450000000000000,Sanwa Online Grip,a:b0,b:b1,back:b12,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:b14,x:b3,y:b4,platform:Windows,
03000000730700000401000000000000,Sanwa PlayOnline Mobile,a:b0,b:b1,back:b2,leftx:a0,lefty:a1,start:b3,platform:Windows,
-0300000000050000289b000000000000,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,
-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,
-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,
+03000000830500006120000000000000,Sanwa Smart Grip II,a:b0,b:b2,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,righttrigger:b7,x:b1,y:b3,platform:Windows,
+03000000c01100000051000000000000,Satechi Bluetooth Controller,a:b0,b:b1,back:b10,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b6,leftstick:b13,lefttrigger:b8,leftx:a0,lefty:a1,rightshoulder:b7,rightstick:b14,righttrigger:b9,rightx:a2,righty:a5,start:b11,x:b3,y:b4,platform:Windows,
+03000000730700000601000000000000,Sega Saturn Controller,a:b0,b:b1,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b6,lefttrigger:b7,leftx:a0,lefty:a1,rightshoulder:b5,righttrigger:b2,start:b9,x:b3,y:b4,platform:Windows,
+03000000b40400000a01000000000000,Sega Saturn Controller,a:b0,b:b1,leftshoulder:b6,lefttrigger:b7,leftx:a0,lefty:a1,rightshoulder:b5,righttrigger:b2,start:b8,x:b3,y:b4,platform:Windows,
+0300000000f000000800000000000000,Sega Saturn Controller,a:b1,b:b2,leftx:a0,lefty:a1,rightshoulder:b7,righttrigger:b3,start:b0,x:b5,y:b6,platform:Windows,
+0300000000050000289b000000000000,Sega Saturn Adapter 2,a:b1,b:b2,leftshoulder:b6,lefttrigger:b4,leftx:a0,lefty:a1,rightshoulder:b7,righttrigger:b5,start:b9,x:b0,y:b3,platform:Windows,
+030000004f04000028b3000000000000,Score A,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a5,start:b9,x:b0,y:b3,platform:Windows,
+03000000952e00002577000000000000,Scuf PS4 Controller,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b10,lefttrigger:a3,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:a4,rightx:a2,righty:a5,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,
+030000003b07000004a1000000000000,SFX,a:b0,b:b2,back:b7,leftshoulder:b6,lefttrigger:b4,leftx:a0,lefty:a1,rightshoulder:b9,righttrigger:b5,start:b8,x:b1,y:b3,platform:Windows,
+03000000120c00001c1e000000000000,SnakeByte GamePad 4S PS4 Controller,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b10,lefttrigger:a3,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:a4,rightx:a2,righty:a5,start:b9,x:b0,y:b3,platform:Windows,
+03000000571d00002000000000000000,SNES Controller,a:b0,b:b1,back:b6,leftshoulder:b4,leftx:a0,lefty:a1,rightshoulder:b5,start:b7,x:b2,y:b3,platform:Windows,
+030000008b2800000300000000000000,SNES Controller,a:b0,b:b4,back:b2,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b6,leftx:a0,lefty:a1,rightshoulder:b7,start:b3,x:b1,y:b5,platform:Windows,
+03000000921200004653000000000000,SNES Controller,a:b0,b:b4,back:b2,leftshoulder:b6,leftx:a0,lefty:a1,rightshoulder:b7,start:b3,x:b1,y:b5,platform:Windows,
+0300000003040000c197000000000000,SNES Controller,a:b0,b:b4,back:b2,leftshoulder:b6,leftx:a0,lefty:a1,rightshoulder:b7,start:b3,x:b1,y:b5,platform:Windows,
+0300000081170000960a000000000000,SNES Controller,a:b4,b:b0,back:b2,leftshoulder:b6,leftx:a0,lefty:a1,rightshoulder:b7,start:b3,x:b5,y:b1,platform:Windows,
+03000000811700009d0a000000000000,SNES Controller,a:b0,b:b4,back:b2,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b6,leftx:a0,lefty:a1,rightshoulder:b7,start:b3,x:b1,y:b5,platform:Windows,
+03000000341a00000208000000000000,Speedlink 6555,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,Speedlink 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,
03000000c01100000591000000000000,Speedlink Torid,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,
03000000d11800000094000000000000,Stadia Controller,a:b0,b:b1,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b10,leftshoulder:b4,leftstick:b6,lefttrigger:b12,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b7,righttrigger:b11,rightx:a3,righty:a4,start:b9,x:b2,y:b3,platform:Windows,
+03000000de280000fc11000000000000,Steam Virtual Gamepad,a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,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:Windows,
+03000000de280000ff11000000000000,Steam Virtual Gamepad,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,
+03000000120c0000160e000000000000,Steel Play Metaltech PS4 Controller,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b10,lefttrigger:a3,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:a4,rightx:a2,righty:a5,start:b9,x:b0,y:b3,platform:Windows,
03000000110100001914000000000000,SteelSeries,a:b0,b:b1,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftstick:b13,lefttrigger:b6,leftx:a0,lefty:a1,rightstick:b14,righttrigger:b7,rightx:a3,righty:a4,start:b11,x:b3,y:b4,platform:Windows,
03000000381000001214000000000000,SteelSeries Free,a:b0,b:b1,back:b12,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:b3,y:b4,platform:Windows,
03000000110100003114000000000000,SteelSeries Stratus Duo,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,
03000000381000001814000000000000,SteelSeries Stratus XL,a:b0,b:b1,back:b18,dpdown:b13,dpleft:b14,dpright:b15,dpup:b12,guide:b19,leftshoulder:b4,leftstick:b10,lefttrigger:a3,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:a4,rightx:a2,righty:a5,start:b9,x:b2,y:b3,platform:Windows,
-03000000790000001c18000000000000,STK-7024X,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,
-03000000ff1100003133000000000000,SVEN X-PAD,a:b2,b:b3,back:b4,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b6,lefttrigger:b8,leftx:a0,lefty:a1,rightshoulder:b7,righttrigger:b9,rightx:a2,righty:a4,start:b5,x:b0,y:b1,platform:Windows,
+03000000790000001c18000000000000,STK 7024X,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,
+03000000381000003014000000000000,Stratus Duo,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,
+03000000381000003114000000000000,Stratus Duo,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,
+03000000380700003847000000000000,Street Fighter Fighting Stick TE,a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,lefttrigger:b10,leftx:a0,lefty:a1,rightshoulder:b5,righttrigger:b11,start:b7,x:b2,y:b3,platform:Windows,
+030000001f08000001e4000000000000,Super Famicom Controller,a:b2,b:b1,back:b8,leftshoulder:b4,leftx:a0,lefty:a1,rightshoulder:b5,start:b9,x:b3,y:b0,platform:Windows,
+03000000790000000418000000000000,Super Famicom Controller,a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b33,rightshoulder:b5,start:b7,x:b2,y:b3,platform:Windows,
03000000d620000011a7000000000000,Switch,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,
-03000000457500002211000000000000,SZMY-POWER PC Gamepad,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b0,y:b3,platform:Windows,
-030000004f04000007d0000000000000,T Mini Wireless,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b0,y:b3,platform:Windows,
-030000004f0400000ab1000000000000,T.16000M,a:b0,b:b1,back:b12,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b11,leftshoulder:b4,lefttrigger:b9,leftx:a0,lefty:a1,rightshoulder:b6,righttrigger:b7,start:b10,x:b2,y:b3,platform:Windows,
+030000000d0f0000f600000000000000,Switch Hori Pad,a:b0,b:b1,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b2,y:b3,platform:Windows,
+03000000457500002211000000000000,Szmy Power PC Gamepad,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b0,y:b3,platform:Windows,
+030000004f04000007d0000000000000,TMini Wireless,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b0,y:b3,platform:Windows,
+030000004f0400000ab1000000000000,T16000M,a:b0,b:b1,back:b12,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b11,leftshoulder:b4,lefttrigger:b9,leftx:a0,lefty:a1,rightshoulder:b6,righttrigger:b7,start:b10,x:b2,y:b3,platform:Windows,
+030000000d0f00007b00000000000000,TAC GEAR,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a5,start:b9,x:b0,y:b3,platform:Windows,
+03000000d814000001a0000000000000,TE Kitty,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b0,y:b3,platform:Windows,
03000000fa1900000706000000000000,Team 5,a:b2,b:b1,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b3,y:b0,platform:Windows,
03000000b50700001203000000000000,Techmobility X6-38V,a:b2,b:b3,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b10,lefttrigger:b5,leftx:a0,lefty:a1,rightshoulder:b6,rightstick:b11,righttrigger:b7,rightx:a3,righty:a2,start:b9,x:b0,y:b1,platform:Windows,
+03000000790000002601000000000000,TGZ,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:a5,start:b9,x:b3,y:b0,platform:Windows,
030000004f04000015b3000000000000,Thrustmaster Dual Analog 4,a:b0,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b10,lefttrigger:b5,leftx:a0,lefty:a1,rightshoulder:b6,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b1,y:b3,platform:Windows,
-030000004f04000023b3000000000000,Thrustmaster Dual Trigger 3-in-1,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a5,start:b9,x:b0,y:b3,platform:Windows,
+030000004f04000023b3000000000000,Thrustmaster Dual Trigger 3 in 1,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a5,start:b9,x:b0,y:b3,platform:Windows,
030000004f0400000ed0000000000000,ThrustMaster eSwap PRO 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,
030000004f04000000b3000000000000,Thrustmaster Firestorm Dual Power,a:b0,b:b2,back:b9,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b8,leftshoulder:b4,leftstick:b11,lefttrigger:b5,leftx:a0,lefty:a1,rightshoulder:b6,rightstick:b12,righttrigger:b7,rightx:a2,righty:a3,start:b10,x:b1,y:b3,platform:Windows,
030000004f04000004b3000000000000,Thrustmaster Firestorm Dual Power 3,a:b0,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b10,lefttrigger:b5,leftx:a0,lefty:a1,rightshoulder:b6,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b1,y:b3,platform:Windows,
+030000006d04000088ca000000000000,Thunderpad,a:b0,b:b1,back:b7,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b5,leftstick:b8,lefttrigger:b10,leftx:a0,lefty:a1,rightshoulder:b4,rightstick:b9,righttrigger:b11,rightx:a3,righty:a4,start:b6,x:b2,y:b3,platform:Windows,
03000000666600000488000000000000,TigerGame PS/PS2 Game Controller Adapter,a:b2,b:b1,back:b9,dpdown:b14,dpleft:b15,dpright:b13,dpup:b12,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,
03000000d62000006000000000000000,Tournament 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,
+03000000c01100000055000000000000,Tronsmart,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,
030000005f140000c501000000000000,Trust 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:Windows,
03000000b80500000210000000000000,Trust 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:Windows,
030000004f04000087b6000000000000,TWCS Throttle,dpdown:b8,dpleft:b9,dpright:b7,dpup:b6,leftstick:b5,lefttrigger:-a5,leftx:a0,lefty:a1,righttrigger:+a5,platform:Windows,
+03000000411200000450000000000000,Twin Shock,a:b2,b:b1,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b6,leftstick:b9,lefttrigger:b4,leftx:a0,lefty:a1,rightshoulder:b7,rightstick:b10,righttrigger:b5,rightx:a3,righty:a4,start:b11,x:b3,y:b0,platform:Windows,
03000000d90400000200000000000000,TwinShock PS2,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,
-030000006e0500001320000000000000,U4113,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,
03000000101c0000171c000000000000,uRage 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:Windows,
-03000000300f00000701000000000000,USB 4-Axis 12-Button 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:a3,righty:a2,start:b9,x:b3,y:b0,platform:Windows,
-03000000341a00002308000000000000,USB gamepad,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,
-030000005509000000b4000000000000,USB gamepad,a:b10,b:b11,back:b5,dpdown:b1,dpleft:b2,dpright:b3,dpup:b0,guide:b14,leftshoulder:b8,leftstick:b6,lefttrigger:a4,leftx:a0,lefty:a1,rightshoulder:b9,rightstick:b7,righttrigger:a5,rightx:a2,righty:a3,start:b4,x:b12,y:b13,platform:Windows,
-030000006b1400000203000000000000,USB gamepad,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,
-03000000790000000a00000000000000,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:a4,start:b9,x:b3,y:b0,platform:Windows,
-03000000f0250000c183000000000000,USB gamepad,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b0,y:b3,platform:Windows,
-03000000ff1100004133000000000000,USB gamepad,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:a4,righty:a2,start:b9,x:b3,y:b0,platform:Windows,
-03000000632500002305000000000000,USB Vibration Joystick (BM),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,
+03000000242f00006e00000000000000,USB Game Controller,a:b1,b:b4,back:b10,leftshoulder:b8,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b9,righttrigger:b7,rightx:a2,righty:a5,start:b11,x:b0,y:b3,platform:Windows,
+03000000b50700001503000000000000,USB Game Controller,a:b2,b:b3,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b10,lefttrigger:b5,leftx:a0,lefty:a1,rightshoulder:b6,rightstick:b11,righttrigger:b7,rightx:a5,righty:a2,start:b9,x:b0,y:b1,platform:Windows,
+03000000b404000081c6000000000000,USB Game 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:a5,start:b9,x:b3,y:b0,platform:Windows,
+03000000666600000188000000000000,USB Game Controller,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,
+03000000666600000288000000000000,USB Game Controller,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,
+03000000300f00000701000000000000,USB Game 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:a3,righty:a2,start:b9,x:b3,y:b0,platform:Windows,
+03000000bd12000012d0000000000000,USB Game Controller,a:b0,b:b1,back:b6,leftshoulder:b4,leftx:a0,lefty:a1,rightshoulder:b5,start:b7,x:b2,y:b3,platform:Windows,
+030000000b0400003065000000000000,USB Game 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:a5,start:b9,x:b3,y:b0,platform:Windows,
+03000000341a00002308000000000000,USB Game 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,
+030000006b1400000203000000000000,USB Game 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,
+03000000790000000a00000000000000,USB Game 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:a4,start:b9,x:b3,y:b0,platform:Windows,
+03000000f0250000c183000000000000,USB Game 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,
+03000000ff1100004133000000000000,USB Game Controller,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:a4,righty:a2,start:b9,x:b3,y:b0,platform:Windows,
+03000000632500002305000000000000,USB Vibration Joystick,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,
03000000790000001a18000000000000,Venom,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,
03000000790000001b18000000000000,Venom 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:b6,rightshoulder:b5,righttrigger:b7,start:b9,x:b0,y:b3,platform:Windows,
030000006f0e00000302000000000000,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,lefttrigger:b6,rightshoulder:b5,righttrigger:b7,start:b9,x:b0,y:b3,platform:Windows,
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,
+03000000120c0000ab57000000000000,Warrior Joypad JS083,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,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,
+030000007e0500003003000000000000,WiiU Pro,a:b0,b:b1,back:b8,dpdown:b14,dpleft:b15,dpright:b16,dpup:b13,leftshoulder:b6,leftstick:b11,lefttrigger:b4,leftx:a0,lefty:a1,rightshoulder:b7,rightstick:b12,righttrigger:b5,rightx:a2,righty:a3,start:b9,x:b3,y:b2,platform:Windows,
+0300000032150000030a000000000000,Wildcat,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,
+0300000032150000140a000000000000,Wolverine,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,
+03000000ad1b000016f0000000000000,Xbox 360 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,
+030000005e0400009102000000000000,Xbox 360 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,
+03000000ad1b00008e02000000000000,Xbox 360 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,
+03000000c62400000053000000000000,Xbox 360 Controller,a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b8,lefttrigger:b10,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b9,righttrigger:b11,rightx:a3,righty:a4,start:b7,x:b2,y:b3,platform:Windows,
+03000000380700002644000000000000,Xbox 360 Controller,a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b7,lefttrigger:b10,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b9,righttrigger:b11,rightx:a2,righty:a5,start:b8,x:b2,y:b3,platform:Windows,
+03000000380700002045000000000000,Xbox 360 Controller,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a5,start:b9,x:b0,y:b3,platform:Windows,
+030000005e0400001907000000000000,Xbox 360 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,
+03000000380700001647000000000000,Xbox 360 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,
+03000000380700002647000000000000,Xbox 360 Controller,a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b8,lefttrigger:b10,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b9,righttrigger:b11,rightx:a3,righty:a4,start:b7,x:b2,y:b3,platform:Windows,
+03000000380700003647000000000000,Xbox 360 Controller,a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b8,lefttrigger:b10,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b9,righttrigger:b11,rightx:a7,righty:a5,start:b7,x:b2,y:b3,platform:Windows,
+030000003807000026b7000000000000,Xbox 360 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,
+03000000c6240000fdfa000000000000,Xbox 360 Controller,a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b8,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b9,rightx:a3,righty:a4,start:b7,x:b2,y:b3,platform:Windows,
+03000000ad1b000000fd000000000000,Xbox 360 Controller,a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b8,lefttrigger:b10,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b9,righttrigger:b11,rightx:a3,righty:a4,start:b7,x:b2,y:b3,platform:Windows,
+03000000ad1b000001fd000000000000,Xbox 360 Controller,a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b8,lefttrigger:a5,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b9,righttrigger:a2,rightx:a3,righty:a4,start:b7,x:b2,y:b3,platform:Windows,
+030000002e160000efbe000000000000,Xbox 360 Controller,a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,lefttrigger:b10,rightshoulder:b5,righttrigger:b11,start:b7,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,
+030000002a0600002000000000000000,Xbox Controller,a:b0,b:b1,back:b13,dpdown:b9,dpleft:b10,dpright:b11,dpup:b8,leftshoulder:b5,leftstick:b14,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b4,rightstick:b15,righttrigger:b7,rightx:a2,righty:a5,start:b12,x:b2,y:b3,platform:Windows,
+030000005e0400000202000000000000,Xbox Controller,a:b0,b:b1,back:b7,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b5,leftstick:b8,lefttrigger:b10,leftx:a0,lefty:a1,rightshoulder:b4,rightstick:b9,righttrigger:b11,rightx:a3,righty:a4,start:b6,x:b2,y:b3,platform:Windows,
+030000005e0400008502000000000000,Xbox Controller,a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b8,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b9,rightx:a3,righty:a4,start:b7,x:b2,y:b3,platform:Windows,
+030000005e0400008702000000000000,Xbox Controller,a:b0,b:b1,back:b7,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b5,leftstick:b8,lefttrigger:b10,leftx:a0,lefty:a1,rightshoulder:b4,rightstick:b9,righttrigger:b7,rightx:a3,righty:a4,start:b6,x:b2,y:b3,platform:Windows,
+030000005e0400008902000000000000,Xbox Controller,a:b0,b:b1,back:b7,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b10,leftstick:b8,lefttrigger:b5,leftx:a0,lefty:a1,rightshoulder:b11,rightstick:b9,righttrigger:b4,rightx:a3,righty:a4,start:b6,x:b2,y:b3,platform:Windows,
+03000000380700001645000000000000,Xbox Controller,a:b0,b:b1,back:b7,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b5,leftstick:b8,lefttrigger:b10,leftx:a0,lefty:a1,rightshoulder:b4,rightstick:b9,righttrigger:b11,rightx:a3,righty:a4,start:b6,x:b2,y:b3,platform:Windows,
+03000000380700002645000000000000,Xbox Controller,a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b8,lefttrigger:b10,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b9,righttrigger:b11,rightx:a3,righty:a4,start:b7,x:b2,y:b3,platform:Windows,
+03000000380700003645000000000000,Xbox Controller,a:b0,b:b1,back:b7,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b5,leftstick:b8,lefttrigger:b10,leftx:a0,lefty:a1,rightshoulder:b4,rightstick:b9,righttrigger:b11,rightx:a3,righty:a4,start:b6,x:b2,y:b3,platform:Windows,
+03000000380700008645000000000000,Xbox 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,
+03000000120c00001088000000000000,Xbox 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,
+03000000300f00008888000000000000,Xbox Controller,a:b0,b:b1,back:b7,dpdown:b13,dpleft:b10,dpright:b11,dpup:b12,leftshoulder:b5,leftstick:b8,lefttrigger:b10,leftx:a0,lefty:a1,rightshoulder:b4,rightstick:b9,righttrigger:b11,rightx:a3,righty:a4,start:b6,x:b2,y:b3,platform:Windows,
+03000000120c00000a88000000000000,Xbox Controller,a:b0,b:b1,back:b7,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b8,lefttrigger:b10,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b9,righttrigger:b11,rightx:a2,righty:a4,start:b6,x:b2,y:b3,platform:Windows,
+030000000d0f00006300000000000000,Xbox One Controller,a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b8,lefttrigger:b8,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b9,righttrigger:b9,rightx:a3,righty:a4,start:b7,x:b2,y:b3,platform:Windows,
+030000005e040000e002000000000000,Xbox One 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,
+030000005e040000d102000000000000,Xbox One 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,
+030000005e040000e302000000000000,Xbox One 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,
+030000006f0e0000a802000000000000,Xbox One 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,
+030000006f0e0000c802000000000000,Xbox One Controller,a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,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:Windows,
+030000005e040000dd02000000000000,Xbox One 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,
+030000005e040000fd02000000000000,Xbox One 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,
+03000000c62400003a54000000000000,Xbox One 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,
+030000005e0400000c0b000000000000,Xbox One 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,
+03000000450c00002043000000000000,Xeox Gamepad SL6556BK,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,
+030000006f0e00000300000000000000,XGear,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:a5,righty:a2,start:b9,x:b3,y:b0,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,
03000000172700004431000000000000,XiaoMi Game Controller,a:b0,b:b1,back:b10,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b20,leftshoulder:b6,leftstick:b13,lefttrigger:b8,leftx:a0,lefty:a1,rightshoulder:b7,rightstick:b14,righttrigger:a7,rightx:a2,righty:a5,start:b11,x:b3,y:b4,platform:Windows,
03000000786901006e70000000000000,XInput 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,
xinput,XInput 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,
-03000000790000004f18000000000000,ZD-T 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,
-03000000120c0000101e000000000000,ZEROPLUS P4 Wired Gamepad,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:a3,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:a4,rightx:a2,righty:a5,start:b9,x:b0,y:b3,platform:Windows,
+03000000790000004f18000000000000,ZDT Android 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:b8,leftx:a0,lefty:a1,rightshoulder:b7,rightstick:b14,righttrigger:b9,rightx:a3,righty:a4,start:b11,x:b3,y:b4,platform:Windows,
+03000000120c0000101e000000000000,Zeroplus P4 Wired Gamepad,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:a3,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:a4,rightx:a2,righty:a5,start:b9,x:b0,y:b3,platform:Windows,
+030000007e0500001720000000000000,Nintendo Switch SNES Controller,a:b0,b:b1,x:b2,y:b3,back:b8,start:b9,-leftx:h0.8,+leftx:h0.2,-lefty:h0.1,+lefty:h0.4,leftshoulder:b4,rightshoulder:b5,lefttrigger:b6,righttrigger:b7,platform:Windows,
# Mac OS X
030000008f0e00000300000009010000,2In1 USB Joystick,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:Mac OS X,
@@ -369,13 +705,15 @@ xinput,XInput Controller,a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,
03000000c82d00005106000000010000,8BitDo M30 Gamepad,a:b1,b:b0,back:b10,guide:b2,leftshoulder:b6,lefttrigger:a5,leftx:a0,lefty:a1,rightshoulder:b7,righttrigger:a4,start:b11,x:b4,y:b3,platform:Mac OS X,
03000000c82d00001590000001000000,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: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,
03000000c82d00006528000000010000,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:a5,leftx:a0,lefty:a1,rightshoulder:b7,rightstick:b14,righttrigger:a4,rightx:a2,righty:a3,start:b11,x:b4,y:b3,platform:Mac OS X,
+03000000c82d000012ab000001000000,8BitDo NES30,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,
+03000000c82d00002028000000010000,8BitDo NES30,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,
030000003512000012ab000001000000,8BitDo NES30 Gamepad,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:Mac OS X,
03000000022000000090000001000000,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,
03000000203800000900000000010000,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,
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,
+03000000c82d00004028000000010000,8Bitdo SN30 GamePad,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: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,
@@ -385,42 +723,45 @@ 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,
+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,
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,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,
+03000000120c0000200e000000010000,Brook Mars PS4 Controller,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:a3,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:a4,rightx:a2,righty:a5,start:b9,x:b0,y:b3,platform:Mac OS X,
+03000000120c0000210e000000010000,Brook Mars PS4 Controller,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b0,y:b3,platform: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,
+030000000d0f00008400000000010000,Fighting Commander,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:a3,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:a4,rightx:a2,righty:a5,start:b9,x:b0,y:b3,platform:Mac OS X,
+030000000d0f00008500000000010000,Fighting Commander,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger: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,
+03000000151900004000000001000000,Flydigi Vader 2,a:b0,b:b1,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b10,lefttrigger:a5,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:a4,rightx:a2,righty:a3,start:b9,x:b2,y:b3,platform:Mac OS X,
+03000000b40400001124000000000000,Flydigi Vader 2,a:b0,b:b1,back:b10,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b6,leftstick:b12,lefttrigger:b8,leftx:a0,lefty:a1,paddle1:b4,paddle2:b5,paddle3:b17,rightshoulder:b7,rightstick:b13,righttrigger:b9,rightx:a3,righty:a4,start:b11,x:b2,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,
+03000000ad1b000001f9000000000000,Gamestop BB070 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,
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,
+030000008f0e00000300000007010000,GreenAsia 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,
-030000000d0f00005f00000000000000,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,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,
-030000000d0f00005e00000000000000,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,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,
-030000000d0f00004d00000000000000,HORI Gem Pad 3,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,
+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,
+030000000d0f00005f00000000000000,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,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,
+030000000d0f00005e00000000000000,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,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,
+030000000d0f00004d00000000000000,Hori Gem Pad 3,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,
030000000d0f00009200000000010000,Hori Pokken Tournament DX Pro Pad,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,
-030000000d0f00006e00000000010000,HORIPAD 4 (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,
-030000000d0f00006600000000010000,HORIPAD 4 (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,
-030000000d0f00006600000000000000,HORIPAD FPS PLUS 4,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:a4,rightx:a2,righty:a5,start:b9,x:b0,y:b3,platform:Mac OS X,
-030000000d0f0000ee00000000010000,HORIPAD mini4,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a5,start:b9,x:b0,y:b3,platform:Mac OS X,
+030000000d0f00006e00000000010000,Horipad 4 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,
+030000000d0f00006600000000010000,Horipad 4 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,
+030000000d0f00006600000000000000,Horipad FPS Plus 4,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:a4,rightx:a2,righty:a5,start:b9,x:b0,y:b3,platform:Mac OS X,
+030000000d0f0000ee00000000010000,Horipad Mini 4,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a5,start:b9,x:b0,y:b3,platform:Mac OS X,
030000008f0e00001330000011010000,HuiJia SNES Controller,a:b4,b:b2,back:b16,dpdown:+a2,dpleft:-a0,dpright:+a0,dpup:-a2,leftshoulder:b12,rightshoulder:b14,start:b18,x:b6,y:b0,platform:Mac OS X,
-03000000830500006020000000010000,iBuffalo SNES Controller,a:b1,b:b0,back:b6,dpdown:+a1,dpleft:-a0,dpright:+a0,dpup:-a1,leftshoulder:b4,rightshoulder:b5,start:b7,x:b3,y:b2,platform:Mac OS X,
-03000000830500006020000000000000,iBuffalo USB 2-axis 8-button Gamepad,a:b1,b:b0,back:b6,leftshoulder:b4,leftx:a0,lefty:a1,rightshoulder:b5,start:b7,x:b3,y:b2,platform:Mac OS X,
+03000000830500006020000000000000,iBuffalo Gamepad,a:b1,b:b0,back:b6,leftshoulder:b4,leftx:a0,lefty:a1,rightshoulder:b5,start:b7,x:b3,y:b2,platform:Mac OS X,
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:Mac OS X,
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:Mac OS X,
03000000242f00002d00000007010000,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:Mac OS X,
@@ -429,7 +770,7 @@ xinput,XInput Controller,a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,
030000006d04000016c2000014040000,Logitech Dual Action,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b0,y:b3,platform:Mac OS X,
030000006d04000016c2000000000000,Logitech F310 Gamepad (DInput),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,
030000006d04000018c2000000000000,Logitech F510 Gamepad (DInput),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,
-030000006d04000019c2000005030000,Logitech F710,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b0,y:b3,platform:Mac OS X,
+030000006d04000019c2000005030000,Logitech F710 Gamepad,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,
030000006d0400001fc2000000000000,Logitech F710 Gamepad (XInput),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,
030000006d04000018c2000000010000,Logitech RumblePad 2 USB,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,
030000006d04000019c2000000000000,Logitech Wireless Gamepad (DInput),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,
@@ -437,7 +778,7 @@ 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,
+03000000790000000600000007010000,Marvo GT-004,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: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,
@@ -445,21 +786,21 @@ xinput,XInput Controller,a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,
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,
+03000000d8140000cecf000000000000,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 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,
03000000d62000007162000001000000,Moga Pro 2 HID,a:b0,b:b1,back:b9,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:b6,x:b2,y:b3,platform:Mac OS X,
-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,
+03000000c62400002a89000000010000,MOGA XP5A 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 XP5A 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,
+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,
+030000008f0e00000300000000000000,Piranha Xtreme PS3 Controller,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,
@@ -472,15 +813,17 @@ xinput,XInput Controller,a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,
030000004c050000cc09000000010000,PS4 Controller,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:a3,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:a4,rightx:a2,righty:a5,start:b9,x:b0,y:b3,platform:Mac OS X,
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:Mac OS X,
030000008916000000fd000000000000,Razer Onza TE,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,
-03000000321500000204000000010000,Razer Panthera (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,
-03000000321500000104000000010000,Razer Panthera (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,
-03000000321500000010000000010000,Razer RAIJU,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,
+03000000321500000204000000010000,Razer Panthera 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,
+03000000321500000104000000010000,Razer Panthera 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,
+03000000321500000010000000010000,Razer Raiju,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,
03000000321500000507000001010000,Razer Raiju Mobile,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,
03000000321500000011000000010000,Razer Raion Fightpad 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: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,
03000000321500000009000000020000,Razer Serval,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:Mac OS X,
030000003215000000090000163a0000,Razer Serval,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:Mac OS X,
0300000032150000030a000000000000,Razer Wildcat,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,
-03000000790000001100000000000000,Retrolink Classic Controller,a:b2,b:b1,back:b8,leftshoulder:b4,leftx:a3,lefty:a4,rightshoulder:b5,start:b9,x:b3,y:b0,platform:Mac OS X,
+03000000830500006020000000010000,Retro Controller,a:b0,b:b1,back:b6,dpdown:+a1,dpleft:-a0,dpright:+a0,dpup:-a1,leftshoulder:b4,lefttrigger:b5,rightshoulder:b8,righttrigger:b9,start:b7,x:b2,y:b3,platform:Mac OS X,
+03000000790000001100000000000000,Retro Controller,a:b1,b:b2,back:b8,dpdown:+a4,dpleft:-a3,dpright:+a3,dpup:-a4,leftshoulder:b6,lefttrigger:b7,rightshoulder:b4,righttrigger:b5,start:b9,x:b0,y:b3,platform:Mac OS X,
+03000000790000001100000005010000,Retro Controller,a:b1,b:b2,back:b8,dpdown:+a4,dpleft:-a3,dpright:+a3,dpup:-a4,leftshoulder:b6,lefttrigger:b7,rightshoulder:b5,righttrigger:b4,start:b9,x:b0,y:b3,platform:Mac OS X,
03000000790000001100000006010000,Retrolink SNES Controller,a:b2,b:b1,back:b8,dpdown:+a4,dpleft:-a3,dpright:+a3,dpup:-a4,leftshoulder:b4,rightshoulder:b5,start:b9,x:b3,y:b0,platform:Mac OS X,
030000006b140000010d000000010000,Revolution Pro 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,
030000006b140000130d000000010000,Revolution Pro Controller 3,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,
@@ -498,10 +841,12 @@ xinput,XInput Controller,a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,
03000000110100002014000000000000,SteelSeries Nimbus,a:b0,b:b1,dpdown:b9,dpleft:b11,dpright:b10,dpup:b8,leftshoulder:b4,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,righttrigger:b7,rightx:a2,righty:a3,start:b12,x:b2,y:b3,platform:Mac OS X,
03000000110100002014000001000000,SteelSeries Nimbus,a:b0,b:b1,dpdown:b9,dpleft:b11,dpright:b10,dpup:b8,guide:b12,leftshoulder:b4,lefttrigger:b6,leftx:a0,lefty:a1~,rightshoulder:b5,righttrigger:b7,rightx:a2,righty:a3~,x:b2,y:b3,platform:Mac OS X,
03000000381000002014000001000000,SteelSeries Nimbus,a:b0,b:b1,dpdown:b9,dpleft:b11,dpright:b10,dpup:b8,guide:b12,leftshoulder:b4,lefttrigger:b6,leftx:a0,lefty:a1~,rightshoulder:b5,righttrigger:b7,rightx:a2,righty:a3~,x:b2,y:b3,platform:Mac OS X,
+05000000484944204465766963650000,SteelSeries Nimbus Plus,a:b0,b:b1,back:b15,dpdown:b11,dpleft:b13,dpright:b12,dpup:b10,guide:b16,leftshoulder:b4,leftstick:b8,lefttrigger:b6,leftx:a0,lefty:a1~,rightshoulder:b5,rightstick:b9,righttrigger:b7,rightx:a2,righty:a3~,start:b14,x:b2,y:b3,platform:Mac OS X,
+05000000556e6b6e6f776e2048494400,SteelSeries Nimbus Plus,a:b0,b:b1,back:b15,dpdown:b11,dpleft:b13,dpright:b12,dpup:b10,guide:b16,leftshoulder:b4,leftstick:b8,lefttrigger:b6,leftx:a0,lefty:a1~,rightshoulder:b5,rightstick:b9,righttrigger:b7,rightx:a2,righty:a3~,start:b14,x:b2,y:b3,platform:Mac OS X,
050000004e696d6275732b0000000000,SteelSeries Nimbus Plus,a:b0,b:b1,back:b15,dpdown:b11,dpleft:b13,dpright:b12,dpup:b10,guide:b16,leftshoulder:b4,leftstick:b8,lefttrigger:b6,leftx:a0,lefty:a1~,rightshoulder:b5,rightstick:b9,righttrigger:b7,rightx:a2,righty:a3~,start:b14,x:b2,y:b3,platform:Mac OS X,
03000000110100001714000000000000,SteelSeries Stratus XL,a:b0,b:b1,dpdown:b9,dpleft:b11,dpright:b10,dpup:b8,leftshoulder:b4,lefttrigger:b6,leftx:a0,lefty:a1~,rightshoulder:b5,righttrigger:b7,rightx:a2,righty:a3~,start:b12,x:b2,y:b3,platform:Mac OS X,
03000000110100001714000020010000,SteelSeries Stratus XL,a:b0,b:b1,dpdown:b9,dpleft:b11,dpright:b10,dpup:b8,leftshoulder:b4,lefttrigger:b6,leftx:a0,lefty:a1~,rightshoulder:b5,righttrigger:b7,rightx:a2,righty:a3~,start:b12,x:b2,y:b3,platform:Mac OS X,
-03000000457500002211000000010000,SZMY-POWER PC Gamepad,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b0,y:b3,platform:Mac OS X,
+03000000457500002211000000010000,SZMY Power PC Gamepad,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b0,y:b3,platform:Mac OS X,
030000004f04000015b3000000000000,Thrustmaster Dual Analog 3.2,a:b0,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b10,lefttrigger:b5,leftx:a0,lefty:a1,rightshoulder:b6,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b1,y:b3,platform:Mac OS X,
030000004f0400000ed0000000020000,ThrustMaster eSwap PRO 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,
030000004f04000000b3000000000000,Thrustmaster Firestorm Dual Power,a:b0,b:b2,back:b9,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b8,leftshoulder:b4,leftstick:b11,lefttrigger:b5,leftx:a0,lefty:a1,rightshoulder:b6,righttrigger:b7,rightx:a2,righty:a3,start:b10,x:b1,y:b3,platform:Mac OS X,
@@ -513,7 +858,7 @@ xinput,XInput Controller,a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,
03000000791d00000103000009010000,Wii Classic Controller,a:b2,b:b1,back:b8,dpdown:b14,dpleft:b15,dpright:b13,dpup:b12,guide:b10,leftshoulder:b6,lefttrigger:b4,leftx:a0,lefty:a1,rightshoulder:b7,righttrigger:b5,rightx:a2,righty:a3,start:b9,x:b3,y:b0,platform:Mac OS X,
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,
+030000005e0400008e02000000000000,Xbox 360 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,
@@ -524,28 +869,33 @@ xinput,XInput Controller,a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,
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,
030000005e040000130b000001050000,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:Mac OS X,
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:Mac OS X,
+030000005e040000130b000009050000,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:Mac OS X,
+030000005e040000200b000011050000,Xbox Wireless 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:Mac OS X,
030000005e040000e002000000000000,Xbox Wireless 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:Mac OS X,
030000005e040000e002000003090000,Xbox Wireless 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:Mac OS X,
030000005e040000ea02000000000000,Xbox Wireless 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,
030000005e040000fd02000003090000,Xbox Wireless Controller,a:b0,b:b1,back:b16,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b15,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,
03000000172700004431000029010000,XiaoMi Game Controller,a:b0,b:b1,back:b10,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b15,leftshoulder:b6,leftstick:b13,lefttrigger:b8,leftx:a0,lefty:a1,rightshoulder:b7,rightstick:b14,righttrigger:a6,rightx:a2,righty:a5,start:b11,x:b3,y:b4,platform:Mac OS X,
-03000000120c0000100e000000010000,ZEROPLUS P4 Gamepad,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger: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,
-03000000120c0000101e000000010000,ZEROPLUS P4 Wired Gamepad,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger: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,
+03000000120c0000100e000000010000,Zeroplus P4 Gamepad,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger: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,
+03000000120c0000101e000000010000,Zeroplus P4 Wired Gamepad,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger: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,
# Linux
+03000000021000000090000011010000,8BitDo FC30 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:Linux,
03000000c82d00000090000011010000,8BitDo FC30 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:Linux,
05000000c82d00001038000000010000,8Bitdo FC30 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:Linux,
05000000c82d00005106000000010000,8BitDo M30,a:b0,b:b1,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b8,lefttrigger:b9,leftx:a0,lefty:a1,rightshoulder:b6,righttrigger:b7,start:b11,x:b3,y:b4,platform:Linux,
03000000c82d00001590000011010000,8BitDo N30 Pro 2,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:Linux,
05000000c82d00006528000000010000,8BitDo N30 Pro 2,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:Linux,
+03000000008000000210000011010000,8BitDo NES30,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:Linux,
03000000c82d00000310000011010000,8BitDo NES30,a:b0,b:b1,back:b10,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b7,lefttrigger:b6,rightshoulder:b9,righttrigger:b8,start:b11,x:b3,y:b4,platform:Linux,
05000000c82d00008010000000010000,8BitDo NES30,a:b0,b:b1,back:b10,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b7,lefttrigger:b6,rightshoulder:b9,righttrigger:b8,start:b11,x:b3,y:b4,platform:Linux,
03000000022000000090000011010000,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:Linux,
05000000203800000900000000010000,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:Linux,
05000000c82d00002038000000010000,8Bitdo NES30 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:a5,leftx:a0,lefty:a1,rightshoulder:b7,rightstick:b14,righttrigger:a4,rightx:a2,righty:a3,start:b11,x:b4,y:b3,platform:Linux,
-03000000c82d00000190000011010000,8Bitdo NES30 Pro 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:a4,leftx:a0,lefty:a1,rightshoulder:b7,rightstick:b14,righttrigger:a5,rightx:a2,righty:a3,start:b11,x:b4,y:b3,platform:Linux,
+03000000c82d00000190000011010000,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:a4,leftx:a0,lefty:a1,rightshoulder:b7,rightstick:b14,righttrigger:a5,rightx:a2,righty:a3,start:b11,x:b4,y:b3,platform:Linux,
05000000c82d00000060000000010000,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:Linux,
05000000c82d00000061000000010000,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:a5,leftx:a0,lefty:a1,rightshoulder:b7,rightstick:b14,righttrigger:a4,rightx:a2,righty:a3,start:b11,x:b4,y:b3,platform:Linux,
+030000003512000021ab000010010000,8BitDo SFC30,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,start:b11,x:b4,y:b3,platform:Linux,
03000000c82d000021ab000010010000,8BitDo SFC30,a:b1,b:b0,back:b10,leftshoulder:b6,leftx:a0,lefty:a1,rightshoulder:b7,start:b11,x:b4,y:b3,platform:Linux,
030000003512000012ab000010010000,8Bitdo SFC30 GamePad,a:b2,b:b1,back:b6,dpdown:+a1,dpleft:-a0,dpright:+a0,dpup:-a1,leftshoulder:b4,rightshoulder:b5,start:b7,x:b3,y:b0,platform:Linux,
05000000102800000900000000010000,8Bitdo SFC30 GamePad,a:b1,b:b0,back:b10,leftshoulder:b6,leftx:a0,lefty:a1,rightshoulder:b7,start:b11,x:b4,y:b3,platform:Linux,
@@ -566,12 +916,12 @@ xinput,XInput Controller,a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,
050000005e040000e002000030110000,8BitDo Zero 2 (XInput),a:b0,b:b1,back:b6,dpdown:+a1,dpleft:-a0,dpright:+a0,dpup:-a1,leftshoulder:b4,rightshoulder:b5,start:b7,x:b2,y:b3,platform:Linux,
05000000a00500003232000001000000,8Bitdo Zero GamePad,a:b0,b:b1,back:b10,leftshoulder:b6,leftx:a0,lefty:a1,rightshoulder:b7,start:b11,x:b3,y:b4,platform:Linux,
05000000a00500003232000008010000,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:Linux,
-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:Linux,
+03000000c01100000355000011010000,Acrux Gamepad,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b0,y:b3,platform:Linux,
030000006f0e00001302000000010000,Afterglow,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,
030000006f0e00003901000020060000,Afterglow Controller for Xbox One,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,
030000006f0e00003901000000430000,Afterglow Prismatic 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,
030000006f0e00003901000013020000,Afterglow Prismatic Wired Controller 048-007-NA,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,
-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,
+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,
@@ -579,80 +929,86 @@ xinput,XInput Controller,a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,
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,
+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,
+03000000503200000210000000000000,Atari Game Controller,a:b0,b:b1,back:b9,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b10,leftshoulder:b4,leftstick:b6,lefttrigger:a5,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b7,righttrigger:a4,rightx:a2,righty:a3,start:b8,x:b2,y:b3,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,
+03000000c62400001b89000011010000,BDA MOGA XP5X 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,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,
+03000000c21100000791000011010000,Be1 GC101 Controller 1.03,a:b2,b:b1,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b3,y:b0,platform:Linux,
+03000000c31100000791000011010000,Be1 GC101 GAMEPAD 1.03,a:b0,b:b1,back:b10,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b6,leftstick:b13,lefttrigger:a5,leftx:a0,lefty:a1,rightshoulder:b7,rightstick:b14,righttrigger:a4,rightx:a2,righty:a3,start:b11,x:b3,y:b4,platform:Linux,
+030000005e0400008e02000003030000,Be1 GC101 Xbox 360,a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b8,leftshoulder:b4,leftstick:b9,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b10,righttrigger:a5,rightx:a3,righty:a4,start:b7,x:b2,y:b3,platform:Linux,
+05000000bc2000000055000001000000,BETOP AX1 BFM,a:b0,b:b1,back:b10,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b6,leftstick:b13,lefttrigger:b8,leftx:a0,lefty:a1,rightshoulder:b7,rightstick:b14,righttrigger:b9,rightx:a2,righty:a3,start:b11,x:b3,y:b4,platform:Linux,
+030000006b1400000209000011010000,Bigben,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b0,y:b3,platform:Linux,
+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 PS4 Controller,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:a3,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:a4,rightx:a2,righty:a5,start:b9,x:b0,y:b3,platform:Linux,
+03000000120c0000210e000011010000,Brook Mars PS4 Controller,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b0,y:b3,platform:Linux,
03000000120c0000f70e000011010000,Brook Universal Fighting Board,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:b6,rightshoulder:b5,rightstick:b11,righttrigger:b7,start:b9,x:b0,y:b3,platform:Linux,
-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,
+03000000ffff0000ffff000000010000,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,
03000000260900008888000000010000,Cyber Gadget GameCube Controller,a:b0,b:b1,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,lefttrigger:a4,leftx:a0,lefty:a1,rightshoulder:b6,righttrigger:a5,rightx:a2,righty:a3~,start:b7,x:b2,y:b3,platform:Linux,
-03000000a306000022f6000011010000,Cyborg 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:Linux,
-03000000b40400000a01000000010000,CYPRESS USB Gamepad,a:b0,b:b1,back:b5,guide:b2,leftshoulder:b6,leftx:a0,lefty:a1,rightshoulder:b7,start:b8,x:b3,y:b4,platform:Linux,
-03000000790000000600000010010000,DragonRise Inc. Generic USB Joystick,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:Linux,
+03000000a306000022f6000011010000,Cyborg V3 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:Linux,
030000004f04000004b3000010010000,Dual Power 2,a:b0,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b10,lefttrigger:b5,leftx:a0,lefty:a1,rightshoulder:b6,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b1,y:b3,platform:Linux,
030000006f0e00003001000001010000,EA Sports 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,
-03000000341a000005f7000010010000,GameCube {HuiJia USB box},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,
+03000000c11100000191000011010000,EasySMX,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,
+030000006e0500000320000010010000,Elecom U3613M,a:b2,b:b3,back:b10,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b8,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b9,righttrigger:b7,rightx:a2,righty:a3,start:b11,x:b0,y:b1,platform:Linux,
+03000000b40400001124000011010000,Flydigi Vader 2,a:b0,b:b1,back:b10,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b6,leftstick:b12,lefttrigger:a5,leftx:a0,lefty:a1,paddle1:b2,paddle2:b5,paddle4:b17,rightshoulder:b7,rightstick:b13,righttrigger:a4,rightx:a2,righty:a3,start:b11,x:b3,y:b4,platform:Linux,
+05000000151900004000000001000000,Flydigi Vader 2,a:b0,b:b1,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b10,lefttrigger:a5,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:a4,rightx:a2,righty:a3,start:b9,x:b2,y:b3,platform:Linux,
+03000000341a000005f7000010010000,HuiJia GameCube Controller Adpater,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,
03000000bc2000000055000011010000,GameSir G3w,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,
+05000000ac0500002d0200001b010000,Gamesir G4s,a:b0,b:b1,back:b10,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b33,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,
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:Linux,
030000006f0e00000104000000010000,Gamestop 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,
-030000008f0e00000800000010010000,Gasia Co. Ltd PS(R) 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,
-030000006f0e00001304000000010000,Generic X-Box 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,
+030000008f0e00000800000010010000,Gasia PlayStation 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,
+030000006f0e00001304000000010000,Xbox 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,
03000000451300000010000010010000,Genius Maxfire Grandias 12,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,
-03000000f0250000c183000010010000,Goodbetterbest Ltd USB 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,
+03000000f0250000c183000010010000,Goodbetterbest 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,
0300000079000000d418000000010000,GPD Win 2 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,
030000007d0400000540000000010000,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:Linux,
-03000000280400000140000000010000,Gravis GamePad Pro USB ,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:Linux,
-030000008f0e00000610000000010000,GreenAsia Electronics 4Axes 12Keys GamePad ,a:b2,b:b1,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b6,leftstick:b9,lefttrigger:b4,leftx:a0,lefty:a1,rightshoulder:b7,rightstick:b10,righttrigger:b5,rightx:a3,righty:a2,start:b11,x:b3,y:b0,platform:Linux,
-030000008f0e00001200000010010000,GreenAsia Inc. USB Joystick,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:Linux,
+03000000280400000140000000010000,Gravis GamePad Pro USB,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:Linux,
+030000008f0e00000610000000010000,GreenAsia Electronics Controller,a:b2,b:b1,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b6,leftstick:b9,lefttrigger:b4,leftx:a0,lefty:a1,rightshoulder:b7,rightstick:b10,righttrigger:b5,rightx:a3,righty:a2,start:b11,x:b3,y:b0,platform:Linux,
+030000008f0e00001200000010010000,GreenAsia USB Joystick,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:Linux,
0500000047532067616d657061640000,GS gamepad,a:b0,b:b1,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b8,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,
03000000f0250000c383000010010000,GT VX2,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,
06000000adde0000efbe000002010000,Hidromancer 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:b2,y:b3,platform:Linux,
-03000000d81400000862000011010000,HitBox (PS3/PC) Analog Mode,a:b1,b:b2,back:b8,guide:b9,leftshoulder:b4,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,righttrigger:b7,start:b12,x:b0,y:b3,platform:Linux,
-03000000c9110000f055000011010000,HJC Game GAMEPAD,a:b0,b:b1,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b2,y:b3,platform:Linux,
-03000000632500002605000010010000,HJD-X,a:b0,b:b1,back:b10,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b6,leftstick:b13,lefttrigger:a4,leftx:a0,lefty:a1,rightshoulder:b7,rightstick:b14,righttrigger:a5,rightx:a2,righty:a3,start:b11,x:b3,y:b4,platform:Linux,
-030000000d0f00000d00000000010000,hori,a:b0,b:b6,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b10,leftshoulder:b3,leftx:b4,lefty:b5,rightshoulder:b7,start:b9,x:b1,y:b2,platform:Linux,
-030000000d0f00001000000011010000,HORI CO. LTD. FIGHTING STICK 3,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,lefttrigger:b6,rightshoulder:b5,righttrigger:b7,start:b9,x:b0,y:b3,platform:Linux,
-030000000d0f0000c100000011010000,HORI CO. LTD. HORIPAD S,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b13,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,
-030000000d0f00006a00000011010000,HORI CO. LTD. Real Arcade Pro.4,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:a3,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:a4,rightx:a2,righty:a5,start:b9,x:b0,y:b3,platform:Linux,
-030000000d0f00006b00000011010000,HORI CO. LTD. Real Arcade Pro.4,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b0,y:b3,platform:Linux,
-030000000d0f00002200000011010000,HORI CO. LTD. REAL ARCADE Pro.V3,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,lefttrigger:b6,rightshoulder:b5,righttrigger:b7,start:b9,x:b0,y:b3,platform:Linux,
-030000000d0f00008500000010010000,HORI Fighting Commander,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b0,y:b3,platform:Linux,
+03000000d81400000862000011010000,HitBox PS3 PC Analog Mode,a:b1,b:b2,back:b8,guide:b9,leftshoulder:b4,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,righttrigger:b7,start:b12,x:b0,y:b3,platform:Linux,
+03000000c9110000f055000011010000,HJC Game Gamepqd,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,
+03000000300f00001210000010010000,Qanba Joystick Plus,a:b0,b:b1,back:b8,leftshoulder:b5,lefttrigger:b7,leftx:a0,lefty:a1,rightshoulder:b4,righttrigger:b6,start:b9,x:b2,y:b3,platform:Linux,
+03000000632500002605000010010000,HJDX,a:b0,b:b1,back:b10,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b6,leftstick:b13,lefttrigger:a4,leftx:a0,lefty:a1,rightshoulder:b7,rightstick:b14,righttrigger:a5,rightx:a2,righty:a3,start:b11,x:b3,y:b4,platform:Linux,
+030000000d0f00000d00000000010000,Hori,a:b0,b:b6,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b10,leftshoulder:b3,rightshoulder:b7,start:b9,x:b1,y:b2,platform:Linux,
+030000000d0f00001000000011010000,Hori Fighting Stick 3,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,lefttrigger:b6,rightshoulder:b5,righttrigger:b7,start:b9,x:b0,y:b3,platform:Linux,
+030000000d0f0000c100000011010000,Horipad S,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b13,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,
+030000000d0f00006a00000011010000,Hori Real Arcade Pro 4,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:a3,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:a4,rightx:a2,righty:a5,start:b9,x:b0,y:b3,platform:Linux,
+030000000d0f00006b00000011010000,Hori Real Arcade Pro 4,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b0,y:b3,platform:Linux,
+030000000d0f00002200000011010000,Hori Real Arcade Pro 3,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,lefttrigger:b6,rightshoulder:b5,righttrigger:b7,start:b9,x:b0,y:b3,platform:Linux,
+030000000d0f00008500000010010000,Hori Fighting Commander,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b0,y:b3,platform:Linux,
030000000d0f00008600000002010000,Hori Fighting Commander,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,
-030000000d0f00005f00000011010000,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:Linux,
-030000000d0f00005e00000011010000,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:Linux,
+030000000d0f00005f00000011010000,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:Linux,
+030000000d0f00005e00000011010000,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:Linux,
+030000000d0f00005001000009040000,Hori Fighting Commander OCTA,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,
03000000ad1b000001f5000033050000,Hori Pad EX Turbo 2,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,
+030000000d0f00003801000011010000,Hori PC Engine Mini Controller,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,start:b9,platform:Linux,
030000000d0f00009200000011010000,Hori Pokken Tournament DX Pro Pad,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:Linux,
-030000000d0f0000aa00000011010000,HORI Real Arcade Pro,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,
-030000000d0f0000d800000072056800,HORI Real Arcade Pro S,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:Linux,
-030000000d0f00001600000000010000,Hori Real Arcade Pro.EX-SE (Xbox 360),a:b0,b:b1,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b10,leftshoulder:b4,lefttrigger:b6,rightshoulder:b5,righttrigger:b7,start:b9,x:b2,y:b3,platform:Linux,
-030000000d0f00006e00000011010000,HORIPAD 4 (PS3),a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b0,y:b3,platform:Linux,
-030000000d0f00006600000011010000,HORIPAD 4 (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:Linux,
-030000000d0f0000ee00000011010000,HORIPAD mini4,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a5,start:b9,x:b0,y:b3,platform:Linux,
-030000000d0f00006700000001010000,HORIPAD ONE,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,
+030000000d0f0000aa00000011010000,Hori Real Arcade Pro,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,
+030000000d0f0000d800000072056800,Hori Real Arcade Pro S,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:Linux,
+030000000d0f00001600000000010000,Hori Real Arcade Pro EXSE,a:b0,b:b1,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b10,leftshoulder:b4,lefttrigger:b6,rightshoulder:b5,righttrigger:b7,start:b9,x:b2,y:b3,platform:Linux,
+030000000d0f00006e00000011010000,Horipad 4 PS3,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b0,y:b3,platform:Linux,
+030000000d0f00006600000011010000,Horipad 4 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:Linux,
+030000000d0f0000ee00000011010000,Horipad Mini 4,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a5,start:b9,x:b0,y:b3,platform:Linux,
+030000000d0f00006700000001010000,Horipad One,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,
030000008f0e00001330000010010000,HuiJia SNES Controller,a:b2,b:b1,back:b8,dpdown:+a1,dpleft:-a0,dpright:+a0,dpup:-a1,leftshoulder:b6,rightshoulder:b7,start:b9,x:b3,y:b0,platform:Linux,
03000000242e00008816000001010000,Hyperkin X91,a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b8,leftshoulder:b4,leftstick:b9,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b10,righttrigger:a5,rightx:a3,righty:a4,start:b7,x:b2,y:b3,platform:Linux,
-03000000830500006020000010010000,iBuffalo SNES Controller,a:b1,b:b0,back:b6,dpdown:+a1,dpleft:-a0,dpright:+a0,dpup:-a1,leftshoulder:b4,rightshoulder:b5,start:b7,x:b3,y:b2,platform:Linux,
-050000006964726f69643a636f6e0000,idroid:con,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b0,y:b3,platform:Linux,
-03000000b50700001503000010010000,impact,a:b2,b:b3,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b10,lefttrigger:b5,leftx:a0,lefty:a1,rightshoulder:b6,rightstick:b11,righttrigger:b7,rightx:a3,righty:a2,start:b9,x:b0,y:b1,platform:Linux,
-03000000d80400008200000003000000,IMS PCU#0 Gamepad Interface,a:b1,b:b0,back:b4,dpdown:+a1,dpleft:-a0,dpright:+a0,dpup:-a1,start:b5,x:b3,y:b2,platform:Linux,
-03000000fd0500000030000000010000,InterAct GoPad I-73000 (Fighting Game Layout),a:b3,b:b4,back:b6,leftx:a0,lefty:a1,rightshoulder:b2,righttrigger:b5,start:b7,x:b0,y:b1,platform:Linux,
-0500000049190000020400001b010000,Ipega PG-9069 - Bluetooth Gamepad,a:b0,b:b1,back:b10,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b161,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,
-03000000632500007505000011010000,Ipega PG-9099 - Bluetooth 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,
-030000006e0500000320000010010000,JC-U3613M - DirectInput Mode,a:b2,b:b3,back:b10,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b8,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b9,righttrigger:b7,rightx:a2,righty:a3,start:b11,x:b0,y:b1,platform:Linux,
+050000006964726f69643a636f6e0000,idroidcon Controller,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b0,y:b3,platform:Linux,
+03000000b50700001503000010010000,Impact,a:b2,b:b3,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b10,lefttrigger:b5,leftx:a0,lefty:a1,rightshoulder:b6,rightstick:b11,righttrigger:b7,rightx:a3,righty:a2,start:b9,x:b0,y:b1,platform:Linux,
+03000000d80400008200000003000000,IMS PCU0 Gamepad,a:b1,b:b0,back:b4,dpdown:+a1,dpleft:-a0,dpright:+a0,dpup:-a1,start:b5,x:b3,y:b2,platform:Linux,
+03000000fd0500000030000000010000,InterAct GoPad I73000,a:b3,b:b4,back:b6,leftx:a0,lefty:a1,rightshoulder:b2,righttrigger:b5,start:b7,x:b0,y:b1,platform:Linux,
+0500000049190000020400001b010000,Ipega PG 9069 Bluetooth Gamepad,a:b0,b:b1,back:b10,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b161,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,
+03000000632500007505000011010000,Ipega PG 9099 Bluetooth 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,
03000000300f00001001000010010000,Jess Tech Dual Analog Rumble Pad,a:b2,b:b3,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b10,lefttrigger:b5,leftx:a0,lefty:a1,rightshoulder:b6,rightstick:b11,righttrigger:b7,rightx:a3,righty:a2,start:b9,x:b0,y:b1,platform:Linux,
03000000300f00000b01000010010000,Jess Tech GGE909 PC Recoil Pad,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:a2,start:b9,x:b3,y:b0,platform:Linux,
03000000ba2200002010000001010000,Jess Technology USB Game Controller,a:b2,b:b1,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,rightx:a3,righty:a2,start:b9,x:b3,y:b0,platform:Linux,
@@ -664,7 +1020,7 @@ xinput,XInput Controller,a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,
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,
-030000006d040000d1ca000000000000,Logitech ChillStream,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,
+030000006d040000d1ca000000000000,Logitech Chillstream,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,
030000006d04000019c2000010010000,Logitech Cordless RumblePad 2,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,
030000006d04000016c2000010010000,Logitech Dual Action,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b0,y:b3,platform:Linux,
030000006d04000016c2000011010000,Logitech Dual Action,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b0,y:b3,platform:Linux,
@@ -673,24 +1029,25 @@ xinput,XInput Controller,a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,
030000006d0400001ec2000020200000,Logitech F510 Gamepad (XInput),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,
030000006d04000019c2000011010000,Logitech F710 Gamepad (DInput),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,
030000006d0400001fc2000005030000,Logitech F710 Gamepad (XInput),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,
-030000006d0400000ac2000010010000,Logitech Inc. WingMan RumblePad,a:b0,b:b1,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b6,lefttrigger:b7,leftx:a0,lefty:a1,rightshoulder:b5,righttrigger:b2,rightx:a3,righty:a4,x:b3,y:b4,platform:Linux,
+030000006d0400000ac2000010010000,Logitech WingMan RumblePad,a:b0,b:b1,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b6,lefttrigger:b7,leftx:a0,lefty:a1,rightshoulder:b5,righttrigger:b2,rightx:a3,righty:a4,x:b3,y:b4,platform:Linux,
030000006d04000018c2000010010000,Logitech RumblePad 2,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,
030000006d04000011c2000010010000,Logitech WingMan Cordless RumblePad,a:b0,b:b1,back:b2,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b5,leftshoulder:b6,lefttrigger:b9,leftx:a0,lefty:a1,rightshoulder:b7,righttrigger:b10,rightx:a3,righty:a4,start:b8,x:b3,y:b4,platform:Linux,
-050000004d4f435554452d3035305800,M54-PC,a:b0,b:b1,back:b10,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b6,leftstick:b13,lefttrigger:a5,leftx:a0,lefty:a1,rightshoulder:b7,rightstick:b14,righttrigger:a4,rightx:a2,righty:a3,start:b11,x:b3,y:b4,platform:Linux,
-05000000380700006652000025010000,Mad Catz C.T.R.L.R ,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,
-03000000380700005032000011010000,Mad Catz FightPad PRO (PS3),a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b0,y:b3,platform:Linux,
-03000000380700005082000011010000,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:Linux,
+050000004d4f435554452d3035335800,Mocute 053X,a:b0,b:b1,x:b2,y:b3,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:Linux
+050000004d4f435554452d3035305800,Mocute 054X,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,
+05000000380700006652000025010000,Mad Catz CTRLR,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,
+03000000380700005032000011010000,Mad Catz FightPad PRO PS3,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b0,y:b3,platform:Linux,
+03000000380700005082000011010000,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:Linux,
03000000ad1b00002ef0000090040000,Mad Catz Fightpad SFxT,a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b8,leftshoulder:b4,lefttrigger:a2,rightshoulder:b5,righttrigger:a5,start:b7,x:b2,y:b3,platform:Linux,
-03000000380700008034000011010000,Mad Catz fightstick (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:Linux,
-03000000380700008084000011010000,Mad Catz fightstick (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:Linux,
-03000000380700008433000011010000,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:Linux,
-03000000380700008483000011010000,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:Linux,
+03000000380700008034000011010000,Mad Catz fightstick 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:Linux,
+03000000380700008084000011010000,Mad Catz fightstick 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:Linux,
+03000000380700008433000011010000,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:Linux,
+03000000380700008483000011010000,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:Linux,
03000000380700001647000010040000,Mad Catz Wired 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,
-03000000380700003847000090040000,Mad Catz Wired Xbox 360 Controller (SFIV),a:b0,b:b1,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b10,leftshoulder:b4,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b2,y:b3,platform:Linux,
+03000000380700003847000090040000,Mad Catz Wired Xbox 360 Controller,a:b0,b:b1,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b10,leftshoulder:b4,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b2,y:b3,platform:Linux,
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,
+03000000242f0000f700000001010000,Mayflash 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: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,
@@ -700,29 +1057,31 @@ xinput,XInput Controller,a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,
0300000025090000e803000001010000,Mayflash Wii Classic Controller,a:b1,b:b0,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b10,leftshoulder:a4,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:a5,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b3,y:b2,platform:Linux,
03000000780000000600000010010000,Microntek USB Joystick,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,
030000005e0400000e00000000010000,Microsoft SideWinder,a:b0,b:b1,back:b9,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b6,rightshoulder:b7,start:b8,x:b3,y:b4,platform:Linux,
-030000005e0400008e02000004010000,Microsoft X-Box 360 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,
-030000005e0400008e02000062230000,Microsoft X-Box 360 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,
-050000005e040000050b000003090000,Microsoft X-Box One Elite 2 pad,a:b0,b:b1,back:b17,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,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:Linux,
-030000005e040000e302000003020000,Microsoft X-Box One Elite 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,
-030000005e040000d102000001010000,Microsoft X-Box One 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,
-030000005e040000dd02000003020000,Microsoft X-Box One pad (Firmware 2015),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,
-030000005e040000d102000003020000,Microsoft X-Box One pad v2,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,
-030000005e0400008502000000010000,Microsoft X-Box pad (Japan),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,
-030000005e0400008902000021010000,Microsoft X-Box pad v2 (US),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,
-030000005e040000000b000008040000,Microsoft Xbox One Elite 2 pad - Wired,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,
-030000005e040000ea02000008040000,Microsoft Xbox One S pad - Wired,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,
-03000000c62400001a53000000010000,Mini PE,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,
+030000005e0400000700000000010000,Microsoft SideWinder Game Pad USB,a:b0,b:b1,back:b8,leftshoulder:b6,lefttrigger:b7,leftx:a0,lefty:a1,rightshoulder:b5,righttrigger:b2,start:b9,x:b3,y:b4,platform:Linux,
+030000005e0400008e02000004010000,Microsoft Xbox 360 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,
+030000005e0400008e02000062230000,Microsoft Xbox 360 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,
+050000005e040000050b000003090000,Microsoft Xbox One Elite 2 pad,a:b0,b:b1,back:b17,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,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:Linux,
+030000005e040000e302000003020000,Microsoft Xbox One Elite 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,
+030000005e040000d102000001010000,Microsoft Xbox One 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,
+030000005e040000dd02000003020000,Microsoft Xbox One pad 2015,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,
+030000005e040000d102000003020000,Microsoft Xbox One pad v2,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,
+030000005e0400008502000000010000,Microsoft Xbox pad,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,
+030000005e0400008902000021010000,Microsoft Xbox pad v2,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,
+030000005e040000000b000008040000,Microsoft Xbox One Elite 2 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,
+030000005e040000ea02000008040000,Microsoft Xbox One S 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,
+03000000c62400001a53000000010000,PowerA Mini Pro Ex,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,
03000000030000000300000002000000,Miroof,a:b1,b:b0,back:b6,leftshoulder:b4,leftx:a0,lefty:a1,rightshoulder:b5,start:b7,x:b3,y:b2,platform:Linux,
05000000d6200000e589000001000000,Moga 2 HID,a:b0,b:b1,back:b9,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:b6,x:b2,y:b3,platform:Linux,
05000000d6200000ad0d000001000000,Moga Pro,a:b0,b:b1,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:b6,x:b2,y:b3,platform:Linux,
05000000d62000007162000001000000,Moga Pro 2 HID,a:b0,b:b1,back:b9,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:b6,x:b2,y:b3,platform:Linux,
-03000000c62400002b89000011010000,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:Linux,
-05000000c62400002a89000000010000,MOGA XP5-A Plus,a:b0,b:b1,back:b10,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b22,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,
-05000000c62400001a89000000010000,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,
-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,
+03000000c62400002b89000011010000,MOGA XP5A 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,
+05000000c62400002a89000000010000,MOGA XP5A Plus,a:b0,b:b1,back:b10,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b22,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,
+05000000c62400001a89000000010000,MOGA XP5X 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,
+03000000250900006688000000010000,MP8866 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,
+030000004f1f00000800000011010000,Neogeo 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,start:b9,x:b0,y:b3,platform:Linux,
+03000000790000004518000010010000,Nexilux GameCube Controller Adapter,a:b1,b:b0,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:b2,y:b3,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,
@@ -741,36 +1100,42 @@ xinput,XInput Controller,a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,
03000000550900001472000011010000,NVIDIA Controller v01.04,a:b0,b:b1,back:b14,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b16,leftshoulder:b4,leftstick:b7,lefttrigger:a3,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b8,righttrigger:a4,rightx:a2,righty:a5,start:b6,x:b2,y:b3,platform:Linux,
05000000550900001472000001000000,NVIDIA Controller v01.04,a:b0,b:b1,back:b14,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b16,leftshoulder:b4,leftstick:b7,lefttrigger:a3,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b8,righttrigger:a4,rightx:a2,righty:a5,start:b6,x:b2,y:b3,platform:Linux,
03000000451300000830000010010000,NYKO CORE,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a5,start:b9,x:b0,y:b3,platform:Linux,
-19000000010000000100000001010000,odroidgo2_joypad,a:b1,b:b0,dpdown:b7,dpleft:b8,dpright:b9,dpup:b6,guide:b10,leftshoulder:b4,leftstick:b12,lefttrigger:b11,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b13,righttrigger:b14,start:b15,x:b2,y:b3,platform:Linux,
-19000000010000000200000011000000,odroidgo2_joypad_v11,a:b1,b:b0,dpdown:b9,dpleft:b10,dpright:b11,dpup:b8,guide:b12,leftshoulder:b4,leftstick:b14,lefttrigger:b13,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b15,righttrigger:b16,start:b17,x:b2,y:b3,platform:Linux,
-030000005e0400000202000000010000,Old Xbox pad,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,
+19000000010000000100000001010000,odroidgo2 joypad,a:b1,b:b0,dpdown:b7,dpleft:b8,dpright:b9,dpup:b6,guide:b10,leftshoulder:b4,leftstick:b12,lefttrigger:b11,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b13,righttrigger:b14,start:b15,x:b2,y:b3,platform:Linux,
+19000000010000000200000011000000,odroidgo2 joypad v11,a:b1,b:b0,dpdown:b9,dpleft:b10,dpright:b11,dpup:b8,guide:b12,leftshoulder:b4,leftstick:b14,lefttrigger:b13,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b15,righttrigger:b16,start:b17,x:b2,y:b3,platform:Linux,
+030000005e0400000202000000010000,Xbox pad,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,
03000000c0160000dc27000001010000,OnyxSoft Dual JoyDivision,a:b0,b:b1,dpdown:+a1,dpleft:-a0,dpright:+a0,dpup:-a1,leftshoulder:b4,rightshoulder:b5,start:b6,x:b2,y:b3,platform:Linux,
05000000362800000100000002010000,OUYA Game Controller,a:b0,b:b3,dpdown:b9,dpleft:b10,dpright:b11,dpup:b8,guide:b14,leftshoulder:b4,leftstick:b6,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b7,righttrigger:a5,rightx:a3,righty:a4,x:b1,y:b2,platform:Linux,
05000000362800000100000003010000,OUYA Game Controller,a:b0,b:b3,dpdown:b9,dpleft:b10,dpright:b11,dpup:b8,guide:b14,leftshoulder:b4,leftstick:b6,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b7,righttrigger:a5,rightx:a3,righty:a4,x:b1,y:b2,platform:Linux,
03000000830500005020000010010000,Padix Co. Ltd. Rockfire PSX/USB Bridge,a:b0,b:b1,back:b10,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b8,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b9,righttrigger:b7,rightx:a2,righty:a3,start:b11,x:b2,y:b3,platform:Linux,
03000000790000001c18000011010000,PC Game 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,
03000000ff1100003133000010010000,PC Game 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,
-030000006f0e0000b802000001010000,PDP AFTERGLOW Wired Xbox One 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,
-030000006f0e0000b802000013020000,PDP AFTERGLOW Wired Xbox One 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,
+030000006f0e0000b802000001010000,PDP Afterglow Wired Xbox One 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,
+030000006f0e0000b802000013020000,PDP Afterglow Wired Xbox One 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,
030000006f0e00006401000001010000,PDP Battlefield One,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,
-030000006f0e00008001000011010000,PDP CO. LTD. Faceoff Wired Pro Controller for Nintendo Switch,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,
+030000006f0e00008001000011010000,PDP Faceoff Wired Pro Controller for Nintendo Switch,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,
030000006f0e00003101000000010000,PDP EA Sports 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,
030000006f0e0000c802000012010000,PDP Kingdom Hearts Controller,a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b8,leftshoulder:b4,leftstick:b9,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b10,righttrigger:a5,rightx:a3,righty:a4,start:b7,x:b2,y:b3,platform:Linux,
030000006f0e00008701000011010000,PDP Rock Candy Wired Controller for Nintendo Switch,a:b2,b:b1,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b13,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,
+03000000c6240000fefa000000010000,Rock Candy Xbox 360 Controller, a:b0,b:b1,x:b2,y:b3,back:b6,guide:b8,start:b7,leftstick:b9,rightstick:b10,leftshoulder:b4,rightshoulder:b5,dpup:h0.1,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,leftx:a0,lefty:a1,rightx:a3,righty:a4,lefttrigger:a2,righttrigger:a5,platform:Linux,
030000006f0e00000901000011010000,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:Linux,
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: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,
+0500000049190000030400001b010000,Ipega PG9099,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,Ipega PG9118,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,
+03000000d9040000160f000000010000,Playstation Controller Adapter,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: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,
03000000d62000000228000001010000,PowerA Wired Controller for Xbox One,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,
-03000000c62400001a58000001010000,PowerA Xbox One Cabled,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,
+03000000d62000000220000001010000,PowerA Wired Controller for Xbox One and Xbox Series S and X,a:b0,b:b1,back:b7,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b9,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b10,righttrigger:a5,rightx:a3,righty:a4,start:b6,x:b2,y:b3,platform:Linux,
+03000000c62400001a58000001010000,PowerA Xbox One,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,
03000000c62400001a54000001010000,PowerA Xbox One Mini Wired 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,
+03000000d620000013a7000011010000,Nintendo Switch PowerA Wired Controller,a:b1,b:b2,x:b0,y:b3,back:b8,guide:b12,start:b9,leftshoulder:b4,rightshoulder:b5,leftstick:b10,rightstick:b11,dpup:h0.1,dpleft:h0.8,dpdown:h0.4,dpright:h0.2,leftx:a0,lefty:a1,rightx:a2,righty:a3,lefttrigger:b6,righttrigger:b7,platform:Linux,
030000006d040000d2ca000011010000,Precision Controller,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b0,y:b3,platform:Linux,
+03000000ba2200000701000001010000,Technology Innovation PS2 Adapter,b:b1,a:b0,x:b3,y:b2,start:b9,back:b8,leftstick:b10,rightstick:b11,leftshoulder:b4,rightshoulder:b5,dpup:h0.1,dpleft:h0.8,dpdown:h0.4,dpright:h0.2,leftx:a0,lefty:a1,rightx:a5,righty:a2,lefttrigger:b6,righttrigger:b7,platform:Linux,
+03000000430b00000300000000010000,EMS Production PS2 Adapter,b:b1,a:b2,x:b3,y:b0,start:b9,back:b8,leftstick:b10,rightstick:b11,leftshoulder:b6,rightshoulder:b7,dpup:b12,dpleft:b15,dpdown:b14,dpright:b13,leftx:a0,lefty:a1,rightx:a5,righty:a2,lefttrigger:b4,righttrigger:b5,platform:Linux,
03000000ff1100004133000010010000,PS2 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,
03000000341a00003608000011010000,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,
030000004c0500006802000010010000,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,
@@ -802,18 +1167,20 @@ xinput,XInput Controller,a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,
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,
+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,
030000008916000001fd000024010000,Razer Onza Classic Edition,a:b0,b:b1,back:b6,dpdown:b14,dpleft:b11,dpright:b12,dpup:b13,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,
030000008916000000fd000024010000,Razer Onza Tournament Edition,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,
-03000000321500000204000011010000,Razer Panthera (PS3),a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b0,y:b3,platform:Linux,
-03000000321500000104000011010000,Razer Panthera (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:Linux,
+03000000321500000204000011010000,Razer Panthera PS3,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b0,y:b3,platform:Linux,
+03000000321500000104000011010000,Razer Panthera 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:Linux,
03000000321500000810000011010000,Razer Panthera Evo Arcade Stick for PS4,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b13,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,
-03000000321500000010000011010000,Razer RAIJU,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,
+03000000321500000010000011010000,Razer Rainu,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,
03000000321500000507000000010000,Razer Raiju Mobile,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:Linux,
+05000000321500000a10000001000000,Razer Raiju Tournament Edition,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b13,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a5,start:b9,x:b0,y:b3,platform:Linux,
+03000000321500000710000000010000,Razer Raiju Tournament Edition Wired,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b13,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a5,start:b9,x:b0,y:b3,platform:Linux,
03000000321500000011000011010000,Razer Raion Fightpad 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:a3,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:a4,rightx:a2,righty:a5,start:b9,x:b0,y:b3,platform:Linux,
030000008916000000fe000024010000,Razer Sabertooth,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,
03000000c6240000045d000024010000,Razer Sabertooth,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,
@@ -821,7 +1188,7 @@ xinput,XInput Controller,a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,
03000000321500000009000011010000,Razer Serval,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,
050000003215000000090000163a0000,Razer Serval,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,
0300000032150000030a000001010000,Razer Wildcat,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,
-03000000790000001100000010010000,Retrolink SNES Controller,a:b2,b:b1,back:b8,dpdown:+a1,dpleft:-a0,dpright:+a0,dpup:-a1,leftshoulder:b4,rightshoulder:b5,start:b9,x:b3,y:b0,platform:Linux,
+03000000790000001100000010010000,Retro Controller,a:b1,b:b2,back:b8,dpdown:+a1,dpleft:-a0,dpright:+a0,dpup:-a1,leftshoulder:b6,lefttrigger:b7,rightshoulder:b4,righttrigger:b5,start:b9,x:b0,y:b3,platform:Linux,
0300000081170000990a000001010000,Retronic Adapter,a:b0,leftx:a0,lefty:a1,platform:Linux,
0300000000f000000300000000010000,RetroPad,a:b1,b:b5,back:b2,leftshoulder:b6,leftx:a0,lefty:a1,rightshoulder:b7,start:b3,x:b0,y:b4,platform:Linux,
030000006b140000010d000011010000,Revolution Pro Controller,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:a3,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:a4,rightx:a2,righty:a5,start:b9,x:b0,y:b3,platform:Linux,
@@ -837,20 +1204,22 @@ xinput,XInput Controller,a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,
03000000300f00001201000010010000,Saitek P380,a:b2,b:b3,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b10,lefttrigger:b5,leftx:a0,lefty:a1,rightshoulder:b6,rightstick:b11,righttrigger:b7,rightx:a3,righty:a2,start:b9,x:b0,y:b1,platform:Linux,
03000000a30600000901000000010000,Saitek P880,a:b2,b:b3,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,x:b0,y:b1,platform:Linux,
03000000a30600000b04000000010000,Saitek P990 Dual Analog Pad,a:b1,b:b2,back:b9,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:b8,x:b0,y:b3,platform:Linux,
-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,
+03000000a306000018f5000010010000,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,
-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,
-030000005f140000c501000010010000,SHANWAN Trust 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,
+03000000a30c00002500000011010000,Sega Genesis Mini 3B controller,a:b2,b:b1,dpdown:+a4,dpleft:-a3,dpright:+a3,dpup:-a4,righttrigger:b5,start:b9,platform:Linux,
+030000001f08000001e4000010010000,SFC Controller,a:b2,b:b1,back:b8,leftshoulder:b4,leftx:a0,lefty:a1,rightshoulder:b5,start:b9,x:b3,y:b0,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,
+030000005f140000c501000010010000,Shanwan Trust 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,
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,
+03000000341a00000908000010010000,SL6566,a:b0,b:b1,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b2,y:b3,platform:Linux,
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,
-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,
+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,
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,
+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,
@@ -870,13 +1239,13 @@ xinput,XInput Controller,a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,
030000003b07000004a1000000010000,Suncom SFX Plus for USB,a:b0,b:b2,back:b7,leftshoulder:b6,lefttrigger:b4,leftx:a0,lefty:a1,rightshoulder:b9,righttrigger:b5,start:b8,x:b1,y:b3,platform:Linux,
03000000666600000488000000010000,Super Joy Box 5 Pro,a:b2,b:b1,back:b9,dpdown:b14,dpleft:b15,dpright:b13,dpup:b12,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,
0300000000f00000f100000000010000,Super RetroPort,a:b1,b:b5,back:b2,leftshoulder:b6,leftx:a0,lefty:a1,rightshoulder:b7,start:b3,x:b0,y:b4,platform:Linux,
-03000000457500002211000010010000,SZMY-POWER CO. LTD. 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,
-030000008f0e00000d31000010010000,SZMY-POWER CO. LTD. GAMEPAD 3 TURBO,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,
-030000008f0e00001431000010010000,SZMY-POWER CO. LTD. PS3 gamepad,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b0,y:b3,platform:Linux,
+03000000457500002211000010010000,SZMY Power Gamepad,a:b2,b:b1,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b3,y:b0,platform:Linux,
+030000008f0e00000d31000010010000,SZMY Power 3 Turbo,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,
+030000008f0e00001431000010010000,SZMY Power PS3 gamepad,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b0,y:b3,platform:Linux,
030000004f04000020b3000010010000,Thrustmaster 2 in 1 DT,a:b0,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b10,lefttrigger:b5,leftx:a0,lefty:a1,rightshoulder:b6,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b1,y:b3,platform:Linux,
030000004f04000015b3000010010000,Thrustmaster Dual Analog 4,a:b0,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b10,lefttrigger:b5,leftx:a0,lefty:a1,rightshoulder:b6,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b1,y:b3,platform:Linux,
-030000004f04000023b3000000010000,Thrustmaster Dual Trigger 3-in-1,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a5,start:b9,x:b0,y:b3,platform:Linux,
-030000004f0400000ed0000011010000,ThrustMaster eSwap PRO Controller,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:a3,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:a4,rightx:a2,righty:a5,start:b9,x:b0,y:b3,platform:Linux,
+030000004f04000023b3000000010000,Thrustmaster Dual Trigger 3 in 1,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a5,start:b9,x:b0,y:b3,platform:Linux,
+030000004f0400000ed0000011010000,Thrustmaster eSwap PRO Controller,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:a3,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:a4,rightx:a2,righty:a5,start:b9,x:b0,y:b3,platform:Linux,
03000000b50700000399000000010000,Thrustmaster Firestorm Digital 2,a:b2,b:b4,back:b11,leftshoulder:b6,leftstick:b10,lefttrigger:b7,leftx:a0,lefty:a1,rightshoulder:b8,rightstick:b0,righttrigger:b9,start:b1,x:b3,y:b5,platform:Linux,
030000004f04000003b3000010010000,Thrustmaster Firestorm Dual Analog 2,a:b0,b:b2,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b10,lefttrigger:b8,leftx:a0,lefty:a1,rightshoulder:b6,rightstick:b11,righttrigger:b9,rightx:a2,righty:a3,x:b1,y:b3,platform:Linux,
030000004f04000000b3000010010000,Thrustmaster Firestorm Dual Power,a:b0,b:b2,back:b9,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b8,leftshoulder:b4,leftstick:b11,lefttrigger:b5,leftx:a0,lefty:a1,rightshoulder:b6,rightstick:b12,righttrigger:b7,rightx:a2,righty:a3,start:b10,x:b1,y:b3,platform:Linux,
@@ -887,49 +1256,62 @@ xinput,XInput Controller,a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,
030000004f04000007d0000000010000,Thrustmaster T Mini Wireless,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,
030000004f04000012b3000010010000,Thrustmaster vibrating gamepad,a:b0,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b10,lefttrigger:b5,leftx:a0,lefty:a1,rightshoulder:b6,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b1,y:b3,platform:Linux,
03000000bd12000015d0000010010000,Tomee SNES USB Controller,a:b2,b:b1,back:b8,dpdown:+a1,dpleft:-a0,dpright:+a0,dpup:-a1,leftshoulder:b4,rightshoulder:b5,start:b9,x:b3,y:b0,platform:Linux,
-03000000d814000007cd000011010000,Toodles 2008 Chimp PC/PS3,a:b0,b:b1,back:b8,leftshoulder:b4,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,righttrigger:b7,start:b9,x:b3,y:b2,platform:Linux,
+03000000d814000007cd000011010000,Toodles 2008 Chimp PC PS3,a:b0,b:b1,back:b8,leftshoulder:b4,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,righttrigger:b7,start:b9,x:b3,y:b2,platform:Linux,
030000005e0400008e02000070050000,Torid,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,
03000000c01100000591000011010000,Torid,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,
03000000100800000100000010010000,Twin USB PS2 Adapter,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:Linux,
03000000100800000300000010010000,USB Gamepad,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:Linux,
03000000790000000600000007010000,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:a3,righty:a4,start:b9,x:b3,y:b0,platform:Linux,
03000000790000001100000000010000,USB Gamepad1,a:b2,b:b1,back:b8,dpdown:a0,dpleft:a1,dpright:a2,dpup:a4,start:b9,platform:Linux,
+03000000790000001100000011010000,USB Saturn Controller,a:b1,b:b2,back:b8,dpdown:+a1,dpleft:-a0,dpright:+a0,dpup:-a1,leftshoulder:b6,lefttrigger:b7,rightshoulder:b5,righttrigger:b4,start:b9,x:b0,y:b3,platform:Linux,
+03000000790000002201000011010000,USB Saturn Controller,a:b0,b:b1,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,lefttrigger:b5,rightshoulder:b6,righttrigger:b7,start:b9,x:b2,y:b3,platform:Linux,
+03000000b40400000a01000000010000,USB Saturn Pad,a:b0,b:b1,leftshoulder:b6,lefttrigger:b7,leftx:a0,lefty:a1,rightshoulder:b5,righttrigger:b2,start:b8,x:b3,y:b4,platform:Linux,
030000006f0e00000302000011010000,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,lefttrigger:b6,rightshoulder:b5,righttrigger:b7,start:b9,x:b0,y:b3,platform:Linux,
030000006f0e00000702000011010000,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:Linux,
-05000000ac0500003232000001000000,VR-BOX,a:b0,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:b2,y:b3,platform:Linux,
+05000000ac0500003232000001000000,VR Box Controller,a:b0,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:b2,y:b3,platform:Linux,
03000000791d00000103000010010000,Wii Classic Controller,a:b2,b:b1,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b10,leftshoulder:b6,lefttrigger:b4,leftx:a0,lefty:a1,rightshoulder:b7,righttrigger:b5,rightx:a2,righty:a3,start:b9,x:b3,y:b0,platform:Linux,
050000000d0f0000f600000001000000,Wireless HORIPAD 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,
-030000005e0400008e02000010010000,X360 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,
-030000005e0400008e02000014010000,X360 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,
-030000005e0400001907000000010000,X360 Wireless Controller,a:b0,b:b1,back:b6,dpdown:b14,dpleft:b11,dpright:b12,dpup:b13,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,
-030000005e0400009102000007010000,X360 Wireless Controller,a:b0,b:b1,back:b6,dpdown:b14,dpleft:b11,dpright:b12,dpup:b13,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,
-030000005e040000a102000000010000,X360 Wireless Controller,a:b0,b:b1,back:b6,dpdown:b14,dpleft:b11,dpright:b12,dpup:b13,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,
-030000005e040000a102000007010000,X360 Wireless 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,
+030000005e0400008e02000010010000,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,
+030000005e0400008e02000014010000,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,
+030000005e0400001907000000010000,Xbox 360 Wireless Controller,a:b0,b:b1,back:b6,dpdown:b14,dpleft:b11,dpright:b12,dpup:b13,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,
+030000005e0400009102000007010000,Xbox 360 Wireless Controller,a:b0,b:b1,back:b6,dpdown:b14,dpleft:b11,dpright:b12,dpup:b13,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,
+030000005e040000a102000000010000,Xbox 360 Wireless Controller,a:b0,b:b1,back:b6,dpdown:b14,dpleft:b11,dpright:b12,dpup:b13,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,
+030000005e040000a102000007010000,Xbox 360 Wireless 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,
0000000058626f782033363020576900,Xbox 360 Wireless Controller,a:b0,b:b1,back:b14,dpdown:b11,dpleft:b12,dpright:b13,dpup:b10,guide:b7,leftshoulder:b4,leftstick:b8,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b9,righttrigger:a5,rightx:a3,righty:a4,start:b6,x:b2,y:b3,platform:Linux,
-030000005e040000a102000014010000,Xbox 360 Wireless Receiver (XBOX),a:b0,b:b1,back:b6,dpdown:b14,dpleft:b11,dpright:b12,dpup:b13,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,
-0000000058626f782047616d65706100,Xbox Gamepad (userspace driver),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,
+030000005e040000a102000014010000,Xbox 360 Wireless Receiver,a:b0,b:b1,back:b6,dpdown:b14,dpleft:b11,dpright:b12,dpup:b13,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,
+0000000058626f782047616d65706100,Xbox 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:a5,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b10,righttrigger:a4,rightx:a2,righty:a3,start:b7,x:b2,y:b3,platform:Linux,
+030000005e0400000a0b000005040000,Xbox One Controller,a:b1,b:b0,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,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,
030000005e040000d102000002010000,Xbox One 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,
050000005e040000fd02000030110000,Xbox One 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,
+050000005e040000e302000002090000,Xbox One Elite,a:b0,b:b1,back:b136,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,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:Linux,
050000005e040000050b000002090000,Xbox One Elite Series 2,a:b0,b:b1,back:b136,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,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:Linux,
030000005e040000ea02000000000000,Xbox One Wireless 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,
050000005e040000e002000003090000,Xbox One Wireless 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:Linux,
050000005e040000fd02000003090000,Xbox One Wireless Controller,a:b0,b:b1,back:b15,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b16,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,
030000005e040000ea02000001030000,Xbox One Wireless Controller (Model 1708),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,
+060000005e040000120b000007050000,Xbox One Wireless Controller (Model 1914),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,
030000005e040000120b000001050000,Xbox Series 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,
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,
+030000005e040000120b000005050000,Xbox Series 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,
+030000005e0400008e02000000010000,Xbox 360 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 SL6556 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,
05000000172700004431000029010000,XiaoMi Game Controller,a:b0,b:b1,back:b10,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b20,leftshoulder:b6,leftstick:b13,lefttrigger:a7,leftx:a0,lefty:a1,rightshoulder:b7,rightstick:b14,righttrigger:a6,rightx:a2,righty:a5,start:b11,x:b3,y:b4,platform:Linux,
-03000000c0160000e105000001010000,Xin-Mo Xin-Mo Dual Arcade,a:b4,b:b3,back:b6,dpdown:b12,dpleft:b13,dpright:b14,dpup:b11,guide:b9,leftshoulder:b2,leftx:a0,lefty:a1,rightshoulder:b5,start:b7,x:b1,y:b0,platform:Linux,
+03000000c0160000e105000001010000,XinMo Dual Arcade,a:b4,b:b3,back:b6,dpdown:b12,dpleft:b13,dpright:b14,dpup:b11,guide:b9,leftshoulder:b2,leftx:a0,lefty:a1,rightshoulder:b5,start:b7,x:b1,y:b0,platform:Linux,
xinput,XInput 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,
-03000000120c0000100e000011010000,ZEROPLUS P4 Gamepad,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:a3,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:a4,rightx:a2,righty:a5,start:b9,x:b0,y:b3,platform:Linux,
-03000000120c0000101e000011010000,ZEROPLUS P4 Wired Gamepad,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:a3,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:a4,rightx:a2,righty:a5,start:b9,x:b0,y:b3,platform:Linux,
+03000000120c0000100e000011010000,Zeroplus P4 Gamepad,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:a3,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:a4,rightx:a2,righty:a5,start:b9,x:b0,y:b3,platform:Linux,
+03000000120c0000101e000011010000,Zeroplus P4 Wired Gamepad,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:a3,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:a4,rightx:a2,righty:a5,start:b9,x:b0,y:b3,platform:Linux,
# Android
+38653964633230666463343334313533,8BitDo Adapter,a:b0,b:b1,back:b15,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b9,leftstick:b7,lefttrigger:b17,leftx:a0,lefty:a1,rightshoulder:b10,rightstick:b8,righttrigger:b18,rightx:a2,righty:a3,start:b6,x:b2,y:b3,platform:Android,
+34343439373236623466343934376233,8BitDo FC30 Pro,a:b0,b:b1,back:b4,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b3,leftstick:b28,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b4,rightstick:b29,righttrigger:b7,start:b5,x:b30,y:b2,platform:Android,
+33656266353630643966653238646264,8BitDo M30,a:b0,b:b1,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b3,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b20,righttrigger:a5,start:b10,x:b19,y:b2,platform:Android,
+39366630663062373237616566353437,8BitDo M30,a:b0,b:b1,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b9,lefttrigger:b17,leftx:a0,lefty:a1,rightshoulder:b10,righttrigger:b18,start:b6,x:b2,y:b3,platform:Android,
+64653533313537373934323436343563,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:b9,righttrigger:b10,start:b6,x:b2,y:b3,platform:Android,
+66356438346136366337386437653934,8BitDo M30,a:b0,b:b1,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b3,lefttrigger:b9,leftx:a0,lefty:a1,rightshoulder:b20,righttrigger:b10,start:b18,x:b19,y:b2,platform:Android,
+66393064393162303732356665666366,8BitDo M30,a:b0,b:b1,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b9,lefttrigger:a4,leftx:a0,lefty:a1,rightshoulder:b10,righttrigger:a5,start:b6,x:b2,y:b3,platform:Android,
05000000c82d000006500000ffff3f00,8BitDo M30 Gamepad,a:b1,b:b0,back:b4,guide:b17,leftshoulder:b9,lefttrigger:a5,leftx:a0,lefty:a1,rightshoulder:b10,righttrigger:a4,start:b6,x:b3,y:b2,platform:Android,
05000000c82d000051060000ffff3f00,8BitDo M30 Gamepad,a:b1,b:b0,back:b4,guide:b17,leftshoulder:b9,lefttrigger:a4,leftx:a0,lefty:a1,rightshoulder:b10,righttrigger:a5,start:b6,x:b3,y:b2,platform:Android,
05000000c82d000015900000ffff3f00,8BitDo N30 Pro 2,a:b1,b:b0,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:b3,y:b2,platform:Android,
@@ -938,60 +1320,152 @@ xinput,XInput Controller,a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,
050000002038000009000000ffff3f00,8BitDo NES30 Pro,a:b1,b:b0,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:b3,y:b2,platform:Android,
05000000c82d000000600000ffff3f00,8BitDo SF30 Pro,a:b1,b:b0,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:b3,y:b2,platform:Android,
05000000c82d000000610000ffff3f00,8BitDo SF30 Pro,a:b1,b:b0,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:b3,y:b2,platform:Android,
+38426974646f20534633302050726f00,8BitDo SF30 Pro,a:b1,b:b0,back:b9,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b3,leftstick:b15,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b18,rightstick:b16,righttrigger:a5,rightx:a3,righty:a4,start:b10,x:b2,y:b17,platform:Android,
+61623334636338643233383735326439,8BitDo SFC30,a:b0,b:b1,back:b4,leftshoulder:b3,leftx:a0,lefty:a1,rightshoulder:b31,start:b5,x:b30,y:b2,platform:Android,
05000000c82d000012900000ffff3f00,8BitDo SN30 Gamepad,a:b1,b:b0,back:b4,leftshoulder:b9,leftx:a0,lefty:a1,rightshoulder:b10,start:b6,x:b3,y:b2,platform:Android,
05000000c82d000062280000ffff3f00,8BitDo SN30 Gamepad,a:b1,b:b0,back:b4,leftshoulder:b9,leftx:a0,lefty:a1,rightshoulder:b10,start:b6,x:b3,y:b2,platform:Android,
+35383531346263653330306238353131,8BitDo SN30 PP,a:b0,b:b1,back:b15,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,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,
05000000c82d000001600000ffff3f00,8BitDo SN30 Pro,a:b1,b:b0,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:b3,y:b2,platform:Android,
+36653638656632326235346264663661,8BitDo SN30 Pro Plus,a:b0,b:b1,back:b17,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,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,
+38303232393133383836366330346462,8BitDo SN30 Pro Plus,a:b0,b:b1,back:b9,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b3,leftstick:b17,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b20,rightstick:b18,righttrigger:a5,rightx:a3,righty:a4,start:b10,x:b19,y:b2,platform:Android,
+38346630346135363335366265656666,8BitDo SN30 Pro Plus,a:b1,b:b0,back:b15,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b9,leftstick:b7,lefttrigger:b17,leftx:a0,lefty:a1,rightshoulder:b10,rightstick:b8,righttrigger:b18,rightx:a2,righty:a3,start:b6,x:b3,y:b2,platform:Android,
+66306331643531333230306437353936,8BitDo SN30 Pro Plus,a:b1,b:b0,back:b15,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b9,leftstick:b7,lefttrigger:b17,leftx:a0,lefty:a1,rightshoulder:b10,rightstick:b8,righttrigger:b18,rightx:a2,righty:a3,start:b6,x:b3,y:b2,platform:Android,
05000000c82d000002600000ffff0f00,8BitDo SN30 Pro+,a:b1,b:b0,back:b4,dpdown:b12,dpleft:b13,dpright:b14,dpup:b11,guide:b17,leftshoulder:b9,leftstick:b7,lefttrigger:b15,leftx:a0,lefty:a1,rightshoulder:b10,rightstick:b8,righttrigger:b16,rightx:a2,righty:a3,start:b6,x:b3,y:b2,platform:Android,
050000002028000009000000ffff3f00,8BitDo SNES30 Gamepad,a:b1,b:b0,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:b3,y:b2,platform:Android,
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,
+33666663316164653937326237613331,8BitDo Zero,a:b0,b:b1,back:b15,leftshoulder:b9,leftx:a0,lefty:a1,rightshoulder:b10,start:b6,x:b2,y:b3,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,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,
+33663434393362303033616630346337,8BitDo Zero 2,a:b0,b:b1,back:b17,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b3,leftx:a0,lefty:a1,rightshoulder:b20,start:b18,x:b19,y:b2,platform:Android,
+34656330626361666438323266633963,8BitDo Zero 2,a:b0,b:b1,back:b9,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftx:a0,lefty:a1,rightshoulder:b20,start:b10,x:b19,y:b2,platform:Android,
+63396666386564393334393236386630,8BitDo Zero 2,a:b1,b:b0,back:b15,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b9,leftx:a0,lefty:a1,rightshoulder:b10,start:b6,x:b3,y:b2,platform:Android,
+63633435623263373466343461646430,8BitDo Zero 2,a:b1,b:b0,back:b15,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b9,leftx:a0,lefty:a1,rightshoulder:b10,start:b6,x:b2,y:b3,platform:Android,
+32333634613735616163326165323731,Amazon Luna Game Controller,a:b0,b:b1,back:b4,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b9,leftstick:b7,lefttrigger:a4,leftx:a0,lefty:a1,rightshoulder:b10,rightstick:b8,righttrigger:a5,rightx:a2,righty:a3,x:b2,y:b3,platform:Android,
+38383337343564366131323064613561,Brook Mars PS4 Controller,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,
+33323763323132376537376266393366,Dual Strike,a:b24,b:b23,back:b25,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b27,lefttrigger:b29,rightshoulder:b78,rightx:a0,righty:a1~,start:b26,x:b22,y:b21,platform:Android,
+30363230653635633863366338623265,Evo VR,a:b0,b:b1,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftx:a0,lefty:a1,x:b2,y:b3,platform:Android,
+05000000b404000011240000dfff3f00,Flydigi Vader 2,a:b0,b:b1,back:b4,dpdown:b12,dpleft:b13,dpright:b14,dpup:b11,leftshoulder:b9,leftstick:b7,lefttrigger:a4,leftx:a0,lefty:a1,paddle1:b17,paddle2:b18,rightshoulder:b10,rightstick:b8,righttrigger:a5,rightx:a2,righty:a3,start:b6,x:b2,y:b3,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,
+34323662653333636330306631326233,Google Nexus,a:b0,b:b1,back:b4,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,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,
+35383633353935396534393230616564,Google Stadia Controller,a:b0,b:b1,back:b15,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,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,
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,
-0500000083050000602000000ffe0000,iBuffalo SNES Controller,a:b1,b:b0,back:b9,dpdown:b12,dpleft:b13,dpright:b14,dpup:b11,leftshoulder:b15,rightshoulder:b16,start:b10,x:b3,y:b2,platform:Android,
+66633030656131663837396562323935,Hori Battle,a:b0,b:b1,back:b15,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,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,
+35623466343433653739346434636330,Hori Fighting Commander 3 Pro,a:b1,b:b19,back:b17,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b3,lefttrigger:b9,leftx:a0,lefty:a1,rightshoulder:b20,righttrigger:b10,rightx:a2,righty:a3,start:b18,x:b0,y:b2,platform:Android,
+65656436646661313232656661616130,Hori PC Engine Mini Controller,a:b1,b:b19,back:b17,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,start:b18,platform:Android,
+31303433326562636431653534636633,Hori Real Arcade Pro 3,a:b1,b:b19,back:b17,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b3,lefttrigger:b9,leftx:a0,lefty:a1,rightshoulder:b20,righttrigger:b10,rightx:a2,righty:a3,start:b18,x:b0,y:b2,platform:Android,
+0500000083050000602000000ffe0000,iBuffalo SNES Controller,a:b0,b:b1,back:b9,dpdown:b12,dpleft:b13,dpright:b14,dpup:b11,leftshoulder:b15,rightshoulder:b16,start:b10,x:b2,y:b3,platform:Android,
+64306137363261396266353433303531,InterAct GoPad,a:b24,b:b25,leftshoulder:b23,lefttrigger:b27,leftx:a0,lefty:a1,rightshoulder:b26,righttrigger:b28,x:b21,y:b22,platform:Android,
+65346535636333663931613264643164,Joy Con,a:b21,b:b22,back:b29,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b25,lefttrigger:b27,leftx:a0,lefty:a1,rightshoulder:b26,righttrigger:b28,rightx:a2,righty:a3,start:b30,x:b23,y:b24,platform:Android,
+33346566643039343630376565326335,Joy Con (L),a:b0,b:b1,back:b7,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b3,leftstick:b15,rightshoulder:b20,start:b17,x:b19,y:b2,platform:Android,
+35313531613435623366313835326238,Joy Con (L),a:b0,b:b1,back:b7,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b3,leftstick:b15,rightshoulder:b20,start:b17,x:b19,y:b2,platform:Android,
+39363561613936303237333537383931,Joy Con (R),a:b0,b:b1,back:b5,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b3,leftstick:b15,rightshoulder:b20,start:b18,x:b19,y:b2,platform:Android,
+38383665633039363066383334653465,Joy Con (R),a:b0,b:b1,back:b5,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b3,leftstick:b15,rightshoulder:b20,start:b18,x:b19,y:b2,platform:Android,
+39656136363638323036303865326464,JYS Aapter,a:b1,b:b19,back:b17,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,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,
+63316564383539663166353034616434,JYS Adapter,a:b1,b:b3,back:b15,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b9,leftstick:b7,lefttrigger:b17,leftx:a0,lefty:a1,rightshoulder:b10,rightstick:b8,righttrigger:b18,rightx:a2,righty:a3,start:b6,x:b0,y:b2,platform:Android,
+64623163333561643339623235373232,Logitech F310,a:b0,b:b1,back:b4,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,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,
+35623364393661626231343866613337,Logitech F710,a:b0,b:b1,back:b4,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b9,leftstick:b7,lefttrigger:b17,leftx:a0,lefty:a1,rightshoulder:b10,rightstick:b8,righttrigger:b18,rightx:a2,righty:a3,start:b6,x:b2,y:b3,platform:Android,
+64396331333230326333313330336533,Logitech F710,a:b0,b:b1,back:b4,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,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,
+30363066623539323534363639323363,Magic NS,a:b1,b:b19,back:b17,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,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,
+31353762393935386662336365626334,Magic NS,a:b1,b:b19,back:b17,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,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,
+39623565346366623931666633323530,Magic NS,a:b1,b:b3,back:b15,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b9,leftstick:b7,lefttrigger:b17,leftx:a0,lefty:a1,rightshoulder:b10,rightstick:b8,righttrigger:b18,rightx:a2,righty:a3,start:b6,x:b0,y:b2,platform:Android,
+32303165626138343962363666346165,Mars,a:b1,b:b19,back:b17,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,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,
+31323564663862633234646330373138,Mega Drive,a:b23,b:b22,leftx:a0,lefty:a1,rightshoulder:b25,righttrigger:b26,start:b30,x:b24,y:b21,platform:Android,
+37333564393261653735306132613061,Mega Drive,a:b21,b:b22,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b26,lefttrigger:b28,rightshoulder:b27,righttrigger:b23,start:b30,x:b24,y:b25,platform:Android,
+64363363336633363736393038313464,Mega Drive,a:b1,b:b0,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,start:b9,x:b2,y:b3,platform:Android,
64633436313965656664373634323364,Microsoft X-Box 360 pad,a:b0,b:b1,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b9,leftstick:b7,lefttrigger:a4,leftx:a0,lefty:a1,rightshoulder:b10,rightstick:b8,righttrigger:a5,rightx:a2,righty:a3,x:b2,y:b3,platform:Android,
+32386235353630393033393135613831,Microsoft Xbox Series Controller,a:b0,b:b1,back:b4,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,
+33343361376163623438613466616531,Mocute M053,a:b0,b:b1,back:b15,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b9,leftstick:b7,lefttrigger:b17,leftx:a0,lefty:a1,rightshoulder:b10,rightstick:b8,righttrigger:b18,rightx:a2,righty:a3,start:b6,x:b2,y:b3,platform:Android,
+39306635663061636563316166303966,Mocute M053,a:b0,b:b1,back:b15,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b9,leftstick:b7,lefttrigger:b17,leftx:a0,lefty:a1,rightshoulder:b10,rightstick:b8,righttrigger:b18,rightx:a2,righty:a3,start:b6,x:b2,y:b3,platform:Android,
7573622067616d657061642020202020,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:Android,
050000007e05000009200000ffff0f00,Nintendo Switch Pro Controller,a:b0,b:b1,back:b15,dpdown:b12,dpleft:b13,dpright:b14,dpup:b11,guide:b5,leftshoulder:b3,leftstick:b4,lefttrigger:b9,leftx:a0,lefty:a1,rightshoulder:b18,rightstick:b6,righttrigger:b10,rightx:a2,righty:a3,start:b16,x:b17,y:b2,platform:Android,
+34323437396534643531326161633738,Nintendo Switch Pro Controller,a:b0,b:b1,back:b15,leftshoulder:b9,leftstick:b7,lefttrigger:b17,leftx:a0,lefty:a1,misc1:b5,rightshoulder:b10,rightstick:b8,righttrigger:b18,rightx:a2,righty:a3,start:b6,x:b2,y:b3,platform:Android,
37336435666338653565313731303834,NVIDIA Controller,a:b0,b:b1,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,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,
4e564944494120436f72706f72617469,NVIDIA Controller,a:b0,b:b1,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,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,
61363931656135336130663561616264,NVIDIA Controller,a:b0,b:b1,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,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,
050000005509000003720000cf7f3f00,NVIDIA Controller v01.01,a:b0,b:b1,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,
050000005509000010720000ffff3f00,NVIDIA Controller v01.03,a:b0,b:b1,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,
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,
+61653962353232366130326530363061,Pokken,a:b1,b:b19,back:b17,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b3,lefttrigger:b9,rightshoulder:b20,righttrigger:b10,start:b18,x:b0,y:b2,platform:Android,
+32666633663735353234363064386132,PS2,a:b23,b:b22,back:b29,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b27,lefttrigger:b25,leftx:a0,lefty:a1,rightshoulder:b28,righttrigger:b26,rightx:a3,righty:a2,start:b30,x:b24,y:b21,platform:Android,
+61363034663839376638653463633865,PS3,a:b0,b:b1,back:b15,dpdown:a14,dpleft:b13,dpright:b14,dpup:b11,leftshoulder:b9,leftstick:b7,lefttrigger:b17,leftx:a0,lefty:a1,rightshoulder:b10,rightstick:b8,righttrigger:b18,rightx:a2,righty:a3,start:b6,x:b2,y:b3,platform:Android,
+66366539656564653432353139356536,PS3,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,
+66383132326164626636313737373037,PS3,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,
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,
+30303839663330346632363232623138,PS4,a:b1,b:b17,back:b15,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,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,
+31326235383662333266633463653332,PS4,a:b1,b:b16,back:b15,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b3,leftstick:b4,lefttrigger:a3,leftx:a0,lefty:a1,rightshoulder:b18,rightstick:b6,righttrigger:a4,rightx:a2,righty:a5,start:b17,x:b0,y:b2,platform:Android,
+31663838336334393132303338353963,PS4,a:b0,b:b1,back:b4,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b9,lefttrigger:a4,leftx:a0,lefty:a1,rightshoulder:b10,righttrigger:a5,rightx:a2,righty:a3,start:b6,x:b2,y:b3,platform:Android,
+34613139376634626133336530386430,PS4,a:b0,b:b1,back:b15,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,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,
+37626233336235343937333961353732,PS4,a:b0,b:b1,back:b15,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,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,
+38393161636261653636653532386639,PS4,a:b0,b:b1,back:b15,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,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,
+63313733393535663339656564343962,PS4,a:b0,b:b1,back:b15,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,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,
+63393662363836383439353064663939,PS4,a:b0,b:b1,back:b4,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,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,
+65366465656364636137653363376531,PS4,a:b1,b:b19,back:b17,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,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,
+66613532303965383534396638613230,PS4,a:b1,b:b19,back:b17,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b3,leftstick:b15,lefttrigger:b9,leftx:a0,lefty:a1,rightshoulder:b20,rightstick:b6,righttrigger:b10,rightx:a2,righty:a5,start:b18,x:b0,y:b2,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: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,
+31373231336561636235613666323035,PS4 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,
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,
+62653335326261303663356263626339,PSX,a:b19,b:b1,back:b17,leftshoulder:b9,lefttrigger:b3,leftx:a0,lefty:a1,rightshoulder:b10,righttrigger:b20,start:b18,x:b2,y:b0,platform:Android,
+64336263393933626535303339616332,Qanba 4RAF,a:b0,b:b1,back:b17,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b20,lefttrigger:b10,leftx:a0,lefty:a1,rightshoulder:b3,righttrigger:b9,rightx:a2,righty:a3,start:b18,x:b19,y:b2,platform:Android,
+36626666353861663864336130363137,Razer Junglecat,a:b0,b:b1,back:b4,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,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,
62653861643333663663383332396665,Razer Kishi,a:b0,b:b1,back:b4,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b5,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,
050000003215000005070000ffff3f00,Razer Raiju Mobile,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,
050000003215000007070000ffff3f00,Razer Raiju Mobile,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,
050000003215000000090000bf7f3f00,Razer Serval,a:b0,b:b1,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,x:b2,y:b3,platform:Android,
+61343739353764363165343237303336,Retro Controller,a:b0,b:b1,back:b9,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b17,lefttrigger:b18,leftx:a0,lefty:a1,start:b10,x:b2,y:b3,platform:Android,
+38653130373365613538333235303036,Retroid Pocket 2,a:b0,b:b1,back:b15,dpdown:b12,dpleft:b13,dpright:b14,dpup:b11,leftshoulder:b9,lefttrigger:b17,leftx:a0,lefty:a1,rightshoulder:b10,righttrigger:b18,rightx:a2,righty:a3,start:b6,x:b2,y:b3,platform:Android,
+64363363336633363736393038313463,Retrolink,a:b1,b:b0,back:b15,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,start:b6,platform:Android,
+33373336396634316434323337666361,RumblePad 2,a:b22,b:b23,back:b29,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b25,lefttrigger:b27,leftx:a0,lefty:a1,rightshoulder:b26,righttrigger:b28,rightx:a2,righty:a3,start:b30,x:b21,y:b24,platform:Android,
+66386565396238363534313863353065,Sanwa Mobile,a:b21,b:b22,leftshoulder:b23,leftx:a0,lefty:a1,rightshoulder:b24,platform:Android,
+32383165316333383766336338373261,Saturn,a:b0,b:b1,back:b4,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b9,lefttrigger:b10,leftx:a0,lefty:a1,rightshoulder:a4,righttrigger:a5,x:b2,y:b3,platform:Android,
+37316565396364386635383230353365,Saturn,a:b21,b:b22,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b26,lefttrigger:b28,rightshoulder:b27,righttrigger:b23,start:b30,x:b24,y:b25,platform:Android,
+38613865396530353338373763623431,Saturn,a:b0,b:b1,leftshoulder:b9,lefttrigger:b10,leftx:a0,lefty:a1,rightshoulder:b20,righttrigger:b19,start:b17,x:b2,y:b3,platform:Android,
+61316232336262373631343137633631,Saturn,a:b0,b:b1,back:b4,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b9,lefttrigger:b10,leftx:a0,lefty:a1,rightshoulder:a4,righttrigger:a5,x:b2,y:b3,platform:Android,
+30353835333338613130373363646337,SG H510,a:b0,b:b1,back:b9,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b3,leftstick:b17,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b20,rightstick:b18,righttrigger:a5,rightx:a3,righty:a4,start:b10,x:b19,y:b2,platform:Android,
+66386262366536653765333235343634,SG H510,a:b0,b:b1,back:b4,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b9,leftstick:b7,lefttrigger:a4,leftx:a0,lefty:a1,rightshoulder:b10,rightstick:b8,righttrigger:a5,rightx:a2,righty:a3,x:b2,y:b3,platform:Android,
+66633132393363353531373465633064,SG H510,a:b0,b:b1,back:b9,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b3,leftstick:b17,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b20,rightstick:b18,righttrigger:a5,rightx:a3,righty:a4,start:b10,x:b19,y:b2,platform:Android,
+30306461613834333439303734316539,Microsoft SideWinder Pro,a:b0,b:b1,leftshoulder:b20,lefttrigger:b9,leftx:a0,lefty:a1,rightshoulder:b19,righttrigger:b10,start:b17,x:b2,y:b3,platform:Android,
+62653761636366393366613135366338,SN30 PP,a:b1,b:b0,back:b15,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b9,leftstick:b7,lefttrigger:b17,leftx:a0,lefty:a1,rightshoulder:b10,rightstick:b8,righttrigger:b18,rightx:a2,righty:a3,start:b6,x:b3,y:b2,platform:Android,
+38376662666661636265313264613039,SNES,a:b0,b:b1,back:b9,leftshoulder:b3,leftx:a0,lefty:a1,rightshoulder:b20,start:b10,x:b19,y:b2,platform:Android,
32633532643734376632656664383733,Sony DualSense,a:b1,b:b19,back:b17,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b3,leftstick:b15,lefttrigger:b9,leftx:a0,lefty:a1,rightshoulder:b20,rightstick:b6,righttrigger:b10,rightx:a2,righty:a5,start:b18,x:b0,y:b2,platform:Android,
61303162353165316365336436343139,Sony DualSense,a:b1,b:b19,back:b17,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b3,leftstick:b15,lefttrigger:b9,leftx:a0,lefty:a1,rightshoulder:b20,rightstick:b6,righttrigger:b10,rightx:a2,righty:a5,start:b18,x:b0,y:b2,platform:Android,
+63303964303462366136616266653561,Sony PSP,a:b21,b:b22,back:b27,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b25,leftx:a0,lefty:a1,rightshoulder:b26,start:b28,x:b23,y:b24,platform:Android,
+63376637643462343766333462383235,Sony Vita,a:b1,b:b19,back:b17,leftshoulder:b3,leftx:a0,lefty:a1,rightshoulder:b20,rightx:a3,righty:a4,start:b18,x:b0,y:b2,platform:Android,
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:Android,
05000000de2800000611000001000000,Steam Controller,a:b0,b:b1,back:b6,guide:b8,leftshoulder:b4,leftstick:b9,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b5,righttrigger:a3,start:b7,x:b2,y:b3,platform:Android,
+0500000011010000201400000f7e0f00,SteelSeries Nimbus,a:b0,b:b1,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b3,lefttrigger:b9,leftx:a0,lefty:a1,rightshoulder:b20,righttrigger:b10,rightx:a2,righty:a3,x:b19,y:b2,platform:Android,
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,
+30623739343039643830333266346439,Valve Steam 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,leftx:a0,lefty:a1,paddle1:b23,paddle2:b24,rightshoulder:b10,rightstick:b8,rightx:a2,righty:a3,start:b6,x:b2,y:b3,platform:Android,
+31643365666432386133346639383937,Valve Steam 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,leftx:a0,lefty:a1,paddle1:b23,paddle2:b24,rightshoulder:b10,rightstick:b8,rightx:a2,righty:a3,start:b6,x:b2,y:b3,platform:Android,
+30386438313564306161393537333663,Wii Classic,a:b23,b:b22,back:b29,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b27,lefttrigger:b25,leftx:a0,lefty:a1,rightshoulder:b28,righttrigger:b26,rightx:a2,righty:a3,start:b30,x:b24,y:b21,platform:Android,
+33333034646336346339646538643633,Wii Classic,a:b23,b:b22,back:b29,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b27,lefttrigger:b25,leftx:a0,lefty:a1,rightshoulder:b28,righttrigger:b26,rightx:a2,righty:a3,start:b30,x:b24,y:b21,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,
+30396232393162346330326334636566,Xbox 360,a:b0,b:b1,back:b4,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,
+38313038323730383864666463383533,Xbox 360,a:b0,b:b1,back:b4,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,
+65353331386662343338643939643636,Xbox 360,a:b0,b:b1,back:b4,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,
+65613532386633373963616462363038,Xbox 360,a:b0,b:b1,back:b4,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,
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,
+33356661323266333733373865656366,Xbox One Controller,a:b0,b:b1,back:b4,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,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,
+35623965373264386238353433656138,Xbox One Controller,a:b0,b:b1,back:b4,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,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,
+050000005e040000fd020000ffff3f00,Xbox One Wireless 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,
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,
34356136633366613530316338376136,Xbox Wireless Controller,a:b0,b:b1,back:b9,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b10,leftshoulder:b3,leftstick:b15,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b18,rightstick:b16,righttrigger:a5,rightx:a3,righty:a4,x:b17,y:b2,platform:Android,
+36616131643361333337396261666433,Xbox Wireless Controller,a:b0,b:b1,back:b15,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,
050000001727000044310000ffff3f00,XiaoMi Game Controller,a:b0,b:b1,back:b4,dpdown:b12,dpleft:b13,dpright:b14,dpup:b11,leftshoulder:b9,leftstick:b7,lefttrigger:a7,leftx:a0,lefty:a1,rightshoulder:b10,rightstick:b8,righttrigger:a6,rightx:a2,righty:a5,start:b6,x:b2,y:b3,platform:Android,
# iOS
@@ -1017,5 +1491,7 @@ xinput,XInput Controller,a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,
05000000de2800000611000001000000,Steam Controller,a:b0,b:b1,back:b6,guide:b8,leftshoulder:b4,leftstick:b9,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b5,righttrigger:a3,start:b7,x:b2,y:b3,platform: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,
+050000005e040000130b0000df870001,Xbox Series X 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,misc1:b10,rightshoulder:b5,rightstick:b7,righttrigger:a5,rightx:a3,righty:a4,start:b9,x:b2,y:b3,platform:iOS,
+050000005e040000130b0000ff870001,Xbox Series X 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,
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 f9a361c761..3dfe73ab8e 100644
--- a/core/input/input.cpp
+++ b/core/input/input.cpp
@@ -35,7 +35,7 @@
#include "core/input/input_map.h"
#include "core/os/os.h"
-static const char *_joy_buttons[JOY_BUTTON_SDL_MAX] = {
+static const char *_joy_buttons[(size_t)JoyButton::SDL_MAX] = {
"a",
"b",
"x",
@@ -59,7 +59,7 @@ static const char *_joy_buttons[JOY_BUTTON_SDL_MAX] = {
"touchpad",
};
-static const char *_joy_axes[JOY_AXIS_SDL_MAX] = {
+static const char *_joy_axes[(size_t)JoyAxis::SDL_MAX] = {
"leftx",
"lefty",
"rightx",
@@ -91,6 +91,7 @@ Input::MouseMode Input::get_mouse_mode() const {
void Input::_bind_methods() {
ClassDB::bind_method(D_METHOD("is_key_pressed", "keycode"), &Input::is_key_pressed);
+ ClassDB::bind_method(D_METHOD("is_physical_key_pressed", "keycode"), &Input::is_physical_key_pressed);
ClassDB::bind_method(D_METHOD("is_mouse_button_pressed", "button"), &Input::is_mouse_button_pressed);
ClassDB::bind_method(D_METHOD("is_joy_button_pressed", "device", "button"), &Input::is_joy_button_pressed);
ClassDB::bind_method(D_METHOD("is_action_pressed", "action", "exact_match"), &Input::is_action_pressed, DEFVAL(false));
@@ -102,7 +103,6 @@ void Input::_bind_methods() {
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));
ClassDB::bind_method(D_METHOD("remove_joy_mapping", "guid"), &Input::remove_joy_mapping);
- ClassDB::bind_method(D_METHOD("joy_connection_changed", "device", "connected", "name", "guid"), &Input::joy_connection_changed);
ClassDB::bind_method(D_METHOD("is_joy_known", "device"), &Input::is_joy_known);
ClassDB::bind_method(D_METHOD("get_joy_axis", "device", "axis"), &Input::get_joy_axis);
ClassDB::bind_method(D_METHOD("get_joy_name", "device"), &Input::get_joy_name);
@@ -117,6 +117,10 @@ void Input::_bind_methods() {
ClassDB::bind_method(D_METHOD("get_accelerometer"), &Input::get_accelerometer);
ClassDB::bind_method(D_METHOD("get_magnetometer"), &Input::get_magnetometer);
ClassDB::bind_method(D_METHOD("get_gyroscope"), &Input::get_gyroscope);
+ ClassDB::bind_method(D_METHOD("set_gravity", "value"), &Input::set_gravity);
+ ClassDB::bind_method(D_METHOD("set_accelerometer", "value"), &Input::set_accelerometer);
+ ClassDB::bind_method(D_METHOD("set_magnetometer", "value"), &Input::set_magnetometer);
+ ClassDB::bind_method(D_METHOD("set_gyroscope", "value"), &Input::set_gyroscope);
ClassDB::bind_method(D_METHOD("get_last_mouse_speed"), &Input::get_last_mouse_speed);
ClassDB::bind_method(D_METHOD("get_mouse_button_mask"), &Input::get_mouse_button_mask);
ClassDB::bind_method(D_METHOD("set_mouse_mode", "mode"), &Input::set_mouse_mode);
@@ -129,6 +133,7 @@ void Input::_bind_methods() {
ClassDB::bind_method(D_METHOD("set_custom_mouse_cursor", "image", "shape", "hotspot"), &Input::set_custom_mouse_cursor, DEFVAL(CURSOR_ARROW), DEFVAL(Vector2()));
ClassDB::bind_method(D_METHOD("parse_input_event", "event"), &Input::parse_input_event);
ClassDB::bind_method(D_METHOD("set_use_accumulated_input", "enable"), &Input::set_use_accumulated_input);
+ ClassDB::bind_method(D_METHOD("flush_buffered_events"), &Input::flush_buffered_events);
BIND_ENUM_CONSTANT(MOUSE_MODE_VISIBLE);
BIND_ENUM_CONSTANT(MOUSE_MODE_HIDDEN);
@@ -159,10 +164,11 @@ void Input::_bind_methods() {
void Input::get_argument_options(const StringName &p_function, int p_idx, List<String> *r_options) const {
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_action_raw_strength" ||
- pf == "get_axis" || pf == "get_vector")) {
+ 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_action_raw_strength" ||
+ pf == "get_axis" || pf == "get_vector")) {
List<PropertyInfo> pinfo;
ProjectSettings::get_singleton()->get_property_list(&pinfo);
@@ -217,13 +223,22 @@ bool Input::is_key_pressed(Key p_keycode) const {
return keys_pressed.has(p_keycode);
}
+bool Input::is_physical_key_pressed(Key p_keycode) const {
+ _THREAD_SAFE_METHOD_
+ return physical_keys_pressed.has(p_keycode);
+}
+
bool Input::is_mouse_button_pressed(MouseButton p_button) const {
_THREAD_SAFE_METHOD_
- return (mouse_button_mask & (1 << (p_button - 1))) != 0;
+ return (mouse_button_mask & mouse_button_to_mask(p_button)) != MouseButton::NONE;
+}
+
+static JoyAxis _combine_device(JoyAxis p_value, int p_device) {
+ return JoyAxis((int)p_value | (p_device << 20));
}
-static int _combine_device(int p_value, int p_device) {
- return p_value | (p_device << 20);
+static JoyButton _combine_device(JoyButton p_value, int p_device) {
+ return JoyButton((int)p_value | (p_device << 20));
}
bool Input::is_joy_button_pressed(int p_device, JoyButton p_button) const {
@@ -310,11 +325,11 @@ Vector2 Input::get_vector(const StringName &p_negative_x, const StringName &p_po
if (p_deadzone < 0.0f) {
// If the deadzone isn't specified, get it from the average of the actions.
- p_deadzone = (InputMap::get_singleton()->action_get_deadzone(p_positive_x) +
- InputMap::get_singleton()->action_get_deadzone(p_negative_x) +
- InputMap::get_singleton()->action_get_deadzone(p_positive_y) +
- InputMap::get_singleton()->action_get_deadzone(p_negative_y)) /
- 4;
+ p_deadzone = 0.25 *
+ (InputMap::get_singleton()->action_get_deadzone(p_positive_x) +
+ InputMap::get_singleton()->action_get_deadzone(p_negative_x) +
+ InputMap::get_singleton()->action_get_deadzone(p_positive_y) +
+ InputMap::get_singleton()->action_get_deadzone(p_negative_y));
}
// Circular length limiting and deadzone.
@@ -332,7 +347,7 @@ Vector2 Input::get_vector(const StringName &p_negative_x, const StringName &p_po
float Input::get_joy_axis(int p_device, JoyAxis p_axis) const {
_THREAD_SAFE_METHOD_
- int c = _combine_device(p_axis, p_device);
+ JoyAxis c = _combine_device(p_axis, p_device);
if (_joy_axis.has(c)) {
return _joy_axis[c];
} else {
@@ -388,7 +403,7 @@ void Input::joy_connection_changed(int p_idx, bool p_connected, String p_name, S
if (p_connected) {
String uidname = p_guid;
- if (p_guid == "") {
+ if (p_guid.is_empty()) {
int uidlen = MIN(p_name.length(), 16);
for (int i = 0; i < uidlen; i++) {
uidname = uidname + _hex_str(p_name[i]);
@@ -406,11 +421,11 @@ void Input::joy_connection_changed(int p_idx, bool p_connected, String p_name, S
js.mapping = mapping;
} else {
js.connected = false;
- for (int i = 0; i < JOY_BUTTON_MAX; i++) {
- int c = _combine_device(i, p_idx);
+ for (int i = 0; i < (int)JoyButton::MAX; i++) {
+ JoyButton c = _combine_device((JoyButton)i, p_idx);
joy_buttons_pressed.erase(c);
}
- for (int i = 0; i < JOY_AXIS_MAX; i++) {
+ for (int i = 0; i < (int)JoyAxis::MAX; i++) {
set_joy_axis(p_idx, (JoyAxis)i, 0.0f);
}
}
@@ -448,21 +463,28 @@ void Input::_parse_input_event_impl(const Ref<InputEvent> &p_event, bool p_is_em
// require additional handling by this class.
Ref<InputEventKey> k = p_event;
- if (k.is_valid() && !k->is_echo() && k->get_keycode() != 0) {
+ if (k.is_valid() && !k->is_echo() && k->get_keycode() != Key::NONE) {
if (k->is_pressed()) {
keys_pressed.insert(k->get_keycode());
} else {
keys_pressed.erase(k->get_keycode());
}
}
+ if (k.is_valid() && !k->is_echo() && k->get_physical_keycode() != Key::NONE) {
+ if (k->is_pressed()) {
+ physical_keys_pressed.insert(k->get_physical_keycode());
+ } else {
+ physical_keys_pressed.erase(k->get_physical_keycode());
+ }
+ }
Ref<InputEventMouseButton> mb = p_event;
if (mb.is_valid()) {
if (mb->is_pressed()) {
- mouse_button_mask |= (MouseButton)(1 << (mb->get_button_index() - 1));
+ mouse_button_mask |= mouse_button_to_mask(mb->get_button_index());
} else {
- mouse_button_mask &= (MouseButton) ~(1 << (mb->get_button_index() - 1));
+ mouse_button_mask &= ~mouse_button_to_mask(mb->get_button_index());
}
Point2 pos = mb->get_global_position();
@@ -470,7 +492,7 @@ void Input::_parse_input_event_impl(const Ref<InputEvent> &p_event, bool p_is_em
set_mouse_position(pos);
}
- if (event_dispatch_function && emulate_touch_from_mouse && !p_is_emulated && mb->get_button_index() == 1) {
+ if (event_dispatch_function && emulate_touch_from_mouse && !p_is_emulated && mb->get_button_index() == MouseButton::LEFT) {
Ref<InputEventScreenTouch> touch_event;
touch_event.instantiate();
touch_event->set_pressed(mb->is_pressed());
@@ -487,7 +509,7 @@ void Input::_parse_input_event_impl(const Ref<InputEvent> &p_event, bool p_is_em
set_mouse_position(pos);
}
- if (event_dispatch_function && emulate_touch_from_mouse && !p_is_emulated && mm->get_button_mask() & 1) {
+ if (event_dispatch_function && emulate_touch_from_mouse && !p_is_emulated && (mm->get_button_mask() & MouseButton::LEFT) != MouseButton::NONE) {
Ref<InputEventScreenDrag> drag_event;
drag_event.instantiate();
@@ -533,11 +555,11 @@ void Input::_parse_input_event_impl(const Ref<InputEvent> &p_event, bool p_is_em
button_event->set_position(st->get_position());
button_event->set_global_position(st->get_position());
button_event->set_pressed(st->is_pressed());
- button_event->set_button_index(MOUSE_BUTTON_LEFT);
+ button_event->set_button_index(MouseButton::LEFT);
if (st->is_pressed()) {
- button_event->set_button_mask(MouseButton(mouse_button_mask | MOUSE_BUTTON_MASK_LEFT));
+ button_event->set_button_mask(MouseButton(mouse_button_mask | MouseButton::MASK_LEFT));
} else {
- button_event->set_button_mask(MouseButton(mouse_button_mask & ~MOUSE_BUTTON_MASK_LEFT));
+ button_event->set_button_mask(MouseButton(mouse_button_mask & ~MouseButton::MASK_LEFT));
}
_parse_input_event_impl(button_event, true);
@@ -570,7 +592,7 @@ void Input::_parse_input_event_impl(const Ref<InputEvent> &p_event, bool p_is_em
Ref<InputEventJoypadButton> jb = p_event;
if (jb.is_valid()) {
- int c = _combine_device(jb->get_button_index(), jb->get_device());
+ JoyButton c = _combine_device(jb->get_button_index(), jb->get_device());
if (jb->is_pressed()) {
joy_buttons_pressed.insert(c);
@@ -618,7 +640,7 @@ void Input::_parse_input_event_impl(const Ref<InputEvent> &p_event, bool p_is_em
void Input::set_joy_axis(int p_device, JoyAxis p_axis, float p_value) {
_THREAD_SAFE_METHOD_
- int c = _combine_device(p_axis, p_device);
+ JoyAxis c = _combine_device(p_axis, p_device);
_joy_axis[c] = p_value;
}
@@ -686,7 +708,7 @@ Point2 Input::get_last_mouse_speed() const {
return mouse_speed_track.speed;
}
-int Input::get_mouse_button_mask() const {
+MouseButton Input::get_mouse_button_mask() const {
return mouse_button_mask; // do not trust OS implementation, should remove it - OS::get_singleton()->get_mouse_button_state();
}
@@ -704,11 +726,11 @@ Point2i Input::warp_mouse_motion(const Ref<InputEventMouseMotion> &p_motion, con
// detect the warp: if the relative distance is greater than the half of the size of the relevant rect
// (checked per each axis), it will be considered as the consequence of a former pointer warp.
- const Point2i rel_sgn(p_motion->get_relative().x >= 0.0f ? 1 : -1, p_motion->get_relative().y >= 0.0 ? 1 : -1);
+ const Point2i rel_sign(p_motion->get_relative().x >= 0.0f ? 1 : -1, p_motion->get_relative().y >= 0.0 ? 1 : -1);
const Size2i warp_margin = p_rect.size * 0.5f;
const Point2i rel_warped(
- Math::fmod(p_motion->get_relative().x + rel_sgn.x * warp_margin.x, p_rect.size.x) - rel_sgn.x * warp_margin.x,
- Math::fmod(p_motion->get_relative().y + rel_sgn.y * warp_margin.y, p_rect.size.y) - rel_sgn.y * warp_margin.y);
+ Math::fmod(p_motion->get_relative().x + rel_sign.x * warp_margin.x, p_rect.size.x) - rel_sign.x * warp_margin.x,
+ Math::fmod(p_motion->get_relative().y + rel_sign.y * warp_margin.y, p_rect.size.y) - rel_sign.y * warp_margin.y);
const Point2i pos_local = p_motion->get_global_position() - p_rect.position;
const Point2i pos_warped(Math::fposmod(pos_local.x, p_rect.size.x), Math::fposmod(pos_local.y, p_rect.size.y));
@@ -765,8 +787,8 @@ void Input::ensure_touch_mouse_raised() {
button_event->set_position(mouse_pos);
button_event->set_global_position(mouse_pos);
button_event->set_pressed(false);
- button_event->set_button_index(MOUSE_BUTTON_LEFT);
- button_event->set_button_mask(MouseButton(mouse_button_mask & ~MOUSE_BUTTON_MASK_LEFT));
+ button_event->set_button_index(MouseButton::LEFT);
+ button_event->set_button_mask(MouseButton(mouse_button_mask & ~MouseButton::MASK_LEFT));
_parse_input_event_impl(button_event, true);
}
@@ -852,6 +874,7 @@ void Input::release_pressed_events() {
flush_buffered_events(); // this is needed to release actions strengths
keys_pressed.clear();
+ physical_keys_pressed.clear();
joy_buttons_pressed.clear();
_joy_axis.clear();
@@ -870,10 +893,10 @@ void Input::joy_button(int p_device, JoyButton p_button, bool p_pressed) {
_THREAD_SAFE_METHOD_;
Joypad &joy = joy_names[p_device];
//printf("got button %i, mapping is %i\n", p_button, joy.mapping);
- if (joy.last_buttons[p_button] == p_pressed) {
+ if (joy.last_buttons[(size_t)p_button] == p_pressed) {
return;
}
- joy.last_buttons[p_button] = p_pressed;
+ joy.last_buttons[(size_t)p_button] = p_pressed;
if (joy.mapping == -1) {
_button_event(p_device, p_button, p_pressed);
return;
@@ -895,16 +918,16 @@ void Input::joy_button(int p_device, JoyButton p_button, bool p_pressed) {
void Input::joy_axis(int p_device, JoyAxis p_axis, const JoyAxisValue &p_value) {
_THREAD_SAFE_METHOD_;
- ERR_FAIL_INDEX(p_axis, JOY_AXIS_MAX);
+ ERR_FAIL_INDEX((int)p_axis, (int)JoyAxis::MAX);
Joypad &joy = joy_names[p_device];
- if (joy.last_axis[p_axis] == p_value.value) {
+ if (joy.last_axis[(size_t)p_axis] == p_value.value) {
return;
}
//when changing direction quickly, insert fake event to release pending inputmap actions
- float last = joy.last_axis[p_axis];
+ float last = joy.last_axis[(size_t)p_axis];
if (p_value.min == 0 && (last < 0.25 || last > 0.75) && (last - 0.5) * (p_value.value - 0.5) < 0) {
JoyAxisValue jx;
jx.min = p_value.min;
@@ -917,7 +940,7 @@ void Input::joy_axis(int p_device, JoyAxis p_axis, const JoyAxisValue &p_value)
joy_axis(p_device, p_axis, jx);
}
- joy.last_axis[p_axis] = p_value.value;
+ joy.last_axis[(size_t)p_axis] = p_value.value;
float val = p_value.min == 0 ? -1.0f + 2.0f * p_value.value : p_value.value;
if (joy.mapping == -1) {
@@ -929,32 +952,32 @@ void Input::joy_axis(int p_device, JoyAxis p_axis, const JoyAxisValue &p_value)
if (map.type == TYPE_BUTTON) {
bool pressed = map.value > 0.5;
- if (pressed == joy_buttons_pressed.has(_combine_device(map.index, p_device))) {
+ if (pressed == joy_buttons_pressed.has(_combine_device((JoyButton)map.index, p_device))) {
// Button already pressed or released; so ignore.
return;
}
_button_event(p_device, (JoyButton)map.index, pressed);
// Ensure opposite D-Pad button is also released.
- switch (map.index) {
- case JOY_BUTTON_DPAD_UP:
- if (joy_buttons_pressed.has(_combine_device(JOY_BUTTON_DPAD_DOWN, p_device))) {
- _button_event(p_device, JOY_BUTTON_DPAD_DOWN, false);
+ switch ((JoyButton)map.index) {
+ case JoyButton::DPAD_UP:
+ if (joy_buttons_pressed.has(_combine_device(JoyButton::DPAD_DOWN, p_device))) {
+ _button_event(p_device, JoyButton::DPAD_DOWN, false);
}
break;
- case JOY_BUTTON_DPAD_DOWN:
- if (joy_buttons_pressed.has(_combine_device(JOY_BUTTON_DPAD_UP, p_device))) {
- _button_event(p_device, JOY_BUTTON_DPAD_UP, false);
+ case JoyButton::DPAD_DOWN:
+ if (joy_buttons_pressed.has(_combine_device(JoyButton::DPAD_UP, p_device))) {
+ _button_event(p_device, JoyButton::DPAD_UP, false);
}
break;
- case JOY_BUTTON_DPAD_LEFT:
- if (joy_buttons_pressed.has(_combine_device(JOY_BUTTON_DPAD_RIGHT, p_device))) {
- _button_event(p_device, JOY_BUTTON_DPAD_RIGHT, false);
+ case JoyButton::DPAD_LEFT:
+ if (joy_buttons_pressed.has(_combine_device(JoyButton::DPAD_RIGHT, p_device))) {
+ _button_event(p_device, JoyButton::DPAD_RIGHT, false);
}
break;
- case JOY_BUTTON_DPAD_RIGHT:
- if (joy_buttons_pressed.has(_combine_device(JOY_BUTTON_DPAD_LEFT, p_device))) {
- _button_event(p_device, JOY_BUTTON_DPAD_LEFT, false);
+ case JoyButton::DPAD_RIGHT:
+ if (joy_buttons_pressed.has(_combine_device(JoyButton::DPAD_LEFT, p_device))) {
+ _button_event(p_device, JoyButton::DPAD_LEFT, false);
}
break;
default:
@@ -971,27 +994,27 @@ void Input::joy_axis(int p_device, JoyAxis p_axis, const JoyAxisValue &p_value)
//printf("invalid mapping\n");
}
-void Input::joy_hat(int p_device, int p_val) {
+void Input::joy_hat(int p_device, HatMask p_val) {
_THREAD_SAFE_METHOD_;
const Joypad &joy = joy_names[p_device];
- JoyEvent map[HAT_MAX];
+ JoyEvent map[(size_t)HatDir::MAX];
- map[HatDir::HAT_UP].type = TYPE_BUTTON;
- map[HatDir::HAT_UP].index = JOY_BUTTON_DPAD_UP;
- map[HatDir::HAT_UP].value = 0;
+ map[(size_t)HatDir::UP].type = TYPE_BUTTON;
+ map[(size_t)HatDir::UP].index = (int)JoyButton::DPAD_UP;
+ map[(size_t)HatDir::UP].value = 0;
- map[HatDir::HAT_RIGHT].type = TYPE_BUTTON;
- map[HatDir::HAT_RIGHT].index = JOY_BUTTON_DPAD_RIGHT;
- map[HatDir::HAT_RIGHT].value = 0;
+ map[(size_t)HatDir::RIGHT].type = TYPE_BUTTON;
+ map[(size_t)HatDir::RIGHT].index = (int)JoyButton::DPAD_RIGHT;
+ map[(size_t)HatDir::RIGHT].value = 0;
- map[HatDir::HAT_DOWN].type = TYPE_BUTTON;
- map[HatDir::HAT_DOWN].index = JOY_BUTTON_DPAD_DOWN;
- map[HatDir::HAT_DOWN].value = 0;
+ map[(size_t)HatDir::DOWN].type = TYPE_BUTTON;
+ map[(size_t)HatDir::DOWN].index = (int)JoyButton::DPAD_DOWN;
+ map[(size_t)HatDir::DOWN].value = 0;
- map[HatDir::HAT_LEFT].type = TYPE_BUTTON;
- map[HatDir::HAT_LEFT].index = JOY_BUTTON_DPAD_LEFT;
- map[HatDir::HAT_LEFT].value = 0;
+ map[(size_t)HatDir::LEFT].type = TYPE_BUTTON;
+ map[(size_t)HatDir::LEFT].index = (int)JoyButton::DPAD_LEFT;
+ map[(size_t)HatDir::LEFT].value = 0;
if (joy.mapping != -1) {
_get_mapped_hat_events(map_db[joy.mapping], (HatDir)0, map);
@@ -999,18 +1022,18 @@ void Input::joy_hat(int p_device, int p_val) {
int cur_val = joy_names[p_device].hat_current;
- for (int hat_direction = 0, hat_mask = 1; hat_direction < HAT_MAX; hat_direction++, hat_mask <<= 1) {
- if ((p_val & hat_mask) != (cur_val & hat_mask)) {
+ for (int hat_direction = 0, hat_mask = 1; hat_direction < (int)HatDir::MAX; hat_direction++, hat_mask <<= 1) {
+ if (((int)p_val & hat_mask) != (cur_val & hat_mask)) {
if (map[hat_direction].type == TYPE_BUTTON) {
- _button_event(p_device, (JoyButton)map[hat_direction].index, p_val & hat_mask);
+ _button_event(p_device, (JoyButton)map[hat_direction].index, (int)p_val & hat_mask);
}
if (map[hat_direction].type == TYPE_AXIS) {
- _axis_event(p_device, (JoyAxis)map[hat_direction].index, (p_val & hat_mask) ? map[hat_direction].value : 0.0);
+ _axis_event(p_device, (JoyAxis)map[hat_direction].index, ((int)p_val & hat_mask) ? map[hat_direction].value : 0.0);
}
}
}
- joy_names[p_device].hat_current = p_val;
+ joy_names[p_device].hat_current = (int)p_val;
}
void Input::_button_event(int p_device, JoyButton p_index, bool p_pressed) {
@@ -1043,10 +1066,10 @@ Input::JoyEvent Input::_get_mapped_button_event(const JoyDeviceMapping &mapping,
event.type = binding.outputType;
switch (binding.outputType) {
case TYPE_BUTTON:
- event.index = binding.output.button;
+ event.index = (int)binding.output.button;
return event;
case TYPE_AXIS:
- event.index = binding.output.axis.axis;
+ event.index = (int)binding.output.axis.axis;
switch (binding.output.axis.range) {
case POSITIVE_HALF_AXIS:
event.value = 1;
@@ -1098,7 +1121,7 @@ Input::JoyEvent Input::_get_mapped_axis_event(const JoyDeviceMapping &mapping, J
}
switch (binding.outputType) {
case TYPE_BUTTON:
- event.index = binding.output.button;
+ event.index = (int)binding.output.button;
switch (binding.input.axis.range) {
case POSITIVE_HALF_AXIS:
event.value = shifted_positive_value;
@@ -1115,7 +1138,7 @@ Input::JoyEvent Input::_get_mapped_axis_event(const JoyDeviceMapping &mapping, J
}
return event;
case TYPE_AXIS:
- event.index = binding.output.axis.axis;
+ event.index = (int)binding.output.axis.axis;
event.value = value;
if (binding.output.axis.range != binding.input.axis.range) {
switch (binding.output.axis.range) {
@@ -1144,43 +1167,43 @@ void Input::_get_mapped_hat_events(const JoyDeviceMapping &mapping, HatDir p_hat
for (int i = 0; i < mapping.bindings.size(); i++) {
const JoyBinding binding = mapping.bindings[i];
if (binding.inputType == TYPE_HAT && binding.input.hat.hat == p_hat) {
- int hat_direction;
+ HatDir hat_direction;
switch (binding.input.hat.hat_mask) {
- case HatMask::HAT_MASK_UP:
- hat_direction = HatDir::HAT_UP;
+ case HatMask::UP:
+ hat_direction = HatDir::UP;
break;
- case HatMask::HAT_MASK_RIGHT:
- hat_direction = HatDir::HAT_RIGHT;
+ case HatMask::RIGHT:
+ hat_direction = HatDir::RIGHT;
break;
- case HatMask::HAT_MASK_DOWN:
- hat_direction = HatDir::HAT_DOWN;
+ case HatMask::DOWN:
+ hat_direction = HatDir::DOWN;
break;
- case HatMask::HAT_MASK_LEFT:
- hat_direction = HatDir::HAT_LEFT;
+ case HatMask::LEFT:
+ hat_direction = HatDir::LEFT;
break;
default:
ERR_PRINT_ONCE("Joypad button mapping error.");
continue;
}
- r_events[hat_direction].type = binding.outputType;
+ r_events[(size_t)hat_direction].type = binding.outputType;
switch (binding.outputType) {
case TYPE_BUTTON:
- r_events[hat_direction].index = binding.output.button;
+ r_events[(size_t)hat_direction].index = (int)binding.output.button;
break;
case TYPE_AXIS:
- r_events[hat_direction].index = binding.output.axis.axis;
+ r_events[(size_t)hat_direction].index = (int)binding.output.axis.axis;
switch (binding.output.axis.range) {
case POSITIVE_HALF_AXIS:
- r_events[hat_direction].value = 1;
+ r_events[(size_t)hat_direction].value = 1;
break;
case NEGATIVE_HALF_AXIS:
- r_events[hat_direction].value = -1;
+ r_events[(size_t)hat_direction].value = -1;
break;
case FULL_AXIS:
// It doesn't make sense for a hat direction to map to a full axis,
// but keeping as a default for a trigger with a positive half-axis.
- r_events[hat_direction].value = 1;
+ r_events[(size_t)hat_direction].value = 1;
break;
}
break;
@@ -1192,21 +1215,21 @@ void Input::_get_mapped_hat_events(const JoyDeviceMapping &mapping, HatDir p_hat
}
JoyButton Input::_get_output_button(String output) {
- for (int i = 0; i < JOY_BUTTON_SDL_MAX; i++) {
+ for (int i = 0; i < (int)JoyButton::SDL_MAX; i++) {
if (output == _joy_buttons[i]) {
return JoyButton(i);
}
}
- return JoyButton::JOY_BUTTON_INVALID;
+ return JoyButton::INVALID;
}
JoyAxis Input::_get_output_axis(String output) {
- for (int i = 0; i < JOY_AXIS_SDL_MAX; i++) {
+ for (int i = 0; i < (int)JoyAxis::SDL_MAX; i++) {
if (output == _joy_axes[i]) {
return JoyAxis(i);
}
}
- return JoyAxis::JOY_AXIS_INVALID;
+ return JoyAxis::INVALID;
}
void Input::parse_mapping(String p_mapping) {
@@ -1226,14 +1249,14 @@ void Input::parse_mapping(String p_mapping) {
int idx = 1;
while (++idx < entry.size()) {
- if (entry[idx] == "") {
+ if (entry[idx].is_empty()) {
continue;
}
String output = entry[idx].get_slice(":", 0).replace(" ", "");
String input = entry[idx].get_slice(":", 1).replace(" ", "");
ERR_CONTINUE_MSG(output.length() < 1 || input.length() < 2,
- String(entry[idx] + "\nInvalid device mapping entry: " + entry[idx]));
+ vformat("Invalid device mapping entry \"%s\" in mapping:\n%s", entry[idx], p_mapping));
if (output == "platform" || output == "hint") {
continue;
@@ -1241,7 +1264,8 @@ void Input::parse_mapping(String p_mapping) {
JoyAxisRange output_range = FULL_AXIS;
if (output[0] == '+' || output[0] == '-') {
- ERR_CONTINUE_MSG(output.length() < 2, String(entry[idx] + "\nInvalid output: " + entry[idx]));
+ ERR_CONTINUE_MSG(output.length() < 2,
+ vformat("Invalid output entry \"%s\" in mapping:\n%s", entry[idx], p_mapping));
if (output[0] == '+') {
output_range = POSITIVE_HALF_AXIS;
} else if (output[0] == '-') {
@@ -1266,16 +1290,16 @@ void Input::parse_mapping(String p_mapping) {
JoyButton output_button = _get_output_button(output);
JoyAxis output_axis = _get_output_axis(output);
- ERR_CONTINUE_MSG(output_button == JOY_BUTTON_INVALID && output_axis == JOY_AXIS_INVALID,
- String(entry[idx] + "\nUnrecognised output string: " + output));
- ERR_CONTINUE_MSG(output_button != JOY_BUTTON_INVALID && output_axis != JOY_AXIS_INVALID,
- String("BUG: Output string matched both button and axis: " + output));
+ ERR_CONTINUE_MSG(output_button == JoyButton::INVALID && output_axis == JoyAxis::INVALID,
+ vformat("Unrecognised output string \"%s\" in mapping:\n%s", output, p_mapping));
+ ERR_CONTINUE_MSG(output_button != JoyButton::INVALID && output_axis != JoyAxis::INVALID,
+ vformat("Output string \"%s\" matched both button and axis in mapping:\n%s", output, p_mapping));
JoyBinding binding;
- if (output_button != JOY_BUTTON_INVALID) {
+ if (output_button != JoyButton::INVALID) {
binding.outputType = TYPE_BUTTON;
binding.output.button = output_button;
- } else if (output_axis != JOY_AXIS_INVALID) {
+ } else if (output_axis != JoyAxis::INVALID) {
binding.outputType = TYPE_AXIS;
binding.output.axis.axis = output_axis;
binding.output.axis.range = output_range;
@@ -1294,13 +1318,13 @@ void Input::parse_mapping(String p_mapping) {
break;
case 'h':
ERR_CONTINUE_MSG(input.length() != 4 || input[2] != '.',
- String(entry[idx] + "\nInvalid hat input: " + input));
+ vformat("Invalid had input \"%s\" in mapping:\n%s", input, p_mapping));
binding.inputType = TYPE_HAT;
binding.input.hat.hat = (HatDir)input.substr(1, 1).to_int();
binding.input.hat.hat_mask = static_cast<HatMask>(input.substr(3).to_int());
break;
default:
- ERR_CONTINUE_MSG(true, String(entry[idx] + "\nUnrecognised input string: " + input));
+ ERR_CONTINUE_MSG(true, vformat("Unrecognized input string \"%s\" in mapping:\n%s", input, p_mapping));
}
mapping.bindings.push_back(binding);
@@ -1326,7 +1350,7 @@ void Input::add_joy_mapping(String p_mapping, bool p_update_existing) {
void Input::remove_joy_mapping(String p_guid) {
for (int i = map_db.size() - 1; i >= 0; i--) {
if (p_guid == map_db[i].uid) {
- map_db.remove(i);
+ map_db.remove_at(i);
}
}
for (KeyValue<int, Joypad> &E : joy_names) {
@@ -1396,10 +1420,10 @@ Input::Input() {
// If defined, parse SDL_GAMECONTROLLERCONFIG for possible new mappings/overrides.
String env_mapping = OS::get_singleton()->get_environment("SDL_GAMECONTROLLERCONFIG");
- if (env_mapping != "") {
+ if (!env_mapping.is_empty()) {
Vector<String> entries = env_mapping.split("\n");
for (int i = 0; i < entries.size(); i++) {
- if (entries[i] == "") {
+ if (entries[i].is_empty()) {
continue;
}
parse_mapping(entries[i]);
diff --git a/core/input/input.h b/core/input/input.h
index 6819fc8eb0..faec654a3c 100644
--- a/core/input/input.h
+++ b/core/input/input.h
@@ -85,11 +85,12 @@ public:
typedef void (*EventDispatchFunc)(const Ref<InputEvent> &p_event);
private:
- int mouse_button_mask = 0;
+ MouseButton mouse_button_mask = MouseButton::NONE;
- Set<int> keys_pressed;
- Set<int> joy_buttons_pressed;
- Map<int, float> _joy_axis;
+ Set<Key> physical_keys_pressed;
+ Set<Key> keys_pressed;
+ Set<JoyButton> joy_buttons_pressed;
+ Map<JoyAxis, float> _joy_axis;
//Map<StringName,int> custom_action_press;
Vector3 gravity;
Vector3 accelerometer;
@@ -133,9 +134,9 @@ private:
StringName name;
StringName uid;
bool connected = false;
- bool last_buttons[JOY_BUTTON_MAX] = { false };
- float last_axis[JOY_AXIS_MAX] = { 0.0f };
- int last_hat = HatMask::HAT_MASK_CENTER;
+ bool last_buttons[(size_t)JoyButton::MAX] = { false };
+ float last_axis[(size_t)JoyAxis::MAX] = { 0.0f };
+ HatMask last_hat = HatMask::CENTER;
int mapping = -1;
int hat_current = 0;
};
@@ -162,7 +163,7 @@ private:
struct JoyEvent {
int type;
- int index;
+ int index; // Can be either JoyAxis or JoyButton.
float value;
};
@@ -206,7 +207,7 @@ private:
JoyEvent _get_mapped_button_event(const JoyDeviceMapping &mapping, JoyButton p_button);
JoyEvent _get_mapped_axis_event(const JoyDeviceMapping &mapping, JoyAxis p_axis, float p_value);
- void _get_mapped_hat_events(const JoyDeviceMapping &mapping, HatDir p_hat, JoyEvent r_events[HAT_MAX]);
+ void _get_mapped_hat_events(const JoyDeviceMapping &mapping, HatDir p_hat, JoyEvent r_events[(size_t)HatDir::MAX]);
JoyButton _get_output_button(String output);
JoyAxis _get_output_axis(String output);
void _button_event(int p_device, JoyButton p_index, bool p_pressed);
@@ -247,6 +248,7 @@ public:
static Input *get_singleton();
bool is_key_pressed(Key p_keycode) const;
+ bool is_physical_key_pressed(Key p_keycode) const;
bool is_mouse_button_pressed(MouseButton p_button) const;
bool is_joy_button_pressed(int p_device, JoyButton p_button) const;
bool is_action_pressed(const StringName &p_action, bool p_exact = false) const;
@@ -265,7 +267,6 @@ public:
float get_joy_vibration_duration(int p_device);
uint64_t get_joy_vibration_timestamp(int p_device);
void joy_connection_changed(int p_idx, bool p_connected, String p_name, String p_guid = "");
- void parse_joypad_mapping(String p_mapping, bool p_update_existing);
Vector3 get_gravity() const;
Vector3 get_accelerometer() const;
@@ -274,7 +275,7 @@ public:
Point2 get_mouse_position() const;
Point2 get_last_mouse_speed() const;
- int get_mouse_button_mask() const;
+ MouseButton get_mouse_button_mask() const;
void warp_mouse_position(const Vector2 &p_to);
Point2i warp_mouse_motion(const Ref<InputEventMouseMotion> &p_motion, const Rect2 &p_rect);
@@ -313,7 +314,7 @@ public:
void parse_mapping(String p_mapping);
void joy_button(int p_device, JoyButton p_button, bool p_pressed);
void joy_axis(int p_device, JoyAxis p_axis, const JoyAxisValue &p_value);
- void joy_hat(int p_device, int p_val);
+ void joy_hat(int p_device, HatMask p_val);
void add_joy_mapping(String p_mapping, bool p_update_existing = false);
void remove_joy_mapping(String p_guid);
diff --git a/core/input/input_enums.h b/core/input/input_enums.h
index 4479a85bfe..8601007ac9 100644
--- a/core/input/input_enums.h
+++ b/core/input/input_enums.h
@@ -31,90 +31,106 @@
#ifndef INPUT_ENUMS_H
#define INPUT_ENUMS_H
-enum HatDir {
- HAT_UP = 0,
- HAT_RIGHT = 1,
- HAT_DOWN = 2,
- HAT_LEFT = 3,
- HAT_MAX = 4,
+enum class HatDir {
+ UP = 0,
+ RIGHT = 1,
+ DOWN = 2,
+ LEFT = 3,
+ MAX = 4,
};
-enum HatMask {
- HAT_MASK_CENTER = 0,
- HAT_MASK_UP = 1,
- HAT_MASK_RIGHT = 2,
- HAT_MASK_DOWN = 4,
- HAT_MASK_LEFT = 8,
+enum class HatMask {
+ CENTER = 0,
+ UP = 1,
+ RIGHT = 2,
+ DOWN = 4,
+ LEFT = 8,
};
-enum JoyAxis {
- JOY_AXIS_INVALID = -1,
- JOY_AXIS_LEFT_X = 0,
- JOY_AXIS_LEFT_Y = 1,
- JOY_AXIS_RIGHT_X = 2,
- JOY_AXIS_RIGHT_Y = 3,
- JOY_AXIS_TRIGGER_LEFT = 4,
- JOY_AXIS_TRIGGER_RIGHT = 5,
- JOY_AXIS_SDL_MAX = 6,
- JOY_AXIS_MAX = 10, // OpenVR supports up to 5 Joysticks making a total of 10 axes.
+enum class JoyAxis {
+ INVALID = -1,
+ LEFT_X = 0,
+ LEFT_Y = 1,
+ RIGHT_X = 2,
+ RIGHT_Y = 3,
+ TRIGGER_LEFT = 4,
+ TRIGGER_RIGHT = 5,
+ SDL_MAX = 6,
+ MAX = 10, // OpenVR supports up to 5 Joysticks making a total of 10 axes.
};
-enum JoyButton {
- JOY_BUTTON_INVALID = -1,
- JOY_BUTTON_A = 0,
- JOY_BUTTON_B = 1,
- JOY_BUTTON_X = 2,
- JOY_BUTTON_Y = 3,
- JOY_BUTTON_BACK = 4,
- JOY_BUTTON_GUIDE = 5,
- JOY_BUTTON_START = 6,
- JOY_BUTTON_LEFT_STICK = 7,
- JOY_BUTTON_RIGHT_STICK = 8,
- JOY_BUTTON_LEFT_SHOULDER = 9,
- JOY_BUTTON_RIGHT_SHOULDER = 10,
- JOY_BUTTON_DPAD_UP = 11,
- JOY_BUTTON_DPAD_DOWN = 12,
- JOY_BUTTON_DPAD_LEFT = 13,
- JOY_BUTTON_DPAD_RIGHT = 14,
- JOY_BUTTON_MISC1 = 15,
- JOY_BUTTON_PADDLE1 = 16,
- JOY_BUTTON_PADDLE2 = 17,
- JOY_BUTTON_PADDLE3 = 18,
- JOY_BUTTON_PADDLE4 = 19,
- JOY_BUTTON_TOUCHPAD = 20,
- JOY_BUTTON_SDL_MAX = 21,
- JOY_BUTTON_MAX = 36, // Android supports up to 36 buttons.
+enum class JoyButton {
+ INVALID = -1,
+ A = 0,
+ B = 1,
+ X = 2,
+ Y = 3,
+ BACK = 4,
+ GUIDE = 5,
+ START = 6,
+ LEFT_STICK = 7,
+ RIGHT_STICK = 8,
+ LEFT_SHOULDER = 9,
+ RIGHT_SHOULDER = 10,
+ DPAD_UP = 11,
+ DPAD_DOWN = 12,
+ DPAD_LEFT = 13,
+ DPAD_RIGHT = 14,
+ MISC1 = 15,
+ PADDLE1 = 16,
+ PADDLE2 = 17,
+ PADDLE3 = 18,
+ PADDLE4 = 19,
+ TOUCHPAD = 20,
+ SDL_MAX = 21,
+ MAX = 36, // Android supports up to 36 buttons.
};
-enum MIDIMessage {
- MIDI_MESSAGE_NONE = 0,
- MIDI_MESSAGE_NOTE_OFF = 0x8,
- MIDI_MESSAGE_NOTE_ON = 0x9,
- MIDI_MESSAGE_AFTERTOUCH = 0xA,
- MIDI_MESSAGE_CONTROL_CHANGE = 0xB,
- MIDI_MESSAGE_PROGRAM_CHANGE = 0xC,
- MIDI_MESSAGE_CHANNEL_PRESSURE = 0xD,
- MIDI_MESSAGE_PITCH_BEND = 0xE,
+enum class MIDIMessage {
+ NONE = 0,
+ NOTE_OFF = 0x8,
+ NOTE_ON = 0x9,
+ AFTERTOUCH = 0xA,
+ CONTROL_CHANGE = 0xB,
+ PROGRAM_CHANGE = 0xC,
+ CHANNEL_PRESSURE = 0xD,
+ PITCH_BEND = 0xE,
};
-enum MouseButton {
- MOUSE_BUTTON_NONE = 0,
- MOUSE_BUTTON_LEFT = 1,
- MOUSE_BUTTON_RIGHT = 2,
- MOUSE_BUTTON_MIDDLE = 3,
- MOUSE_BUTTON_WHEEL_UP = 4,
- MOUSE_BUTTON_WHEEL_DOWN = 5,
- MOUSE_BUTTON_WHEEL_LEFT = 6,
- MOUSE_BUTTON_WHEEL_RIGHT = 7,
- MOUSE_BUTTON_XBUTTON1 = 8,
- MOUSE_BUTTON_XBUTTON2 = 9,
- MOUSE_BUTTON_MASK_LEFT = (1 << (MOUSE_BUTTON_LEFT - 1)),
- MOUSE_BUTTON_MASK_RIGHT = (1 << (MOUSE_BUTTON_RIGHT - 1)),
- MOUSE_BUTTON_MASK_MIDDLE = (1 << (MOUSE_BUTTON_MIDDLE - 1)),
- MOUSE_BUTTON_MASK_XBUTTON1 = (1 << (MOUSE_BUTTON_XBUTTON1 - 1)),
- MOUSE_BUTTON_MASK_XBUTTON2 = (1 << (MOUSE_BUTTON_XBUTTON2 - 1)),
+enum class MouseButton {
+ NONE = 0,
+ LEFT = 1,
+ RIGHT = 2,
+ MIDDLE = 3,
+ WHEEL_UP = 4,
+ WHEEL_DOWN = 5,
+ WHEEL_LEFT = 6,
+ WHEEL_RIGHT = 7,
+ MB_XBUTTON1 = 8, // "XBUTTON1" is a reserved word on Windows.
+ MB_XBUTTON2 = 9, // "XBUTTON2" is a reserved word on Windows.
+ MASK_LEFT = (1 << (LEFT - 1)),
+ MASK_RIGHT = (1 << (RIGHT - 1)),
+ MASK_MIDDLE = (1 << (MIDDLE - 1)),
+ MASK_XBUTTON1 = (1 << (MB_XBUTTON1 - 1)),
+ MASK_XBUTTON2 = (1 << (MB_XBUTTON2 - 1)),
};
+inline MouseButton mouse_button_to_mask(MouseButton button) {
+ return MouseButton(1 << ((int)button - 1));
+}
+
+inline MouseButton operator&(MouseButton a, MouseButton b) {
+ return (MouseButton)((int)a & (int)b);
+}
+
+inline MouseButton operator|(MouseButton a, MouseButton b) {
+ return (MouseButton)((int)a | (int)b);
+}
+
+inline MouseButton operator^(MouseButton a, MouseButton b) {
+ return (MouseButton)((int)a ^ (int)b);
+}
+
inline MouseButton &operator|=(MouseButton &a, MouseButton b) {
return (MouseButton &)((int &)a |= (int)b);
}
@@ -123,4 +139,28 @@ inline MouseButton &operator&=(MouseButton &a, MouseButton b) {
return (MouseButton &)((int &)a &= (int)b);
}
+inline MouseButton operator~(MouseButton a) {
+ return (MouseButton)(~(int)a);
+}
+
+inline HatMask operator|(HatMask a, HatMask b) {
+ return (HatMask)((int)a | (int)b);
+}
+
+inline HatMask operator&(HatMask a, HatMask b) {
+ return (HatMask)((int)a & (int)b);
+}
+
+inline HatMask &operator&=(HatMask &a, HatMask b) {
+ return (HatMask &)((int &)a &= (int)b);
+}
+
+inline HatMask &operator|=(HatMask &a, HatMask b) {
+ return (HatMask &)((int &)a |= (int)b);
+}
+
+inline HatMask operator~(HatMask a) {
+ return (HatMask)(~(int)a);
+}
+
#endif // INPUT_ENUMS_H
diff --git a/core/input/input_event.cpp b/core/input/input_event.cpp
index 1d2b5f19ee..7c98fa9540 100644
--- a/core/input/input_event.cpp
+++ b/core/input/input_event.cpp
@@ -203,19 +203,19 @@ void InputEventWithModifiers::set_modifiers_from_event(const InputEventWithModif
set_meta_pressed(event->is_meta_pressed());
}
-uint32_t InputEventWithModifiers::get_modifiers_mask() const {
- uint32_t mask = 0;
+Key InputEventWithModifiers::get_modifiers_mask() const {
+ Key mask = Key::NONE;
if (is_ctrl_pressed()) {
- mask |= KEY_MASK_CTRL;
+ mask |= KeyModifierMask::CTRL;
}
if (is_shift_pressed()) {
- mask |= KEY_MASK_SHIFT;
+ mask |= KeyModifierMask::SHIFT;
}
if (is_alt_pressed()) {
- mask |= KEY_MASK_ALT;
+ mask |= KeyModifierMask::ALT;
}
if (is_meta_pressed()) {
- mask |= KEY_MASK_META;
+ mask |= KeyModifierMask::META;
}
return mask;
}
@@ -224,16 +224,16 @@ String InputEventWithModifiers::as_text() const {
Vector<String> mod_names;
if (is_ctrl_pressed()) {
- mod_names.push_back(find_keycode_name(KEY_CTRL));
+ mod_names.push_back(find_keycode_name(Key::CTRL));
}
if (is_shift_pressed()) {
- mod_names.push_back(find_keycode_name(KEY_SHIFT));
+ mod_names.push_back(find_keycode_name(Key::SHIFT));
}
if (is_alt_pressed()) {
- mod_names.push_back(find_keycode_name(KEY_ALT));
+ mod_names.push_back(find_keycode_name(Key::ALT));
}
if (is_meta_pressed()) {
- mod_names.push_back(find_keycode_name(KEY_META));
+ mod_names.push_back(find_keycode_name(Key::META));
}
if (!mod_names.is_empty()) {
@@ -325,12 +325,12 @@ Key InputEventKey::get_physical_keycode() const {
return physical_keycode;
}
-void InputEventKey::set_unicode(uint32_t p_unicode) {
+void InputEventKey::set_unicode(char32_t p_unicode) {
unicode = p_unicode;
emit_changed();
}
-uint32_t InputEventKey::get_unicode() const {
+char32_t InputEventKey::get_unicode() const {
return unicode;
}
@@ -343,29 +343,29 @@ bool InputEventKey::is_echo() const {
return echo;
}
-uint32_t InputEventKey::get_keycode_with_modifiers() const {
+Key InputEventKey::get_keycode_with_modifiers() const {
return keycode | get_modifiers_mask();
}
-uint32_t InputEventKey::get_physical_keycode_with_modifiers() const {
+Key InputEventKey::get_physical_keycode_with_modifiers() const {
return physical_keycode | get_modifiers_mask();
}
String InputEventKey::as_text() const {
String kc;
- if (keycode == 0) {
+ if (keycode == Key::NONE) {
kc = keycode_get_string(physical_keycode) + " (" + RTR("Physical") + ")";
} else {
kc = keycode_get_string(keycode);
}
- if (kc == String()) {
+ if (kc.is_empty()) {
return kc;
}
String mods_text = InputEventWithModifiers::as_text();
- return mods_text == "" ? kc : mods_text + "+" + kc;
+ return mods_text.is_empty() ? kc : mods_text + "+" + kc;
}
String InputEventKey::to_string() {
@@ -374,15 +374,15 @@ String InputEventKey::to_string() {
String kc = "";
String physical = "false";
- if (keycode == 0) {
- kc = itos(physical_keycode) + " (" + keycode_get_string(physical_keycode) + ")";
+ if (keycode == Key::NONE) {
+ kc = itos((int64_t)physical_keycode) + " (" + keycode_get_string(physical_keycode) + ")";
physical = "true";
} else {
- kc = itos(keycode) + " (" + keycode_get_string(keycode) + ")";
+ kc = itos((int64_t)keycode) + " (" + keycode_get_string(keycode) + ")";
}
String mods = InputEventWithModifiers::as_text();
- mods = mods == "" ? TTR("none") : mods;
+ mods = mods.is_empty() ? TTR("none") : mods;
return vformat("InputEventKey: keycode=%s, mods=%s, physical=%s, pressed=%s, echo=%s", kc, mods, physical, p, e);
}
@@ -390,22 +390,22 @@ String InputEventKey::to_string() {
Ref<InputEventKey> InputEventKey::create_reference(Key p_keycode) {
Ref<InputEventKey> ie;
ie.instantiate();
- ie->set_keycode(p_keycode & KEY_CODE_MASK);
- ie->set_unicode(p_keycode & KEY_CODE_MASK);
+ ie->set_keycode(p_keycode & KeyModifierMask::CODE_MASK);
+ ie->set_unicode(char32_t(p_keycode & KeyModifierMask::CODE_MASK));
- if (p_keycode & KEY_MASK_SHIFT) {
+ if ((p_keycode & KeyModifierMask::SHIFT) != Key::NONE) {
ie->set_shift_pressed(true);
}
- if (p_keycode & KEY_MASK_ALT) {
+ if ((p_keycode & KeyModifierMask::ALT) != Key::NONE) {
ie->set_alt_pressed(true);
}
- if (p_keycode & KEY_MASK_CTRL) {
+ if ((p_keycode & KeyModifierMask::CTRL) != Key::NONE) {
ie->set_ctrl_pressed(true);
}
- if (p_keycode & KEY_MASK_CMD) {
+ if ((p_keycode & KeyModifierMask::CMD) != Key::NONE) {
ie->set_command_pressed(true);
}
- if (p_keycode & KEY_MASK_META) {
+ if ((p_keycode & KeyModifierMask::META) != Key::NONE) {
ie->set_meta_pressed(true);
}
@@ -419,14 +419,14 @@ bool InputEventKey::action_match(const Ref<InputEvent> &p_event, bool *p_pressed
}
bool match = false;
- if (get_keycode() == 0) {
- uint32_t code = get_physical_keycode_with_modifiers();
- uint32_t event_code = key->get_physical_keycode_with_modifiers();
+ if (get_keycode() == Key::NONE) {
+ Key code = get_physical_keycode_with_modifiers();
+ Key event_code = key->get_physical_keycode_with_modifiers();
match = get_physical_keycode() == key->get_physical_keycode() && (!key->is_pressed() || (code & event_code) == code);
} else {
- uint32_t code = get_keycode_with_modifiers();
- uint32_t event_code = key->get_keycode_with_modifiers();
+ Key code = get_keycode_with_modifiers();
+ Key event_code = key->get_keycode_with_modifiers();
match = get_keycode() == key->get_keycode() && (!key->is_pressed() || (code & event_code) == code);
}
@@ -452,8 +452,13 @@ bool InputEventKey::is_match(const Ref<InputEvent> &p_event, bool p_exact_match)
return false;
}
- return keycode == key->keycode &&
- (!p_exact_match || get_modifiers_mask() == key->get_modifiers_mask());
+ if (keycode == Key::NONE) {
+ return physical_keycode == key->physical_keycode &&
+ (!p_exact_match || get_modifiers_mask() == key->get_modifiers_mask());
+ } else {
+ return keycode == key->keycode &&
+ (!p_exact_match || get_modifiers_mask() == key->get_modifiers_mask());
+ }
}
void InputEventKey::_bind_methods() {
@@ -482,12 +487,12 @@ void InputEventKey::_bind_methods() {
///////////////////////////////////
-void InputEventMouse::set_button_mask(int p_mask) {
+void InputEventMouse::set_button_mask(MouseButton p_mask) {
button_mask = p_mask;
emit_changed();
}
-int InputEventMouse::get_button_mask() const {
+MouseButton InputEventMouse::get_button_mask() const {
return button_mask;
}
@@ -611,7 +616,7 @@ bool InputEventMouseButton::is_match(const Ref<InputEvent> &p_event, bool p_exac
}
return button_index == mb->button_index &&
- (!p_exact_match || get_modifiers_mask() == mb->get_modifiers_mask());
+ (!p_exact_match || get_modifiers_mask() == mb->get_modifiers_mask());
}
static const char *_mouse_button_descriptions[9] = {
@@ -629,24 +634,24 @@ static const char *_mouse_button_descriptions[9] = {
String InputEventMouseButton::as_text() const {
// Modifiers
String mods_text = InputEventWithModifiers::as_text();
- String full_string = mods_text == "" ? "" : mods_text + "+";
+ String full_string = mods_text.is_empty() ? "" : mods_text + "+";
// Button
- int idx = get_button_index();
+ MouseButton idx = get_button_index();
switch (idx) {
- case MOUSE_BUTTON_LEFT:
- case MOUSE_BUTTON_RIGHT:
- case MOUSE_BUTTON_MIDDLE:
- case MOUSE_BUTTON_WHEEL_UP:
- case MOUSE_BUTTON_WHEEL_DOWN:
- case MOUSE_BUTTON_WHEEL_LEFT:
- case MOUSE_BUTTON_WHEEL_RIGHT:
- case MOUSE_BUTTON_XBUTTON1:
- case MOUSE_BUTTON_XBUTTON2:
- full_string += RTR(_mouse_button_descriptions[idx - 1]); // button index starts from 1, array index starts from 0, so subtract 1
+ case MouseButton::LEFT:
+ case MouseButton::RIGHT:
+ case MouseButton::MIDDLE:
+ case MouseButton::WHEEL_UP:
+ case MouseButton::WHEEL_DOWN:
+ case MouseButton::WHEEL_LEFT:
+ case MouseButton::WHEEL_RIGHT:
+ case MouseButton::MB_XBUTTON1:
+ case MouseButton::MB_XBUTTON2:
+ full_string += RTR(_mouse_button_descriptions[(size_t)idx - 1]); // button index starts from 1, array index starts from 0, so subtract 1
break;
default:
- full_string += RTR("Button") + " #" + itos(idx);
+ full_string += RTR("Button") + " #" + itos((int64_t)idx);
break;
}
@@ -662,27 +667,27 @@ String InputEventMouseButton::to_string() {
String p = is_pressed() ? "true" : "false";
String d = double_click ? "true" : "false";
- int idx = get_button_index();
- String button_string = itos(idx);
+ MouseButton idx = get_button_index();
+ String button_string = itos((int64_t)idx);
switch (idx) {
- case MOUSE_BUTTON_LEFT:
- case MOUSE_BUTTON_RIGHT:
- case MOUSE_BUTTON_MIDDLE:
- case MOUSE_BUTTON_WHEEL_UP:
- case MOUSE_BUTTON_WHEEL_DOWN:
- case MOUSE_BUTTON_WHEEL_LEFT:
- case MOUSE_BUTTON_WHEEL_RIGHT:
- case MOUSE_BUTTON_XBUTTON1:
- case MOUSE_BUTTON_XBUTTON2:
- button_string += " (" + RTR(_mouse_button_descriptions[idx - 1]) + ")"; // button index starts from 1, array index starts from 0, so subtract 1
+ case MouseButton::LEFT:
+ case MouseButton::RIGHT:
+ case MouseButton::MIDDLE:
+ case MouseButton::WHEEL_UP:
+ case MouseButton::WHEEL_DOWN:
+ case MouseButton::WHEEL_LEFT:
+ case MouseButton::WHEEL_RIGHT:
+ case MouseButton::MB_XBUTTON1:
+ case MouseButton::MB_XBUTTON2:
+ button_string += " (" + RTR(_mouse_button_descriptions[(size_t)idx - 1]) + ")"; // button index starts from 1, array index starts from 0, so subtract 1
break;
default:
break;
}
String mods = InputEventWithModifiers::as_text();
- mods = mods == "" ? TTR("none") : mods;
+ mods = mods.is_empty() ? TTR("none") : mods;
// Work around the fact vformat can only take 5 substitutions but 6 need to be passed.
String index_and_mods = vformat("button_index=%s, mods=%s", button_index, mods);
@@ -773,23 +778,23 @@ String InputEventMouseMotion::as_text() const {
}
String InputEventMouseMotion::to_string() {
- int button_mask = get_button_mask();
- String button_mask_string = itos(button_mask);
- switch (get_button_mask()) {
- case MOUSE_BUTTON_MASK_LEFT:
- button_mask_string += " (" + RTR(_mouse_button_descriptions[MOUSE_BUTTON_LEFT - 1]) + ")";
+ MouseButton button_mask = get_button_mask();
+ String button_mask_string = itos((int64_t)button_mask);
+ switch (button_mask) {
+ case MouseButton::MASK_LEFT:
+ button_mask_string += " (" + RTR(_mouse_button_descriptions[(size_t)MouseButton::LEFT - 1]) + ")";
break;
- case MOUSE_BUTTON_MASK_MIDDLE:
- button_mask_string += " (" + RTR(_mouse_button_descriptions[MOUSE_BUTTON_MIDDLE - 1]) + ")";
+ case MouseButton::MASK_MIDDLE:
+ button_mask_string += " (" + RTR(_mouse_button_descriptions[(size_t)MouseButton::MIDDLE - 1]) + ")";
break;
- case MOUSE_BUTTON_MASK_RIGHT:
- button_mask_string += " (" + RTR(_mouse_button_descriptions[MOUSE_BUTTON_RIGHT - 1]) + ")";
+ case MouseButton::MASK_RIGHT:
+ button_mask_string += " (" + RTR(_mouse_button_descriptions[(size_t)MouseButton::RIGHT - 1]) + ")";
break;
- case MOUSE_BUTTON_MASK_XBUTTON1:
- button_mask_string += " (" + RTR(_mouse_button_descriptions[MOUSE_BUTTON_XBUTTON1 - 1]) + ")";
+ case MouseButton::MASK_XBUTTON1:
+ button_mask_string += " (" + RTR(_mouse_button_descriptions[(size_t)MouseButton::MB_XBUTTON1 - 1]) + ")";
break;
- case MOUSE_BUTTON_MASK_XBUTTON2:
- button_mask_string += " (" + RTR(_mouse_button_descriptions[MOUSE_BUTTON_XBUTTON2 - 1]) + ")";
+ case MouseButton::MASK_XBUTTON2:
+ button_mask_string += " (" + RTR(_mouse_button_descriptions[(size_t)MouseButton::MB_XBUTTON2 - 1]) + ")";
break;
default:
break;
@@ -864,7 +869,7 @@ void InputEventMouseMotion::_bind_methods() {
///////////////////////////////////
void InputEventJoypadMotion::set_axis(JoyAxis p_axis) {
- ERR_FAIL_INDEX(p_axis, JOY_AXIS_MAX);
+ ERR_FAIL_COND(p_axis < JoyAxis::LEFT_X || p_axis > JoyAxis::MAX);
axis = p_axis;
emit_changed();
@@ -930,10 +935,10 @@ bool InputEventJoypadMotion::is_match(const Ref<InputEvent> &p_event, bool p_exa
}
return axis == jm->axis &&
- (!p_exact_match || ((axis_value < 0) == (jm->axis_value < 0)));
+ (!p_exact_match || ((axis_value < 0) == (jm->axis_value < 0)));
}
-static const char *_joy_axis_descriptions[JOY_AXIS_MAX] = {
+static const char *_joy_axis_descriptions[(size_t)JoyAxis::MAX] = {
TTRC("Left Stick X-Axis, Joystick 0 X-Axis"),
TTRC("Left Stick Y-Axis, Joystick 0 Y-Axis"),
TTRC("Right Stick X-Axis, Joystick 1 X-Axis"),
@@ -947,7 +952,7 @@ static const char *_joy_axis_descriptions[JOY_AXIS_MAX] = {
};
String InputEventJoypadMotion::as_text() const {
- String desc = axis < JOY_AXIS_MAX ? RTR(_joy_axis_descriptions[axis]) : TTR("Unknown Joypad Axis");
+ String desc = axis < JoyAxis::MAX ? RTR(_joy_axis_descriptions[(size_t)axis]) : TTR("Unknown Joypad Axis");
return vformat(TTR("Joypad Motion on Axis %d (%s) with Value %.2f"), axis, desc, axis_value);
}
@@ -1027,7 +1032,7 @@ bool InputEventJoypadButton::is_match(const Ref<InputEvent> &p_event, bool p_exa
return button_index == button->button_index;
}
-static const char *_joy_button_descriptions[JOY_BUTTON_SDL_MAX] = {
+static const char *_joy_button_descriptions[(size_t)JoyButton::SDL_MAX] = {
TTRC("Bottom Action, Sony Cross, Xbox A, Nintendo B"),
TTRC("Right Action, Sony Circle, Xbox B, Nintendo A"),
TTRC("Left Action, Sony Square, Xbox X, Nintendo Y"),
@@ -1052,10 +1057,10 @@ static const char *_joy_button_descriptions[JOY_BUTTON_SDL_MAX] = {
};
String InputEventJoypadButton::as_text() const {
- String text = "Joypad Button " + itos(button_index);
+ String text = "Joypad Button " + itos((int64_t)button_index);
- if (button_index >= 0 && button_index < JOY_BUTTON_SDL_MAX) {
- text += vformat(" (%s)", _joy_button_descriptions[button_index]);
+ if (button_index > JoyButton::INVALID && button_index < JoyButton::SDL_MAX) {
+ text += vformat(" (%s)", _joy_button_descriptions[(size_t)button_index]);
}
if (pressure != 0) {
@@ -1501,7 +1506,7 @@ int InputEventMIDI::get_controller_value() const {
}
String InputEventMIDI::as_text() const {
- return vformat(RTR("MIDI Input on Channel=%s Message=%s"), itos(channel), itos(message));
+ return vformat(RTR("MIDI Input on Channel=%s Message=%s"), itos(channel), itos((int64_t)message));
}
String InputEventMIDI::to_string() {
diff --git a/core/input/input_event.h b/core/input/input_event.h
index 3fc8078a09..70046e4491 100644
--- a/core/input/input_event.h
+++ b/core/input/input_event.h
@@ -151,7 +151,7 @@ public:
void set_modifiers_from_event(const InputEventWithModifiers *event);
- uint32_t get_modifiers_mask() const;
+ Key get_modifiers_mask() const;
virtual String as_text() const override;
virtual String to_string() override;
@@ -164,8 +164,8 @@ class InputEventKey : public InputEventWithModifiers {
bool pressed = false; /// otherwise release
- Key keycode = KEY_NONE; // Key enum, without modifier masks.
- Key physical_keycode = KEY_NONE;
+ Key keycode = Key::NONE; // Key enum, without modifier masks.
+ Key physical_keycode = Key::NONE;
uint32_t unicode = 0; ///unicode
bool echo = false; /// true if this is an echo key
@@ -183,14 +183,14 @@ public:
void set_physical_keycode(Key p_keycode);
Key get_physical_keycode() const;
- void set_unicode(uint32_t p_unicode);
- uint32_t get_unicode() const;
+ void set_unicode(char32_t p_unicode);
+ char32_t get_unicode() const;
void set_echo(bool p_enable);
virtual bool is_echo() const override;
- uint32_t get_keycode_with_modifiers() const;
- uint32_t get_physical_keycode_with_modifiers() const;
+ Key get_keycode_with_modifiers() const;
+ Key get_physical_keycode_with_modifiers() const;
virtual bool action_match(const Ref<InputEvent> &p_event, bool *p_pressed, float *p_strength, float *p_raw_strength, float p_deadzone) const override;
virtual bool is_match(const Ref<InputEvent> &p_event, bool p_exact_match = true) const override;
@@ -208,7 +208,7 @@ public:
class InputEventMouse : public InputEventWithModifiers {
GDCLASS(InputEventMouse, InputEventWithModifiers);
- int button_mask = 0;
+ MouseButton button_mask = MouseButton::NONE;
Vector2 pos;
Vector2 global_pos;
@@ -217,8 +217,8 @@ protected:
static void _bind_methods();
public:
- void set_button_mask(int p_mask);
- int get_button_mask() const;
+ void set_button_mask(MouseButton p_mask);
+ MouseButton get_button_mask() const;
void set_position(const Vector2 &p_pos);
Vector2 get_position() const;
@@ -233,7 +233,7 @@ class InputEventMouseButton : public InputEventMouse {
GDCLASS(InputEventMouseButton, InputEventMouse);
float factor = 1;
- MouseButton button_index = MOUSE_BUTTON_NONE;
+ MouseButton button_index = MouseButton::NONE;
bool pressed = false; //otherwise released
bool double_click = false; //last even less than double click time
@@ -501,7 +501,7 @@ class InputEventMIDI : public InputEvent {
GDCLASS(InputEventMIDI, InputEvent);
int channel = 0;
- MIDIMessage message = MIDI_MESSAGE_NONE;
+ MIDIMessage message = MIDIMessage::NONE;
int pitch = 0;
int velocity = 0;
int instrument = 0;
diff --git a/core/input/input_map.cpp b/core/input/input_map.cpp
index 1ec4299093..183a2c3e68 100644
--- a/core/input/input_map.cpp
+++ b/core/input/input_map.cpp
@@ -381,320 +381,320 @@ const OrderedHashMap<String, List<Ref<InputEvent>>> &InputMap::get_builtins() {
}
List<Ref<InputEvent>> inputs;
- inputs.push_back(InputEventKey::create_reference(KEY_ENTER));
- inputs.push_back(InputEventKey::create_reference(KEY_KP_ENTER));
- inputs.push_back(InputEventKey::create_reference(KEY_SPACE));
+ inputs.push_back(InputEventKey::create_reference(Key::ENTER));
+ inputs.push_back(InputEventKey::create_reference(Key::KP_ENTER));
+ inputs.push_back(InputEventKey::create_reference(Key::SPACE));
default_builtin_cache.insert("ui_accept", inputs);
inputs = List<Ref<InputEvent>>();
- inputs.push_back(InputEventJoypadButton::create_reference(JOY_BUTTON_Y));
- inputs.push_back(InputEventKey::create_reference(KEY_SPACE));
+ inputs.push_back(InputEventJoypadButton::create_reference(JoyButton::Y));
+ inputs.push_back(InputEventKey::create_reference(Key::SPACE));
default_builtin_cache.insert("ui_select", inputs);
inputs = List<Ref<InputEvent>>();
- inputs.push_back(InputEventKey::create_reference(KEY_ESCAPE));
+ inputs.push_back(InputEventKey::create_reference(Key::ESCAPE));
default_builtin_cache.insert("ui_cancel", inputs);
inputs = List<Ref<InputEvent>>();
- inputs.push_back(InputEventKey::create_reference(KEY_TAB));
+ inputs.push_back(InputEventKey::create_reference(Key::TAB));
default_builtin_cache.insert("ui_focus_next", inputs);
inputs = List<Ref<InputEvent>>();
- inputs.push_back(InputEventKey::create_reference(KEY_TAB | KEY_MASK_SHIFT));
+ inputs.push_back(InputEventKey::create_reference(Key::TAB | KeyModifierMask::SHIFT));
default_builtin_cache.insert("ui_focus_prev", inputs);
inputs = List<Ref<InputEvent>>();
- inputs.push_back(InputEventKey::create_reference(KEY_LEFT));
- inputs.push_back(InputEventJoypadButton::create_reference(JOY_BUTTON_DPAD_LEFT));
+ inputs.push_back(InputEventKey::create_reference(Key::LEFT));
+ inputs.push_back(InputEventJoypadButton::create_reference(JoyButton::DPAD_LEFT));
default_builtin_cache.insert("ui_left", inputs);
inputs = List<Ref<InputEvent>>();
- inputs.push_back(InputEventKey::create_reference(KEY_RIGHT));
- inputs.push_back(InputEventJoypadButton::create_reference(JOY_BUTTON_DPAD_RIGHT));
+ inputs.push_back(InputEventKey::create_reference(Key::RIGHT));
+ inputs.push_back(InputEventJoypadButton::create_reference(JoyButton::DPAD_RIGHT));
default_builtin_cache.insert("ui_right", inputs);
inputs = List<Ref<InputEvent>>();
- inputs.push_back(InputEventKey::create_reference(KEY_UP));
- inputs.push_back(InputEventJoypadButton::create_reference(JOY_BUTTON_DPAD_UP));
+ inputs.push_back(InputEventKey::create_reference(Key::UP));
+ inputs.push_back(InputEventJoypadButton::create_reference(JoyButton::DPAD_UP));
default_builtin_cache.insert("ui_up", inputs);
inputs = List<Ref<InputEvent>>();
- inputs.push_back(InputEventKey::create_reference(KEY_DOWN));
- inputs.push_back(InputEventJoypadButton::create_reference(JOY_BUTTON_DPAD_DOWN));
+ inputs.push_back(InputEventKey::create_reference(Key::DOWN));
+ inputs.push_back(InputEventJoypadButton::create_reference(JoyButton::DPAD_DOWN));
default_builtin_cache.insert("ui_down", inputs);
inputs = List<Ref<InputEvent>>();
- inputs.push_back(InputEventKey::create_reference(KEY_PAGEUP));
+ inputs.push_back(InputEventKey::create_reference(Key::PAGEUP));
default_builtin_cache.insert("ui_page_up", inputs);
inputs = List<Ref<InputEvent>>();
- inputs.push_back(InputEventKey::create_reference(KEY_PAGEDOWN));
+ inputs.push_back(InputEventKey::create_reference(Key::PAGEDOWN));
default_builtin_cache.insert("ui_page_down", inputs);
inputs = List<Ref<InputEvent>>();
- inputs.push_back(InputEventKey::create_reference(KEY_HOME));
+ inputs.push_back(InputEventKey::create_reference(Key::HOME));
default_builtin_cache.insert("ui_home", inputs);
inputs = List<Ref<InputEvent>>();
- inputs.push_back(InputEventKey::create_reference(KEY_END));
+ inputs.push_back(InputEventKey::create_reference(Key::END));
default_builtin_cache.insert("ui_end", inputs);
// ///// UI basic Shortcuts /////
inputs = List<Ref<InputEvent>>();
- inputs.push_back(InputEventKey::create_reference(KEY_X | KEY_MASK_CMD));
- inputs.push_back(InputEventKey::create_reference(KEY_DELETE | KEY_MASK_SHIFT));
+ inputs.push_back(InputEventKey::create_reference(Key::X | KeyModifierMask::CMD));
+ inputs.push_back(InputEventKey::create_reference(Key::KEY_DELETE | KeyModifierMask::SHIFT));
default_builtin_cache.insert("ui_cut", inputs);
inputs = List<Ref<InputEvent>>();
- inputs.push_back(InputEventKey::create_reference(KEY_C | KEY_MASK_CMD));
- inputs.push_back(InputEventKey::create_reference(KEY_INSERT | KEY_MASK_CMD));
+ inputs.push_back(InputEventKey::create_reference(Key::C | KeyModifierMask::CMD));
+ inputs.push_back(InputEventKey::create_reference(Key::INSERT | KeyModifierMask::CMD));
default_builtin_cache.insert("ui_copy", inputs);
inputs = List<Ref<InputEvent>>();
- inputs.push_back(InputEventKey::create_reference(KEY_V | KEY_MASK_CMD));
- inputs.push_back(InputEventKey::create_reference(KEY_INSERT | KEY_MASK_SHIFT));
+ inputs.push_back(InputEventKey::create_reference(Key::V | KeyModifierMask::CMD));
+ inputs.push_back(InputEventKey::create_reference(Key::INSERT | KeyModifierMask::SHIFT));
default_builtin_cache.insert("ui_paste", inputs);
inputs = List<Ref<InputEvent>>();
- inputs.push_back(InputEventKey::create_reference(KEY_Z | KEY_MASK_CMD));
+ inputs.push_back(InputEventKey::create_reference(Key::Z | KeyModifierMask::CMD));
default_builtin_cache.insert("ui_undo", inputs);
inputs = List<Ref<InputEvent>>();
- inputs.push_back(InputEventKey::create_reference(KEY_Z | KEY_MASK_CMD | KEY_MASK_SHIFT));
- inputs.push_back(InputEventKey::create_reference(KEY_Y | KEY_MASK_CMD));
+ inputs.push_back(InputEventKey::create_reference(Key::Z | KeyModifierMask::CMD | KeyModifierMask::SHIFT));
+ inputs.push_back(InputEventKey::create_reference(Key::Y | KeyModifierMask::CMD));
default_builtin_cache.insert("ui_redo", inputs);
// ///// UI Text Input Shortcuts /////
inputs = List<Ref<InputEvent>>();
- inputs.push_back(InputEventKey::create_reference(KEY_SPACE | KEY_MASK_CTRL));
+ inputs.push_back(InputEventKey::create_reference(Key::SPACE | KeyModifierMask::CTRL));
default_builtin_cache.insert("ui_text_completion_query", inputs);
inputs = List<Ref<InputEvent>>();
- inputs.push_back(InputEventKey::create_reference(KEY_ENTER));
- inputs.push_back(InputEventKey::create_reference(KEY_KP_ENTER));
+ inputs.push_back(InputEventKey::create_reference(Key::ENTER));
+ inputs.push_back(InputEventKey::create_reference(Key::KP_ENTER));
default_builtin_cache.insert("ui_text_completion_accept", inputs);
inputs = List<Ref<InputEvent>>();
- inputs.push_back(InputEventKey::create_reference(KEY_TAB));
+ inputs.push_back(InputEventKey::create_reference(Key::TAB));
default_builtin_cache.insert("ui_text_completion_replace", inputs);
// Newlines
inputs = List<Ref<InputEvent>>();
- inputs.push_back(InputEventKey::create_reference(KEY_ENTER));
- inputs.push_back(InputEventKey::create_reference(KEY_KP_ENTER));
+ inputs.push_back(InputEventKey::create_reference(Key::ENTER));
+ inputs.push_back(InputEventKey::create_reference(Key::KP_ENTER));
default_builtin_cache.insert("ui_text_newline", inputs);
inputs = List<Ref<InputEvent>>();
- inputs.push_back(InputEventKey::create_reference(KEY_ENTER | KEY_MASK_CMD));
- inputs.push_back(InputEventKey::create_reference(KEY_KP_ENTER | KEY_MASK_CMD));
+ inputs.push_back(InputEventKey::create_reference(Key::ENTER | KeyModifierMask::CMD));
+ inputs.push_back(InputEventKey::create_reference(Key::KP_ENTER | KeyModifierMask::CMD));
default_builtin_cache.insert("ui_text_newline_blank", inputs);
inputs = List<Ref<InputEvent>>();
- inputs.push_back(InputEventKey::create_reference(KEY_ENTER | KEY_MASK_SHIFT | KEY_MASK_CMD));
- inputs.push_back(InputEventKey::create_reference(KEY_KP_ENTER | KEY_MASK_SHIFT | KEY_MASK_CMD));
+ inputs.push_back(InputEventKey::create_reference(Key::ENTER | KeyModifierMask::SHIFT | KeyModifierMask::CMD));
+ inputs.push_back(InputEventKey::create_reference(Key::KP_ENTER | KeyModifierMask::SHIFT | KeyModifierMask::CMD));
default_builtin_cache.insert("ui_text_newline_above", inputs);
// Indentation
inputs = List<Ref<InputEvent>>();
- inputs.push_back(InputEventKey::create_reference(KEY_TAB));
+ inputs.push_back(InputEventKey::create_reference(Key::TAB));
default_builtin_cache.insert("ui_text_indent", inputs);
inputs = List<Ref<InputEvent>>();
- inputs.push_back(InputEventKey::create_reference(KEY_TAB | KEY_MASK_SHIFT));
+ inputs.push_back(InputEventKey::create_reference(Key::TAB | KeyModifierMask::SHIFT));
default_builtin_cache.insert("ui_text_dedent", inputs);
// Text Backspace and Delete
inputs = List<Ref<InputEvent>>();
- inputs.push_back(InputEventKey::create_reference(KEY_BACKSPACE));
- inputs.push_back(InputEventKey::create_reference(KEY_BACKSPACE | KEY_MASK_SHIFT));
+ inputs.push_back(InputEventKey::create_reference(Key::BACKSPACE));
+ inputs.push_back(InputEventKey::create_reference(Key::BACKSPACE | KeyModifierMask::SHIFT));
default_builtin_cache.insert("ui_text_backspace", inputs);
inputs = List<Ref<InputEvent>>();
- inputs.push_back(InputEventKey::create_reference(KEY_BACKSPACE | KEY_MASK_CMD));
+ inputs.push_back(InputEventKey::create_reference(Key::BACKSPACE | KeyModifierMask::CMD));
default_builtin_cache.insert("ui_text_backspace_word", inputs);
inputs = List<Ref<InputEvent>>();
- inputs.push_back(InputEventKey::create_reference(KEY_BACKSPACE | KEY_MASK_ALT));
+ inputs.push_back(InputEventKey::create_reference(Key::BACKSPACE | KeyModifierMask::ALT));
default_builtin_cache.insert("ui_text_backspace_word.macos", inputs);
inputs = List<Ref<InputEvent>>();
default_builtin_cache.insert("ui_text_backspace_all_to_left", inputs);
inputs = List<Ref<InputEvent>>();
- inputs.push_back(InputEventKey::create_reference(KEY_BACKSPACE | KEY_MASK_CMD));
+ inputs.push_back(InputEventKey::create_reference(Key::BACKSPACE | KeyModifierMask::CMD));
default_builtin_cache.insert("ui_text_backspace_all_to_left.macos", inputs);
inputs = List<Ref<InputEvent>>();
- inputs.push_back(InputEventKey::create_reference(KEY_DELETE));
+ inputs.push_back(InputEventKey::create_reference(Key::KEY_DELETE));
default_builtin_cache.insert("ui_text_delete", inputs);
inputs = List<Ref<InputEvent>>();
- inputs.push_back(InputEventKey::create_reference(KEY_DELETE | KEY_MASK_CMD));
+ inputs.push_back(InputEventKey::create_reference(Key::KEY_DELETE | KeyModifierMask::CMD));
default_builtin_cache.insert("ui_text_delete_word", inputs);
inputs = List<Ref<InputEvent>>();
- inputs.push_back(InputEventKey::create_reference(KEY_DELETE | KEY_MASK_ALT));
+ inputs.push_back(InputEventKey::create_reference(Key::KEY_DELETE | KeyModifierMask::ALT));
default_builtin_cache.insert("ui_text_delete_word.macos", inputs);
inputs = List<Ref<InputEvent>>();
default_builtin_cache.insert("ui_text_delete_all_to_right", inputs);
inputs = List<Ref<InputEvent>>();
- inputs.push_back(InputEventKey::create_reference(KEY_DELETE | KEY_MASK_CMD));
+ inputs.push_back(InputEventKey::create_reference(Key::KEY_DELETE | KeyModifierMask::CMD));
default_builtin_cache.insert("ui_text_delete_all_to_right.macos", inputs);
// Text Caret Movement Left/Right
inputs = List<Ref<InputEvent>>();
- inputs.push_back(InputEventKey::create_reference(KEY_LEFT));
+ inputs.push_back(InputEventKey::create_reference(Key::LEFT));
default_builtin_cache.insert("ui_text_caret_left", inputs);
inputs = List<Ref<InputEvent>>();
- inputs.push_back(InputEventKey::create_reference(KEY_LEFT | KEY_MASK_CMD));
+ inputs.push_back(InputEventKey::create_reference(Key::LEFT | KeyModifierMask::CMD));
default_builtin_cache.insert("ui_text_caret_word_left", inputs);
inputs = List<Ref<InputEvent>>();
- inputs.push_back(InputEventKey::create_reference(KEY_LEFT | KEY_MASK_ALT));
+ inputs.push_back(InputEventKey::create_reference(Key::LEFT | KeyModifierMask::ALT));
default_builtin_cache.insert("ui_text_caret_word_left.macos", inputs);
inputs = List<Ref<InputEvent>>();
- inputs.push_back(InputEventKey::create_reference(KEY_RIGHT));
+ inputs.push_back(InputEventKey::create_reference(Key::RIGHT));
default_builtin_cache.insert("ui_text_caret_right", inputs);
inputs = List<Ref<InputEvent>>();
- inputs.push_back(InputEventKey::create_reference(KEY_RIGHT | KEY_MASK_CMD));
+ inputs.push_back(InputEventKey::create_reference(Key::RIGHT | KeyModifierMask::CMD));
default_builtin_cache.insert("ui_text_caret_word_right", inputs);
inputs = List<Ref<InputEvent>>();
- inputs.push_back(InputEventKey::create_reference(KEY_RIGHT | KEY_MASK_ALT));
+ inputs.push_back(InputEventKey::create_reference(Key::RIGHT | KeyModifierMask::ALT));
default_builtin_cache.insert("ui_text_caret_word_right.macos", inputs);
// Text Caret Movement Up/Down
inputs = List<Ref<InputEvent>>();
- inputs.push_back(InputEventKey::create_reference(KEY_UP));
+ inputs.push_back(InputEventKey::create_reference(Key::UP));
default_builtin_cache.insert("ui_text_caret_up", inputs);
inputs = List<Ref<InputEvent>>();
- inputs.push_back(InputEventKey::create_reference(KEY_DOWN));
+ inputs.push_back(InputEventKey::create_reference(Key::DOWN));
default_builtin_cache.insert("ui_text_caret_down", inputs);
// Text Caret Movement Line Start/End
inputs = List<Ref<InputEvent>>();
- inputs.push_back(InputEventKey::create_reference(KEY_HOME));
+ inputs.push_back(InputEventKey::create_reference(Key::HOME));
default_builtin_cache.insert("ui_text_caret_line_start", inputs);
inputs = List<Ref<InputEvent>>();
- inputs.push_back(InputEventKey::create_reference(KEY_A | KEY_MASK_CTRL));
- inputs.push_back(InputEventKey::create_reference(KEY_LEFT | KEY_MASK_CMD));
+ inputs.push_back(InputEventKey::create_reference(Key::A | KeyModifierMask::CTRL));
+ inputs.push_back(InputEventKey::create_reference(Key::LEFT | KeyModifierMask::CMD));
default_builtin_cache.insert("ui_text_caret_line_start.macos", inputs);
inputs = List<Ref<InputEvent>>();
- inputs.push_back(InputEventKey::create_reference(KEY_END));
+ inputs.push_back(InputEventKey::create_reference(Key::END));
default_builtin_cache.insert("ui_text_caret_line_end", inputs);
inputs = List<Ref<InputEvent>>();
- inputs.push_back(InputEventKey::create_reference(KEY_E | KEY_MASK_CTRL));
- inputs.push_back(InputEventKey::create_reference(KEY_RIGHT | KEY_MASK_CMD));
+ inputs.push_back(InputEventKey::create_reference(Key::E | KeyModifierMask::CTRL));
+ inputs.push_back(InputEventKey::create_reference(Key::RIGHT | KeyModifierMask::CMD));
default_builtin_cache.insert("ui_text_caret_line_end.macos", inputs);
// Text Caret Movement Page Up/Down
inputs = List<Ref<InputEvent>>();
- inputs.push_back(InputEventKey::create_reference(KEY_PAGEUP));
+ inputs.push_back(InputEventKey::create_reference(Key::PAGEUP));
default_builtin_cache.insert("ui_text_caret_page_up", inputs);
inputs = List<Ref<InputEvent>>();
- inputs.push_back(InputEventKey::create_reference(KEY_PAGEDOWN));
+ inputs.push_back(InputEventKey::create_reference(Key::PAGEDOWN));
default_builtin_cache.insert("ui_text_caret_page_down", inputs);
// Text Caret Movement Document Start/End
inputs = List<Ref<InputEvent>>();
- inputs.push_back(InputEventKey::create_reference(KEY_HOME | KEY_MASK_CMD));
+ inputs.push_back(InputEventKey::create_reference(Key::HOME | KeyModifierMask::CMD));
default_builtin_cache.insert("ui_text_caret_document_start", inputs);
inputs = List<Ref<InputEvent>>();
- inputs.push_back(InputEventKey::create_reference(KEY_UP | KEY_MASK_CMD));
+ inputs.push_back(InputEventKey::create_reference(Key::UP | KeyModifierMask::CMD));
default_builtin_cache.insert("ui_text_caret_document_start.macos", inputs);
inputs = List<Ref<InputEvent>>();
- inputs.push_back(InputEventKey::create_reference(KEY_END | KEY_MASK_CMD));
+ inputs.push_back(InputEventKey::create_reference(Key::END | KeyModifierMask::CMD));
default_builtin_cache.insert("ui_text_caret_document_end", inputs);
inputs = List<Ref<InputEvent>>();
- inputs.push_back(InputEventKey::create_reference(KEY_DOWN | KEY_MASK_CMD));
+ inputs.push_back(InputEventKey::create_reference(Key::DOWN | KeyModifierMask::CMD));
default_builtin_cache.insert("ui_text_caret_document_end.macos", inputs);
// Text Scrolling
inputs = List<Ref<InputEvent>>();
- inputs.push_back(InputEventKey::create_reference(KEY_UP | KEY_MASK_CMD));
+ inputs.push_back(InputEventKey::create_reference(Key::UP | KeyModifierMask::CMD));
default_builtin_cache.insert("ui_text_scroll_up", inputs);
inputs = List<Ref<InputEvent>>();
- inputs.push_back(InputEventKey::create_reference(KEY_UP | KEY_MASK_CMD | KEY_MASK_ALT));
+ inputs.push_back(InputEventKey::create_reference(Key::UP | KeyModifierMask::CMD | KeyModifierMask::ALT));
default_builtin_cache.insert("ui_text_scroll_up.macos", inputs);
inputs = List<Ref<InputEvent>>();
- inputs.push_back(InputEventKey::create_reference(KEY_DOWN | KEY_MASK_CMD));
+ inputs.push_back(InputEventKey::create_reference(Key::DOWN | KeyModifierMask::CMD));
default_builtin_cache.insert("ui_text_scroll_down", inputs);
inputs = List<Ref<InputEvent>>();
- inputs.push_back(InputEventKey::create_reference(KEY_DOWN | KEY_MASK_CMD | KEY_MASK_ALT));
+ inputs.push_back(InputEventKey::create_reference(Key::DOWN | KeyModifierMask::CMD | KeyModifierMask::ALT));
default_builtin_cache.insert("ui_text_scroll_down.macos", inputs);
// Text Misc
inputs = List<Ref<InputEvent>>();
- inputs.push_back(InputEventKey::create_reference(KEY_A | KEY_MASK_CMD));
+ inputs.push_back(InputEventKey::create_reference(Key::A | KeyModifierMask::CMD));
default_builtin_cache.insert("ui_text_select_all", inputs);
inputs = List<Ref<InputEvent>>();
- inputs.push_back(InputEventKey::create_reference(KEY_D | KEY_MASK_CMD));
+ inputs.push_back(InputEventKey::create_reference(Key::D | KeyModifierMask::CMD));
default_builtin_cache.insert("ui_text_select_word_under_caret", inputs);
inputs = List<Ref<InputEvent>>();
- inputs.push_back(InputEventKey::create_reference(KEY_INSERT));
+ inputs.push_back(InputEventKey::create_reference(Key::INSERT));
default_builtin_cache.insert("ui_text_toggle_insert_mode", inputs);
inputs = List<Ref<InputEvent>>();
- inputs.push_back(InputEventKey::create_reference(KEY_MENU));
+ inputs.push_back(InputEventKey::create_reference(Key::MENU));
default_builtin_cache.insert("ui_menu", inputs);
inputs = List<Ref<InputEvent>>();
- inputs.push_back(InputEventKey::create_reference(KEY_ENTER));
- inputs.push_back(InputEventKey::create_reference(KEY_KP_ENTER));
+ inputs.push_back(InputEventKey::create_reference(Key::ENTER));
+ inputs.push_back(InputEventKey::create_reference(Key::KP_ENTER));
default_builtin_cache.insert("ui_text_submit", inputs);
// ///// UI Graph Shortcuts /////
inputs = List<Ref<InputEvent>>();
- inputs.push_back(InputEventKey::create_reference(KEY_D | KEY_MASK_CMD));
+ inputs.push_back(InputEventKey::create_reference(Key::D | KeyModifierMask::CMD));
default_builtin_cache.insert("ui_graph_duplicate", inputs);
inputs = List<Ref<InputEvent>>();
- inputs.push_back(InputEventKey::create_reference(KEY_DELETE));
+ inputs.push_back(InputEventKey::create_reference(Key::KEY_DELETE));
default_builtin_cache.insert("ui_graph_delete", inputs);
// ///// UI File Dialog Shortcuts /////
inputs = List<Ref<InputEvent>>();
- inputs.push_back(InputEventKey::create_reference(KEY_BACKSPACE));
+ inputs.push_back(InputEventKey::create_reference(Key::BACKSPACE));
default_builtin_cache.insert("ui_filedialog_up_one_level", inputs);
inputs = List<Ref<InputEvent>>();
- inputs.push_back(InputEventKey::create_reference(KEY_F5));
+ inputs.push_back(InputEventKey::create_reference(Key::F5));
default_builtin_cache.insert("ui_filedialog_refresh", inputs);
inputs = List<Ref<InputEvent>>();
- inputs.push_back(InputEventKey::create_reference(KEY_H));
+ inputs.push_back(InputEventKey::create_reference(Key::H));
default_builtin_cache.insert("ui_filedialog_show_hidden", inputs);
inputs = List<Ref<InputEvent>>();
- inputs.push_back(InputEventKey::create_reference(KEY_QUOTELEFT | KEY_MASK_CMD));
+ inputs.push_back(InputEventKey::create_reference(Key::QUOTELEFT | KeyModifierMask::CMD));
default_builtin_cache.insert("ui_swap_input_direction", inputs);
return default_builtin_cache;
@@ -718,7 +718,7 @@ const OrderedHashMap<String, List<Ref<InputEvent>>> &InputMap::get_builtins_with
String name = split[0];
String override_for = split.size() > 1 ? split[1] : String();
- if (override_for != String() && OS::get_singleton()->has_feature(override_for)) {
+ if (!override_for.is_empty() && OS::get_singleton()->has_feature(override_for)) {
builtins_with_overrides[name].push_back(override_for);
}
}
@@ -730,12 +730,12 @@ const OrderedHashMap<String, List<Ref<InputEvent>>> &InputMap::get_builtins_with
String name = split[0];
String override_for = split.size() > 1 ? split[1] : String();
- if (builtins_with_overrides.has(name) && override_for == String()) {
+ if (builtins_with_overrides.has(name) && override_for.is_empty()) {
// Builtin has an override but this particular one is not an override, so skip.
continue;
}
- if (override_for != String() && !OS::get_singleton()->has_feature(override_for)) {
+ if (!override_for.is_empty() && !OS::get_singleton()->has_feature(override_for)) {
// OS does not support this override - skip.
continue;
}
diff --git a/core/input/input_map.h b/core/input/input_map.h
index 8bef722089..0bf572ddca 100644
--- a/core/input/input_map.h
+++ b/core/input/input_map.h
@@ -41,8 +41,8 @@ class InputMap : public Object {
public:
/**
- * A special value used to signify that a given Action can be triggered by any device
- */
+ * A special value used to signify that a given Action can be triggered by any device
+ */
static int ALL_DEVICES;
struct Action {
diff --git a/core/io/compression.h b/core/io/compression.h
index cbfed74124..06f26876e5 100644
--- a/core/io/compression.h
+++ b/core/io/compression.h
@@ -54,8 +54,6 @@ public:
static int get_max_compressed_buffer_size(int p_src_size, Mode p_mode = MODE_ZSTD);
static int decompress(uint8_t *p_dst, int p_dst_max_size, const uint8_t *p_src, int p_src_size, Mode p_mode = MODE_ZSTD);
static int decompress_dynamic(Vector<uint8_t> *p_dst_vect, int p_max_dst_size, const uint8_t *p_src, int p_src_size, Mode p_mode);
-
- Compression() {}
};
#endif // COMPRESSION_H
diff --git a/core/io/config_file.cpp b/core/io/config_file.cpp
index 49fa73dab2..b2300574f8 100644
--- a/core/io/config_file.cpp
+++ b/core/io/config_file.cpp
@@ -183,7 +183,9 @@ Error ConfigFile::_internal_save(FileAccess *file) {
if (E != values.front()) {
file->store_string("\n");
}
- file->store_string("[" + E.key() + "]\n\n");
+ if (!E.key().is_empty()) {
+ file->store_string("[" + E.key() + "]\n\n");
+ }
for (OrderedHashMap<String, Variant>::Element F = E.get().front(); F; F = F.next()) {
String vstr;
@@ -285,9 +287,9 @@ Error ConfigFile::_parse(const String &p_path, VariantParser::Stream *p_stream)
return err;
}
- if (assign != String()) {
+ if (!assign.is_empty()) {
set_value(section, assign, value);
- } else if (next_tag.name != String()) {
+ } else if (!next_tag.name.is_empty()) {
section = next_tag.name;
}
}
diff --git a/core/io/dir_access.cpp b/core/io/dir_access.cpp
index 3bff0a3fd5..d804e67493 100644
--- a/core/io/dir_access.cpp
+++ b/core/io/dir_access.cpp
@@ -79,7 +79,7 @@ static Error _erase_recursive(DirAccess *da) {
da->list_dir_begin();
String n = da->get_next();
- while (n != String()) {
+ while (!n.is_empty()) {
if (n != "." && n != "..") {
if (da->current_is_dir()) {
dirs.push_back(n);
@@ -183,7 +183,7 @@ String DirAccess::fix_path(String p_path) const {
if (ProjectSettings::get_singleton()) {
if (p_path.begins_with("res://")) {
String resource_path = ProjectSettings::get_singleton()->get_resource_path();
- if (resource_path != "") {
+ if (!resource_path.is_empty()) {
return p_path.replace_first("res:/", resource_path);
}
return p_path.replace_first("res://", "");
@@ -194,7 +194,7 @@ String DirAccess::fix_path(String p_path) const {
case ACCESS_USERDATA: {
if (p_path.begins_with("user://")) {
String data_dir = OS::get_singleton()->get_user_data_dir();
- if (data_dir != "") {
+ if (!data_dir.is_empty()) {
return p_path.replace_first("user:/", data_dir);
}
return p_path.replace_first("user://", "");
@@ -337,7 +337,7 @@ Error DirAccess::_copy_dir(DirAccess *p_target_da, String p_to, int p_chmod_flag
String curdir = get_current_dir();
list_dir_begin();
String n = get_next();
- while (n != String()) {
+ while (!n.is_empty()) {
if (n != "." && n != "..") {
if (p_copy_links && is_link(get_current_dir().plus_file(n))) {
create_link(read_link(get_current_dir().plus_file(n)), p_to + n);
diff --git a/core/io/file_access.cpp b/core/io/file_access.cpp
index e6e79dff8a..1b9c43b155 100644
--- a/core/io/file_access.cpp
+++ b/core/io/file_access.cpp
@@ -127,7 +127,7 @@ String FileAccess::fix_path(const String &p_path) const {
if (ProjectSettings::get_singleton()) {
if (r_path.begins_with("res://")) {
String resource_path = ProjectSettings::get_singleton()->get_resource_path();
- if (resource_path != "") {
+ if (!resource_path.is_empty()) {
return r_path.replace("res:/", resource_path);
}
return r_path.replace("res://", "");
@@ -138,7 +138,7 @@ String FileAccess::fix_path(const String &p_path) const {
case ACCESS_USERDATA: {
if (r_path.begins_with("user://")) {
String data_dir = OS::get_singleton()->get_user_data_dir();
- if (data_dir != "") {
+ if (!data_dir.is_empty()) {
return r_path.replace("user:/", data_dir);
}
return r_path.replace("user://", "");
diff --git a/core/io/file_access_pack.cpp b/core/io/file_access_pack.cpp
index b2832b2a75..e343706e66 100644
--- a/core/io/file_access_pack.cpp
+++ b/core/io/file_access_pack.cpp
@@ -459,7 +459,7 @@ PackedData::PackedDir *DirAccessPack::_find_dir(String p_dir) {
nd = nd.simplify_path();
- if (nd == "") {
+ if (nd.is_empty()) {
nd = ".";
}
diff --git a/core/io/http_client.cpp b/core/io/http_client.cpp
index 5c1352c1b6..5c67bc4c48 100644
--- a/core/io/http_client.cpp
+++ b/core/io/http_client.cpp
@@ -49,6 +49,14 @@ HTTPClient *HTTPClient::create() {
return nullptr;
}
+void HTTPClient::set_http_proxy(const String &p_host, int p_port) {
+ WARN_PRINT("HTTP proxy feature is not available");
+}
+
+void HTTPClient::set_https_proxy(const String &p_host, int p_port) {
+ WARN_PRINT("HTTPS proxy feature is not available");
+}
+
Error HTTPClient::_request_raw(Method p_method, const String &p_url, const Vector<String> &p_headers, const Vector<uint8_t> &p_body) {
int size = p_body.size();
return request(p_method, p_url, p_headers, size > 0 ? p_body.ptr() : nullptr, size);
@@ -85,8 +93,7 @@ String HTTPClient::query_string_from_dict(const Dictionary &p_dict) {
}
}
}
- query.erase(0, 1);
- return query;
+ return query.substr(1);
}
Dictionary HTTPClient::_get_response_headers_as_dictionary() {
@@ -143,6 +150,9 @@ void HTTPClient::_bind_methods() {
ClassDB::bind_method(D_METHOD("get_status"), &HTTPClient::get_status);
ClassDB::bind_method(D_METHOD("poll"), &HTTPClient::poll);
+ ClassDB::bind_method(D_METHOD("set_http_proxy", "host", "port"), &HTTPClient::set_http_proxy);
+ ClassDB::bind_method(D_METHOD("set_https_proxy", "host", "port"), &HTTPClient::set_https_proxy);
+
ClassDB::bind_method(D_METHOD("query_string_from_dict", "fields"), &HTTPClient::query_string_from_dict);
ADD_PROPERTY(PropertyInfo(Variant::BOOL, "blocking_mode_enabled"), "set_blocking_mode", "is_blocking_mode_enabled");
diff --git a/core/io/http_client.h b/core/io/http_client.h
index 718c3a905e..9bc0134a6a 100644
--- a/core/io/http_client.h
+++ b/core/io/http_client.h
@@ -192,6 +192,10 @@ public:
virtual Error poll() = 0;
+ // Use empty string or -1 to unset
+ virtual void set_http_proxy(const String &p_host, int p_port);
+ virtual void set_https_proxy(const String &p_host, int p_port);
+
HTTPClient() {}
virtual ~HTTPClient() {}
};
diff --git a/core/io/http_client_tcp.cpp b/core/io/http_client_tcp.cpp
index b3d35b3603..f2ddeddbb8 100644
--- a/core/io/http_client_tcp.cpp
+++ b/core/io/http_client_tcp.cpp
@@ -70,9 +70,21 @@ Error HTTPClientTCP::connect_to_host(const String &p_host, int p_port, bool p_ss
connection = tcp_connection;
- if (conn_host.is_valid_ip_address()) {
+ if (ssl && https_proxy_port != -1) {
+ proxy_client.instantiate(); // Needs proxy negotiation
+ server_host = https_proxy_host;
+ server_port = https_proxy_port;
+ } else if (!ssl && http_proxy_port != -1) {
+ server_host = http_proxy_host;
+ server_port = http_proxy_port;
+ } else {
+ server_host = conn_host;
+ server_port = conn_port;
+ }
+
+ if (server_host.is_valid_ip_address()) {
// Host contains valid IP
- Error err = tcp_connection->connect_to_host(IPAddress(conn_host), p_port);
+ Error err = tcp_connection->connect_to_host(IPAddress(server_host), server_port);
if (err) {
status = STATUS_CANT_CONNECT;
return err;
@@ -81,7 +93,7 @@ Error HTTPClientTCP::connect_to_host(const String &p_host, int p_port, bool p_ss
status = STATUS_CONNECTING;
} else {
// Host contains hostname and needs to be resolved to IP
- resolving = IP::get_singleton()->resolve_hostname_queue_item(conn_host);
+ resolving = IP::get_singleton()->resolve_hostname_queue_item(server_host);
status = STATUS_RESOLVING;
}
@@ -134,7 +146,12 @@ Error HTTPClientTCP::request(Method p_method, const String &p_url, const Vector<
ERR_FAIL_COND_V(status != STATUS_CONNECTED, ERR_INVALID_PARAMETER);
ERR_FAIL_COND_V(connection.is_null(), ERR_INVALID_DATA);
- String request = String(_methods[p_method]) + " " + p_url + " HTTP/1.1\r\n";
+ String uri = p_url;
+ if (!ssl && http_proxy_port != -1) {
+ uri = vformat("http://%s:%d%s", conn_host, conn_port, p_url);
+ }
+
+ String request = String(_methods[p_method]) + " " + uri + " HTTP/1.1\r\n";
bool add_host = true;
bool add_clen = p_body_size > 0;
bool add_uagent = true;
@@ -229,6 +246,7 @@ void HTTPClientTCP::close() {
}
connection.unref();
+ proxy_client.unref();
status = STATUS_DISCONNECTED;
head_request = false;
if (resolving != IP::RESOLVER_INVALID_ID) {
@@ -265,7 +283,7 @@ Error HTTPClientTCP::poll() {
Error err = ERR_BUG; // Should be at least one entry.
while (ip_candidates.size() > 0) {
- err = tcp_connection->connect_to_host(ip_candidates.front(), conn_port);
+ err = tcp_connection->connect_to_host(ip_candidates.pop_front(), server_port);
if (err == OK) {
break;
}
@@ -294,7 +312,48 @@ Error HTTPClientTCP::poll() {
return OK;
} break;
case StreamPeerTCP::STATUS_CONNECTED: {
- if (ssl) {
+ if (ssl && proxy_client.is_valid()) {
+ Error err = proxy_client->poll();
+ if (err == ERR_UNCONFIGURED) {
+ proxy_client->set_connection(tcp_connection);
+ const Vector<String> headers;
+ err = proxy_client->request(METHOD_CONNECT, vformat("%s:%d", conn_host, conn_port), headers, nullptr, 0);
+ if (err != OK) {
+ status = STATUS_CANT_CONNECT;
+ return err;
+ }
+ } else if (err != OK) {
+ status = STATUS_CANT_CONNECT;
+ return err;
+ }
+ switch (proxy_client->get_status()) {
+ case STATUS_REQUESTING: {
+ return OK;
+ } break;
+ case STATUS_BODY: {
+ proxy_client->read_response_body_chunk();
+ return OK;
+ } break;
+ case STATUS_CONNECTED: {
+ if (proxy_client->get_response_code() != RESPONSE_OK) {
+ status = STATUS_CANT_CONNECT;
+ return ERR_CANT_CONNECT;
+ }
+ proxy_client.unref();
+ return OK;
+ }
+ case STATUS_DISCONNECTED:
+ case STATUS_RESOLVING:
+ case STATUS_CONNECTING: {
+ status = STATUS_CANT_CONNECT;
+ ERR_FAIL_V(ERR_BUG);
+ } break;
+ default: {
+ status = STATUS_CANT_CONNECT;
+ return ERR_CANT_CONNECT;
+ } break;
+ }
+ } else if (ssl) {
Ref<StreamPeerSSL> ssl;
if (!handshaking) {
// Connect the StreamPeerSSL and start handshaking
@@ -344,7 +403,7 @@ Error HTTPClientTCP::poll() {
Error err = ERR_CANT_CONNECT;
while (ip_candidates.size() > 0) {
tcp_connection->disconnect_from_host();
- err = tcp_connection->connect_to_host(ip_candidates.pop_front(), conn_port);
+ err = tcp_connection->connect_to_host(ip_candidates.pop_front(), server_port);
if (err == OK) {
return OK;
}
@@ -678,6 +737,26 @@ int HTTPClientTCP::get_read_chunk_size() const {
return read_chunk_size;
}
+void HTTPClientTCP::set_http_proxy(const String &p_host, int p_port) {
+ if (p_host.is_empty() || p_port == -1) {
+ http_proxy_host = "";
+ http_proxy_port = -1;
+ } else {
+ http_proxy_host = p_host;
+ http_proxy_port = p_port;
+ }
+}
+
+void HTTPClientTCP::set_https_proxy(const String &p_host, int p_port) {
+ if (p_host.is_empty() || p_port == -1) {
+ https_proxy_host = "";
+ https_proxy_port = -1;
+ } else {
+ https_proxy_host = p_host;
+ https_proxy_port = p_port;
+ }
+}
+
HTTPClientTCP::HTTPClientTCP() {
tcp_connection.instantiate();
}
diff --git a/core/io/http_client_tcp.h b/core/io/http_client_tcp.h
index 170afb551c..40a962925e 100644
--- a/core/io/http_client_tcp.h
+++ b/core/io/http_client_tcp.h
@@ -38,8 +38,14 @@ private:
Status status = STATUS_DISCONNECTED;
IP::ResolverID resolving = IP::RESOLVER_INVALID_ID;
Array ip_candidates;
- int conn_port = -1;
+ int conn_port = -1; // Server to make requests to
String conn_host;
+ int server_port = -1; // Server to connect to (might be a proxy server)
+ String server_host;
+ int http_proxy_port = -1; // Proxy server for http requests
+ String http_proxy_host;
+ int https_proxy_port = -1; // Proxy server for https requests
+ String https_proxy_host;
bool ssl = false;
bool ssl_verify_host = false;
bool blocking = false;
@@ -58,6 +64,7 @@ private:
Ref<StreamPeerTCP> tcp_connection;
Ref<StreamPeer> connection;
+ Ref<HTTPClientTCP> proxy_client; // Negotiate with proxy server
int response_num = 0;
Vector<String> response_headers;
@@ -87,6 +94,8 @@ public:
void set_read_chunk_size(int p_size) override;
int get_read_chunk_size() const override;
Error poll() override;
+ void set_http_proxy(const String &p_host, int p_port) override;
+ void set_https_proxy(const String &p_host, int p_port) override;
HTTPClientTCP();
};
diff --git a/core/io/image.cpp b/core/io/image.cpp
index c70f4b86bd..3f34de132f 100644
--- a/core/io/image.cpp
+++ b/core/io/image.cpp
@@ -86,20 +86,14 @@ SaveEXRFunc Image::save_exr_func = nullptr;
SavePNGBufferFunc Image::save_png_buffer_func = nullptr;
-void Image::_put_pixelb(int p_x, int p_y, uint32_t p_pixelsize, uint8_t *p_data, const uint8_t *p_pixel) {
- uint32_t ofs = (p_y * width + p_x) * p_pixelsize;
-
- for (uint32_t i = 0; i < p_pixelsize; i++) {
- p_data[ofs + i] = p_pixel[i];
- }
+void Image::_put_pixelb(int p_x, int p_y, uint32_t p_pixel_size, uint8_t *p_data, const uint8_t *p_pixel) {
+ uint32_t ofs = (p_y * width + p_x) * p_pixel_size;
+ memcpy(p_data + ofs, p_pixel, p_pixel_size);
}
-void Image::_get_pixelb(int p_x, int p_y, uint32_t p_pixelsize, const uint8_t *p_data, uint8_t *p_pixel) {
- uint32_t ofs = (p_y * width + p_x) * p_pixelsize;
-
- for (uint32_t i = 0; i < p_pixelsize; i++) {
- p_pixel[i] = p_data[ofs + i];
- }
+void Image::_get_pixelb(int p_x, int p_y, uint32_t p_pixel_size, const uint8_t *p_data, uint8_t *p_pixel) {
+ uint32_t ofs = (p_y * width + p_x) * p_pixel_size;
+ memcpy(p_pixel, p_data + ofs, p_pixel_size);
}
int Image::get_format_pixel_size(Format p_format) {
@@ -797,7 +791,7 @@ static void _scale_bilinear(const uint8_t *__restrict p_src, uint8_t *__restrict
uint32_t interp_down = p01 + (((p11 - p01) * src_xofs_frac) >> FRAC_BITS);
uint32_t interp = interp_up + (((interp_down - interp_up) * src_yofs_frac) >> FRAC_BITS);
interp >>= FRAC_BITS;
- p_dst[i * p_dst_width * CC + j * CC + l] = interp;
+ p_dst[i * p_dst_width * CC + j * CC + l] = uint8_t(interp);
} else if (sizeof(T) == 2) { //half float
float xofs_frac = float(src_xofs_frac) / (1 << FRAC_BITS);
@@ -2697,24 +2691,55 @@ void Image::blend_rect_mask(const Ref<Image> &p_src, const Ref<Image> &p_mask, c
}
}
-void Image::fill(const Color &c) {
+// Repeats `p_pixel` `p_count` times in consecutive memory.
+// Results in the original pixel and `p_count - 1` subsequent copies of it.
+void Image::_repeat_pixel_over_subsequent_memory(uint8_t *p_pixel, int p_pixel_size, int p_count) {
+ int offset = 1;
+ for (int stride = 1; offset + stride <= p_count; stride *= 2) {
+ memcpy(p_pixel + offset * p_pixel_size, p_pixel, stride * p_pixel_size);
+ offset += stride;
+ }
+ if (offset < p_count) {
+ memcpy(p_pixel + offset * p_pixel_size, p_pixel, (p_count - offset) * p_pixel_size);
+ }
+}
+
+void Image::fill(const Color &p_color) {
ERR_FAIL_COND_MSG(!_can_modify(format), "Cannot fill in compressed or custom image formats.");
- uint8_t *wp = data.ptrw();
- uint8_t *dst_data_ptr = wp;
+ uint8_t *dst_data_ptr = data.ptrw();
int pixel_size = get_format_pixel_size(format);
- // put first pixel with the format-aware API
- set_pixel(0, 0, c);
+ // Put first pixel with the format-aware API.
+ _set_color_at_ofs(dst_data_ptr, 0, p_color);
- for (int y = 0; y < height; y++) {
- for (int x = 0; x < width; x++) {
- uint8_t *dst = &dst_data_ptr[(y * width + x) * pixel_size];
+ _repeat_pixel_over_subsequent_memory(dst_data_ptr, pixel_size, width * height);
+}
- for (int k = 0; k < pixel_size; k++) {
- dst[k] = dst_data_ptr[k];
- }
+void Image::fill_rect(const Rect2 &p_rect, const Color &p_color) {
+ ERR_FAIL_COND_MSG(!_can_modify(format), "Cannot fill rect in compressed or custom image formats.");
+
+ Rect2i r = Rect2i(0, 0, width, height).intersection(p_rect.abs());
+ if (r.has_no_area()) {
+ return;
+ }
+
+ uint8_t *dst_data_ptr = data.ptrw();
+
+ int pixel_size = get_format_pixel_size(format);
+
+ // Put first pixel with the format-aware API.
+ uint8_t *rect_first_pixel_ptr = &dst_data_ptr[(r.position.y * width + r.position.x) * pixel_size];
+ _set_color_at_ofs(rect_first_pixel_ptr, 0, p_color);
+
+ if (r.size.x == width) {
+ // No need to fill rows separately.
+ _repeat_pixel_over_subsequent_memory(rect_first_pixel_ptr, pixel_size, width * r.size.y);
+ } else {
+ _repeat_pixel_over_subsequent_memory(rect_first_pixel_ptr, pixel_size, r.size.x);
+ for (int y = 1; y < r.size.y; y++) {
+ memcpy(rect_first_pixel_ptr + y * width * pixel_size, rect_first_pixel_ptr, r.size.x * pixel_size);
}
}
}
@@ -3160,6 +3185,7 @@ void Image::_bind_methods() {
ClassDB::bind_method(D_METHOD("blend_rect", "src", "src_rect", "dst"), &Image::blend_rect);
ClassDB::bind_method(D_METHOD("blend_rect_mask", "src", "mask", "src_rect", "dst"), &Image::blend_rect_mask);
ClassDB::bind_method(D_METHOD("fill", "color"), &Image::fill);
+ ClassDB::bind_method(D_METHOD("fill_rect", "rect", "color"), &Image::fill_rect);
ClassDB::bind_method(D_METHOD("get_used_rect"), &Image::get_used_rect);
ClassDB::bind_method(D_METHOD("get_rect", "rect"), &Image::get_rect);
diff --git a/core/io/image.h b/core/io/image.h
index 8f1b251ac3..9023463b08 100644
--- a/core/io/image.h
+++ b/core/io/image.h
@@ -41,7 +41,7 @@
* Image storage class. This is used to store an image in user memory, as well as
* providing some basic methods for image manipulation.
* Images can be loaded from a file, or registered into the Render object as textures.
-*/
+ */
class Image;
@@ -190,8 +190,10 @@ private:
static int _get_dst_image_size(int p_width, int p_height, Format p_format, int &r_mipmaps, int p_mipmaps = -1, int *r_mm_width = nullptr, int *r_mm_height = nullptr);
bool _can_modify(Format p_format) const;
- _FORCE_INLINE_ void _put_pixelb(int p_x, int p_y, uint32_t p_pixelsize, uint8_t *p_data, const uint8_t *p_pixel);
- _FORCE_INLINE_ void _get_pixelb(int p_x, int p_y, uint32_t p_pixelsize, const uint8_t *p_data, uint8_t *p_pixel);
+ _FORCE_INLINE_ void _put_pixelb(int p_x, int p_y, uint32_t p_pixel_size, uint8_t *p_data, const uint8_t *p_pixel);
+ _FORCE_INLINE_ void _get_pixelb(int p_x, int p_y, uint32_t p_pixel_size, const uint8_t *p_data, uint8_t *p_pixel);
+
+ _FORCE_INLINE_ void _repeat_pixel_over_subsequent_memory(uint8_t *p_pixel, int p_pixel_size, int p_count);
void _set_data(const Dictionary &p_data);
Dictionary _get_data() const;
@@ -362,7 +364,8 @@ public:
void blit_rect_mask(const Ref<Image> &p_src, const Ref<Image> &p_mask, const Rect2 &p_src_rect, const Point2 &p_dest);
void blend_rect(const Ref<Image> &p_src, const Rect2 &p_src_rect, const Point2 &p_dest);
void blend_rect_mask(const Ref<Image> &p_src, const Ref<Image> &p_mask, const Rect2 &p_src_rect, const Point2 &p_dest);
- void fill(const Color &c);
+ void fill(const Color &p_color);
+ void fill_rect(const Rect2 &p_rect, const Color &p_color);
Rect2 get_used_rect() const;
Ref<Image> get_rect(const Rect2 &p_area) const;
diff --git a/core/io/logger.cpp b/core/io/logger.cpp
index 09539f716c..3330bb8149 100644
--- a/core/io/logger.cpp
+++ b/core/io/logger.cpp
@@ -50,7 +50,7 @@ void Logger::set_flush_stdout_on_print(bool value) {
_flush_stdout_on_print = value;
}
-void Logger::log_error(const char *p_function, const char *p_file, int p_line, const char *p_code, const char *p_rationale, ErrorType p_type) {
+void Logger::log_error(const char *p_function, const char *p_file, int p_line, const char *p_code, const char *p_rationale, bool p_editor_notify, ErrorType p_type) {
if (!should_log(true)) {
return;
}
@@ -81,7 +81,11 @@ void Logger::log_error(const char *p_function, const char *p_file, int p_line, c
err_details = p_code;
}
- logf_error("%s: %s\n", err_type, err_details);
+ if (p_editor_notify) {
+ logf_error("%s: %s\n", err_type, err_details);
+ } else {
+ logf_error("USER %s: %s\n", err_type, err_details);
+ }
logf_error(" at: %s (%s:%i) - %s\n", p_function, p_file, p_line, p_code);
}
@@ -132,7 +136,7 @@ void RotatedFileLogger::clear_old_backups() {
da->list_dir_begin();
String f = da->get_next();
Set<String> backups;
- while (f != String()) {
+ while (!f.is_empty()) {
if (!da->current_is_dir() && f.begins_with(basename) && f.get_extension() == extension && f != base_path.get_file()) {
backups.insert(f);
}
@@ -159,7 +163,7 @@ void RotatedFileLogger::rotate_file() {
if (max_files > 1) {
String timestamp = Time::get_singleton()->get_datetime_string_from_system().replace(":", ".");
String backup_name = base_path.get_basename() + timestamp;
- if (base_path.get_extension() != String()) {
+ if (!base_path.get_extension().is_empty()) {
backup_name += "." + base_path.get_extension();
}
@@ -256,13 +260,13 @@ void CompositeLogger::logv(const char *p_format, va_list p_list, bool p_err) {
}
}
-void CompositeLogger::log_error(const char *p_function, const char *p_file, int p_line, const char *p_code, const char *p_rationale, ErrorType p_type) {
+void CompositeLogger::log_error(const char *p_function, const char *p_file, int p_line, const char *p_code, const char *p_rationale, bool p_editor_notify, ErrorType p_type) {
if (!should_log(true)) {
return;
}
for (int i = 0; i < loggers.size(); ++i) {
- loggers[i]->log_error(p_function, p_file, p_line, p_code, p_rationale, p_type);
+ loggers[i]->log_error(p_function, p_file, p_line, p_code, p_rationale, p_editor_notify, p_type);
}
}
diff --git a/core/io/logger.h b/core/io/logger.h
index ccf68562d6..48b073aa45 100644
--- a/core/io/logger.h
+++ b/core/io/logger.h
@@ -54,7 +54,7 @@ public:
static void set_flush_stdout_on_print(bool value);
virtual void logv(const char *p_format, va_list p_list, bool p_err) _PRINTF_FORMAT_ATTRIBUTE_2_0 = 0;
- virtual void log_error(const char *p_function, const char *p_file, int p_line, const char *p_code, const char *p_rationale, ErrorType p_type = ERR_ERROR);
+ virtual void log_error(const char *p_function, const char *p_file, int p_line, const char *p_code, const char *p_rationale, bool p_editor_notify = false, ErrorType p_type = ERR_ERROR);
void logf(const char *p_format, ...) _PRINTF_FORMAT_ATTRIBUTE_2_3;
void logf_error(const char *p_format, ...) _PRINTF_FORMAT_ATTRIBUTE_2_3;
@@ -83,7 +83,6 @@ class RotatedFileLogger : public Logger {
FileAccess *file = nullptr;
- void rotate_file_without_closing();
void close_file();
void clear_old_backups();
void rotate_file();
@@ -103,7 +102,7 @@ public:
CompositeLogger(Vector<Logger *> p_loggers);
virtual void logv(const char *p_format, va_list p_list, bool p_err) _PRINTF_FORMAT_ATTRIBUTE_2_0;
- virtual void log_error(const char *p_function, const char *p_file, int p_line, const char *p_code, const char *p_rationale, ErrorType p_type = ERR_ERROR);
+ virtual void log_error(const char *p_function, const char *p_file, int p_line, const char *p_code, const char *p_rationale, bool p_editor_notify, ErrorType p_type = ERR_ERROR);
void add_logger(Logger *p_logger);
diff --git a/core/io/marshalls.cpp b/core/io/marshalls.cpp
index e7d5b78d14..7c06a354d1 100644
--- a/core/io/marshalls.cpp
+++ b/core/io/marshalls.cpp
@@ -562,7 +562,7 @@ Error decode_variant(Variant &r_variant, const uint8_t *p_buffer, int p_len, int
return err;
}
- if (str == String()) {
+ if (str.is_empty()) {
r_variant = (Object *)nullptr;
} else {
Object *obj = ClassDB::instantiate(str);
diff --git a/core/io/marshalls.h b/core/io/marshalls.h
index 05804d5a46..9ea060e48c 100644
--- a/core/io/marshalls.h
+++ b/core/io/marshalls.h
@@ -44,9 +44,9 @@ typedef uint32_t uintr_t;
#endif
/**
- * Miscellaneous helpers for marshalling data types, and encoding
- * in an endian independent way
- */
+ * Miscellaneous helpers for marshalling data types, and encoding
+ * in an endian independent way
+ */
union MarshallFloat {
uint32_t i; ///< int
diff --git a/core/io/packed_data_container.cpp b/core/io/packed_data_container.cpp
index 4a76f0191d..d34b5b6fe3 100644
--- a/core/io/packed_data_container.cpp
+++ b/core/io/packed_data_container.cpp
@@ -100,6 +100,7 @@ Variant PackedDataContainer::_iter_get_ofs(const Variant &p_iter, uint32_t p_off
}
Variant PackedDataContainer::_get_at_ofs(uint32_t p_ofs, const uint8_t *p_buf, bool &err) const {
+ ERR_FAIL_COND_V(p_ofs + 4 > (uint32_t)data.size(), Variant());
uint32_t type = decode_uint32(p_buf + p_ofs);
if (type == TYPE_ARRAY || type == TYPE_DICT) {
@@ -122,6 +123,7 @@ Variant PackedDataContainer::_get_at_ofs(uint32_t p_ofs, const uint8_t *p_buf, b
}
uint32_t PackedDataContainer::_type_at_ofs(uint32_t p_ofs) const {
+ ERR_FAIL_COND_V(p_ofs + 4 > (uint32_t)data.size(), 0);
const uint8_t *rd = data.ptr();
ERR_FAIL_COND_V(!rd, 0);
const uint8_t *r = &rd[p_ofs];
@@ -131,6 +133,7 @@ uint32_t PackedDataContainer::_type_at_ofs(uint32_t p_ofs) const {
}
int PackedDataContainer::_size(uint32_t p_ofs) const {
+ ERR_FAIL_COND_V(p_ofs + 4 > (uint32_t)data.size(), 0);
const uint8_t *rd = data.ptr();
ERR_FAIL_COND_V(!rd, 0);
const uint8_t *r = &rd[p_ofs];
@@ -149,6 +152,7 @@ int PackedDataContainer::_size(uint32_t p_ofs) const {
}
Variant PackedDataContainer::_key_at_ofs(uint32_t p_ofs, const Variant &p_key, bool &err) const {
+ ERR_FAIL_COND_V(p_ofs + 4 > (uint32_t)data.size(), Variant());
const uint8_t *rd = data.ptr();
if (!rd) {
err = true;
diff --git a/core/io/pck_packer.cpp b/core/io/pck_packer.cpp
index 806a95398f..8d75581342 100644
--- a/core/io/pck_packer.cpp
+++ b/core/io/pck_packer.cpp
@@ -47,13 +47,14 @@ static int _get_pad(int p_alignment, int p_n) {
}
void PCKPacker::_bind_methods() {
- ClassDB::bind_method(D_METHOD("pck_start", "pck_name", "alignment", "key", "encrypt_directory"), &PCKPacker::pck_start, DEFVAL(0), DEFVAL(String()), DEFVAL(false));
+ ClassDB::bind_method(D_METHOD("pck_start", "pck_name", "alignment", "key", "encrypt_directory"), &PCKPacker::pck_start, DEFVAL(32), DEFVAL("0000000000000000000000000000000000000000000000000000000000000000"), DEFVAL(false));
ClassDB::bind_method(D_METHOD("add_file", "pck_path", "source_path", "encrypt"), &PCKPacker::add_file, DEFVAL(false));
ClassDB::bind_method(D_METHOD("flush", "verbose"), &PCKPacker::flush, DEFVAL(false));
}
Error PCKPacker::pck_start(const String &p_file, int p_alignment, const String &p_key, bool p_encrypt_directory) {
ERR_FAIL_COND_V_MSG((p_key.is_empty() || !p_key.is_valid_hex_number(false) || p_key.length() != 64), ERR_CANT_CREATE, "Invalid Encryption Key (must be 64 characters long).");
+ ERR_FAIL_COND_V_MSG(p_alignment <= 0, ERR_CANT_CREATE, "Invalid alignment, must be greater then 0.");
String _key = p_key.to_lower();
key.resize(32);
diff --git a/core/io/pck_packer.h b/core/io/pck_packer.h
index 3d2ce8f240..bd8902a01d 100644
--- a/core/io/pck_packer.h
+++ b/core/io/pck_packer.h
@@ -58,7 +58,7 @@ class PCKPacker : public RefCounted {
Vector<File> files;
public:
- Error pck_start(const String &p_file, int p_alignment = 0, const String &p_key = String(), bool p_encrypt_directory = false);
+ Error pck_start(const String &p_file, int p_alignment = 32, const String &p_key = "0000000000000000000000000000000000000000000000000000000000000000", bool p_encrypt_directory = false);
Error add_file(const String &p_file, const String &p_src, bool p_encrypt = false);
Error flush(bool p_verbose = false);
diff --git a/core/io/resource.cpp b/core/io/resource.cpp
index 1cefa52d69..8da4e936e3 100644
--- a/core/io/resource.cpp
+++ b/core/io/resource.cpp
@@ -52,7 +52,7 @@ void Resource::set_path(const String &p_path, bool p_take_over) {
return;
}
- if (path_cache != "") {
+ if (!path_cache.is_empty()) {
ResourceCache::lock.write_lock();
ResourceCache::resources.erase(path_cache);
ResourceCache::lock.write_unlock();
@@ -82,7 +82,7 @@ void Resource::set_path(const String &p_path, bool p_take_over) {
}
path_cache = p_path;
- if (path_cache != "") {
+ if (!path_cache.is_empty()) {
ResourceCache::lock.write_lock();
ResourceCache::resources[path_cache] = this;
ResourceCache::lock.write_unlock();
@@ -136,6 +136,7 @@ String Resource::get_scene_unique_id() const {
void Resource::set_name(const String &p_name) {
name = p_name;
+ emit_changed();
}
String Resource::get_name() const {
@@ -382,7 +383,7 @@ 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, const String &p_id) {
- if (p_id == "") {
+ if (p_id.is_empty()) {
ResourceCache::path_cache_lock.write_lock();
ResourceCache::resource_path_cache[p_path].erase(get_path());
ResourceCache::path_cache_lock.write_unlock();
@@ -433,7 +434,7 @@ Resource::Resource() :
remapped_list(this) {}
Resource::~Resource() {
- if (path_cache != "") {
+ if (!path_cache.is_empty()) {
ResourceCache::lock.write_lock();
ResourceCache::resources.erase(path_cache);
ResourceCache::lock.write_unlock();
diff --git a/core/io/resource.h b/core/io/resource.h
index 9ccc247887..109c0f6611 100644
--- a/core/io/resource.h
+++ b/core/io/resource.h
@@ -103,6 +103,7 @@ public:
virtual void set_path(const String &p_path, bool p_take_over = false);
String get_path() const;
+ _FORCE_INLINE_ bool is_built_in() const { return path_cache.is_empty() || path_cache.find("::") != -1 || path_cache.begins_with("local://"); }
static String generate_scene_unique_id();
void set_scene_unique_id(const String &p_id);
diff --git a/core/io/resource_format_binary.cpp b/core/io/resource_format_binary.cpp
index cbb033f6c6..bd040f303d 100644
--- a/core/io/resource_format_binary.cpp
+++ b/core/io/resource_format_binary.cpp
@@ -727,7 +727,7 @@ Error ResourceLoaderBinary::load() {
}
res = RES(r);
- if (path != String() && cache_mode != ResourceFormatLoader::CACHE_MODE_IGNORE) {
+ if (!path.is_empty() && 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_scene_unique_id(id);
@@ -829,7 +829,7 @@ void ResourceLoaderBinary::get_dependencies(FileAccess *p_f, List<String> *p_dep
dep = external_resources[i].path;
}
- if (p_add_types && external_resources[i].type != String()) {
+ if (p_add_types && !external_resources[i].type.is_empty()) {
dep += "::" + external_resources[i].type;
}
@@ -1026,7 +1026,7 @@ RES ResourceFormatLoaderBinary::load(const String &p_path, const String &p_origi
loader.cache_mode = p_cache_mode;
loader.use_sub_threads = p_use_sub_threads;
loader.progress = r_progress;
- String path = p_original_path != "" ? p_original_path : p_path;
+ String path = !p_original_path.is_empty() ? p_original_path : p_path;
loader.local_path = ProjectSettings::get_singleton()->localize_path(path);
loader.res_path = loader.local_path;
//loader.set_local_path( Globals::get_singleton()->localize_path(p_path) );
@@ -1045,7 +1045,7 @@ RES ResourceFormatLoaderBinary::load(const String &p_path, const String &p_origi
}
void ResourceFormatLoaderBinary::get_recognized_extensions_for_type(const String &p_type, List<String> *p_extensions) const {
- if (p_type == "") {
+ if (p_type.is_empty()) {
get_recognized_extensions(p_extensions);
return;
}
@@ -1572,7 +1572,7 @@ void ResourceFormatSaverBinaryInstance::write_variant(FileAccess *f, const Varia
return; // don't save it
}
- if (res->get_path().length() && res->get_path().find("::") == -1) {
+ if (!res->is_built_in()) {
f->store_32(OBJECT_EXTERNAL_RESOURCE_INDEX);
f->store_32(external_resources[res]);
} else {
@@ -1743,7 +1743,7 @@ void ResourceFormatSaverBinaryInstance::_find_resources(const Variant &p_variant
return;
}
- if (!p_main && (!bundle_resources) && res->get_path().length() && res->get_path().find("::") == -1) {
+ if (!p_main && (!bundle_resources) && !res->is_built_in()) {
if (res->get_path() == path) {
ERR_PRINT("Circular reference to resource being saved found: '" + local_path + "' will be null next time it's loaded.");
return;
@@ -1978,8 +1978,8 @@ Error ResourceFormatSaverBinaryInstance::save(const String &p_path, const RES &p
Set<String> used_unique_ids;
for (RES &r : saved_resources) {
- if (r->get_path() == "" || r->get_path().find("::") != -1) {
- if (r->get_scene_unique_id() != "") {
+ if (r->is_built_in()) {
+ if (!r->get_scene_unique_id().is_empty()) {
if (used_unique_ids.has(r->get_scene_unique_id())) {
r->set_scene_unique_id("");
} else {
@@ -1992,8 +1992,8 @@ Error ResourceFormatSaverBinaryInstance::save(const String &p_path, const RES &p
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_scene_unique_id() == "") {
+ if (r->is_built_in()) {
+ if (r->get_scene_unique_id().is_empty()) {
String new_id;
while (true) {
diff --git a/core/io/resource_importer.cpp b/core/io/resource_importer.cpp
index cd44c537a8..fc5c434e37 100644
--- a/core/io/resource_importer.cpp
+++ b/core/io/resource_importer.cpp
@@ -78,8 +78,8 @@ Error ResourceFormatImporter::_get_path_and_type(const String &p_path, PathAndTy
return err;
}
- if (assign != String()) {
- if (!path_found && assign.begins_with("path.") && r_path_and_type.path == String()) {
+ if (!assign.is_empty()) {
+ if (!path_found && assign.begins_with("path.") && r_path_and_type.path.is_empty()) {
String feature = assign.get_slicec('.', 1);
if (OS::get_singleton()->has_feature(feature)) {
r_path_and_type.path = value;
@@ -112,7 +112,7 @@ Error ResourceFormatImporter::_get_path_and_type(const String &p_path, PathAndTy
memdelete(f);
- if (r_path_and_type.path == String() || r_path_and_type.type == String()) {
+ if (r_path_and_type.path.is_empty() || r_path_and_type.type.is_empty()) {
return ERR_FILE_CORRUPT;
}
return OK;
@@ -158,7 +158,7 @@ void ResourceFormatImporter::get_recognized_extensions(List<String> *p_extension
}
void ResourceFormatImporter::get_recognized_extensions_for_type(const String &p_type, List<String> *p_extensions) const {
- if (p_type == "") {
+ if (p_type.is_empty()) {
get_recognized_extensions(p_extensions);
return;
}
@@ -167,7 +167,7 @@ void ResourceFormatImporter::get_recognized_extensions_for_type(const String &p_
for (int i = 0; i < importers.size(); i++) {
String res_type = importers[i]->get_resource_type();
- if (res_type == String()) {
+ if (res_type.is_empty()) {
continue;
}
@@ -246,7 +246,7 @@ int ResourceFormatImporter::get_import_order(const String &p_path) const {
bool ResourceFormatImporter::handles_type(const String &p_type) const {
for (int i = 0; i < importers.size(); i++) {
String res_type = importers[i]->get_resource_type();
- if (res_type == String()) {
+ if (res_type.is_empty()) {
continue;
}
if (ClassDB::is_parent_class(res_type, p_type)) {
@@ -300,7 +300,7 @@ void ResourceFormatImporter::get_internal_resource_path_list(const String &p_pat
return;
}
- if (assign != String()) {
+ if (!assign.is_empty()) {
if (assign.begins_with("path.")) {
r_paths->push_back(value);
} else if (assign == "path") {
diff --git a/core/io/resource_importer.h b/core/io/resource_importer.h
index a1cacbd306..cd583e2533 100644
--- a/core/io/resource_importer.h
+++ b/core/io/resource_importer.h
@@ -134,8 +134,8 @@ public:
virtual int get_preset_count() const { return 0; }
virtual String get_preset_name(int p_idx) const { return String(); }
- virtual void get_import_options(List<ImportOption> *r_options, int p_preset = 0) const = 0;
- virtual bool get_option_visibility(const String &p_option, const Map<StringName, Variant> &p_options) const = 0;
+ virtual void get_import_options(const String &p_path, List<ImportOption> *r_options, int p_preset = 0) const = 0;
+ virtual bool get_option_visibility(const String &p_path, const String &p_option, const Map<StringName, Variant> &p_options) const = 0;
virtual String get_option_group_file() const { return String(); }
virtual Error import(const String &p_source_file, const String &p_save_path, const Map<StringName, Variant> &p_options, List<String> *r_platform_variants, List<String> *r_gen_files = nullptr, Variant *r_metadata = nullptr) = 0;
diff --git a/core/io/resource_loader.cpp b/core/io/resource_loader.cpp
index 2198761c2a..f65570bd60 100644
--- a/core/io/resource_loader.cpp
+++ b/core/io/resource_loader.cpp
@@ -52,7 +52,7 @@ bool ResourceFormatLoader::recognize_path(const String &p_path, const String &p_
String extension = p_path.get_extension();
List<String> extensions;
- if (p_for_type == String()) {
+ if (p_for_type.is_empty()) {
get_recognized_extensions(&extensions);
} else {
get_recognized_extensions_for_type(p_for_type, &extensions);
@@ -96,7 +96,7 @@ ResourceUID::ID ResourceFormatLoader::get_resource_uid(const String &p_path) con
}
void ResourceFormatLoader::get_recognized_extensions_for_type(const String &p_type, List<String> *p_extensions) const {
- if (p_type == "" || handles_type(p_type)) {
+ if (p_type.is_empty() || handles_type(p_type)) {
get_recognized_extensions(p_extensions);
}
}
@@ -194,7 +194,7 @@ RES ResourceLoader::_load(const String &p_path, const String &p_original_path, c
continue;
}
found = true;
- RES res = loader[i]->load(p_path, p_original_path != String() ? p_original_path : p_path, r_error, p_use_sub_threads, r_progress, p_cache_mode);
+ RES res = loader[i]->load(p_path, !p_original_path.is_empty() ? p_original_path : p_path, r_error, p_use_sub_threads, r_progress, p_cache_mode);
if (res.is_null()) {
continue;
}
@@ -289,7 +289,7 @@ Error ResourceLoader::load_threaded_request(const String &p_path, const String &
thread_load_mutex->lock();
- if (p_source_resource != String()) {
+ if (!p_source_resource.is_empty()) {
//must be loading from this resource
if (!thread_load_tasks.has(p_source_resource)) {
thread_load_mutex->unlock();
@@ -310,7 +310,7 @@ Error ResourceLoader::load_threaded_request(const String &p_path, const String &
if (thread_load_tasks.has(local_path)) {
thread_load_tasks[local_path].requests++;
- if (p_source_resource != String()) {
+ if (!p_source_resource.is_empty()) {
thread_load_tasks[p_source_resource].sub_tasks.insert(local_path);
}
thread_load_mutex->unlock();
@@ -354,7 +354,7 @@ Error ResourceLoader::load_threaded_request(const String &p_path, const String &
ResourceCache::lock.read_unlock();
}
- if (p_source_resource != String()) {
+ if (!p_source_resource.is_empty()) {
thread_load_tasks[p_source_resource].sub_tasks.insert(local_path);
}
@@ -574,7 +574,7 @@ RES ResourceLoader::load(const String &p_path, const String &p_type_hint, Resour
bool xl_remapped = false;
String path = _path_remap(local_path, &xl_remapped);
- if (path == "") {
+ if (path.is_empty()) {
ERR_FAIL_V_MSG(RES(), "Remapping '" + local_path + "' failed.");
}
@@ -776,7 +776,7 @@ String ResourceLoader::get_resource_type(const String &p_path) {
for (int i = 0; i < loader_count; i++) {
String result = loader[i]->get_resource_type(local_path);
- if (result != "") {
+ if (!result.is_empty()) {
return result;
}
}
diff --git a/core/io/translation_loader_po.cpp b/core/io/translation_loader_po.cpp
index 83d575cee8..cb7d67a726 100644
--- a/core/io/translation_loader_po.cpp
+++ b/core/io/translation_loader_po.cpp
@@ -87,7 +87,7 @@ RES TranslationLoaderPO::load_translation(FileAccess *f, Error *r_error) {
// In PO file, "msgctxt" appears before "msgid". If we encounter a "msgctxt", we add what we have read
// and set "entered_context" to true to prevent adding twice.
- if (!skip_this && msg_id != "") {
+ if (!skip_this && !msg_id.is_empty()) {
if (status == STATUS_READING_STRING) {
translation->add_message(msg_id, msg_str, msg_context);
} else if (status == STATUS_READING_PLURAL) {
@@ -125,7 +125,7 @@ RES TranslationLoaderPO::load_translation(FileAccess *f, Error *r_error) {
ERR_FAIL_V_MSG(RES(), "Unexpected 'msgid', was expecting 'msgstr' while parsing: " + path + ":" + itos(line));
}
- if (msg_id != "") {
+ if (!msg_id.is_empty()) {
if (!skip_this && !entered_context) {
if (status == STATUS_READING_STRING) {
translation->add_message(msg_id, msg_str, msg_context);
@@ -137,7 +137,7 @@ RES TranslationLoaderPO::load_translation(FileAccess *f, Error *r_error) {
translation->add_plural_message(msg_id, msgs_plural, msg_context);
}
}
- } else if (config == "") {
+ } else if (config.is_empty()) {
config = msg_str;
// Record plural rule.
int p_start = config.find("Plural-Forms");
@@ -178,7 +178,7 @@ RES TranslationLoaderPO::load_translation(FileAccess *f, Error *r_error) {
status = STATUS_READING_STRING;
}
- if (l == "" || l.begins_with("#")) {
+ if (l.is_empty() || l.begins_with("#")) {
if (l.find("fuzzy") != -1) {
skip_next = true;
}
@@ -236,15 +236,15 @@ RES TranslationLoaderPO::load_translation(FileAccess *f, Error *r_error) {
// Add the last set of data from last iteration.
if (status == STATUS_READING_STRING) {
- if (msg_id != "") {
+ if (!msg_id.is_empty()) {
if (!skip_this) {
translation->add_message(msg_id, msg_str, msg_context);
}
- } else if (config == "") {
+ } else if (config.is_empty()) {
config = msg_str;
}
} else if (status == STATUS_READING_PLURAL) {
- if (!skip_this && msg_id != "") {
+ if (!skip_this && !msg_id.is_empty()) {
if (plural_index != plural_forms - 1) {
memdelete(f);
ERR_FAIL_V_MSG(RES(), "Number of 'msgstr[]' doesn't match with number of plural forms: " + path + ":" + itos(line));
@@ -253,7 +253,7 @@ RES TranslationLoaderPO::load_translation(FileAccess *f, Error *r_error) {
}
}
- ERR_FAIL_COND_V_MSG(config == "", RES(), "No config found in file: " + path + ".");
+ ERR_FAIL_COND_V_MSG(config.is_empty(), RES(), "No config found in file: " + path + ".");
Vector<String> configs = config.split("\n");
for (int i = 0; i < configs.size(); i++) {
diff --git a/core/math/a_star.cpp b/core/math/a_star.cpp
index d59dbf1ba8..bdceae4374 100644
--- a/core/math/a_star.cpp
+++ b/core/math/a_star.cpp
@@ -210,7 +210,7 @@ bool AStar::has_point(int p_id) const {
return points.has(p_id);
}
-Array AStar::get_points() {
+Array AStar::get_point_ids() {
Array point_list;
for (OAHashMap<int, Point *>::Iterator it = points.iter(); it.valid; it = points.next_iter(it)) {
@@ -239,7 +239,7 @@ bool AStar::are_points_connected(int p_id, int p_with_id, bool bidirectional) co
const Set<Segment>::Element *element = segments.find(s);
return element != nullptr &&
- (bidirectional || (element->get().direction & s.direction) == s.direction);
+ (bidirectional || (element->get().direction & s.direction) == s.direction);
}
void AStar::clear() {
@@ -344,7 +344,7 @@ bool AStar::_solve(Point *begin_point, Point *end_point) {
}
sorter.pop_heap(0, open_list.size(), open_list.ptrw()); // Remove the current point from the open list
- open_list.remove(open_list.size() - 1);
+ open_list.remove_at(open_list.size() - 1);
p->closed_pass = pass; // Mark the point as closed
for (OAHashMap<int, Point *>::Iterator it = p->neighbours.iter(); it.valid; it = p->neighbours.next_iter(it)) {
@@ -539,7 +539,7 @@ void AStar::_bind_methods() {
ClassDB::bind_method(D_METHOD("remove_point", "id"), &AStar::remove_point);
ClassDB::bind_method(D_METHOD("has_point", "id"), &AStar::has_point);
ClassDB::bind_method(D_METHOD("get_point_connections", "id"), &AStar::get_point_connections);
- ClassDB::bind_method(D_METHOD("get_points"), &AStar::get_points);
+ ClassDB::bind_method(D_METHOD("get_point_ids"), &AStar::get_point_ids);
ClassDB::bind_method(D_METHOD("set_point_disabled", "id", "disabled"), &AStar::set_point_disabled, DEFVAL(true));
ClassDB::bind_method(D_METHOD("is_point_disabled", "id"), &AStar::is_point_disabled);
@@ -606,8 +606,8 @@ Vector<int> AStar2D::get_point_connections(int p_id) {
return astar.get_point_connections(p_id);
}
-Array AStar2D::get_points() {
- return astar.get_points();
+Array AStar2D::get_point_ids() {
+ return astar.get_point_ids();
}
void AStar2D::set_point_disabled(int p_id, bool p_disabled) {
@@ -812,7 +812,7 @@ bool AStar2D::_solve(AStar::Point *begin_point, AStar::Point *end_point) {
}
sorter.pop_heap(0, open_list.size(), open_list.ptrw()); // Remove the current point from the open list
- open_list.remove(open_list.size() - 1);
+ open_list.remove_at(open_list.size() - 1);
p->closed_pass = astar.pass; // Mark the point as closed
for (OAHashMap<int, AStar::Point *>::Iterator it = p->neighbours.iter(); it.valid; it = p->neighbours.next_iter(it)) {
@@ -859,7 +859,7 @@ void AStar2D::_bind_methods() {
ClassDB::bind_method(D_METHOD("remove_point", "id"), &AStar2D::remove_point);
ClassDB::bind_method(D_METHOD("has_point", "id"), &AStar2D::has_point);
ClassDB::bind_method(D_METHOD("get_point_connections", "id"), &AStar2D::get_point_connections);
- ClassDB::bind_method(D_METHOD("get_points"), &AStar2D::get_points);
+ ClassDB::bind_method(D_METHOD("get_point_ids"), &AStar2D::get_point_ids);
ClassDB::bind_method(D_METHOD("set_point_disabled", "id", "disabled"), &AStar2D::set_point_disabled, DEFVAL(true));
ClassDB::bind_method(D_METHOD("is_point_disabled", "id"), &AStar2D::is_point_disabled);
diff --git a/core/math/a_star.h b/core/math/a_star.h
index 64fa32a325..ef6f22d228 100644
--- a/core/math/a_star.h
+++ b/core/math/a_star.h
@@ -138,7 +138,7 @@ public:
void remove_point(int p_id);
bool has_point(int p_id) const;
Vector<int> get_point_connections(int p_id);
- Array get_points();
+ Array get_point_ids();
void set_point_disabled(int p_id, bool p_disabled = true);
bool is_point_disabled(int p_id) const;
@@ -188,7 +188,7 @@ public:
void remove_point(int p_id);
bool has_point(int p_id) const;
Vector<int> get_point_connections(int p_id);
- Array get_points();
+ Array get_point_ids();
void set_point_disabled(int p_id, bool p_disabled = true);
bool is_point_disabled(int p_id) const;
diff --git a/core/math/aabb.cpp b/core/math/aabb.cpp
index 51a1309f0e..83726f46b5 100644
--- a/core/math/aabb.cpp
+++ b/core/math/aabb.cpp
@@ -33,7 +33,7 @@
#include "core/string/print_string.h"
#include "core/variant/variant.h"
-real_t AABB::get_area() const {
+real_t AABB::get_volume() const {
return size.x * size.y * size.z;
}
@@ -46,6 +46,11 @@ bool AABB::operator!=(const AABB &p_rval) const {
}
void AABB::merge_with(const AABB &p_aabb) {
+#ifdef MATH_CHECKS
+ if (unlikely(size.x < 0 || size.y < 0 || size.z < 0 || p_aabb.size.x < 0 || p_aabb.size.y < 0 || p_aabb.size.z < 0)) {
+ ERR_PRINT("AABB size is negative, this is not supported. Use AABB.abs() to get an AABB with a positive size.");
+ }
+#endif
Vector3 beg_1, beg_2;
Vector3 end_1, end_2;
Vector3 min, max;
@@ -72,6 +77,11 @@ bool AABB::is_equal_approx(const AABB &p_aabb) const {
}
AABB AABB::intersection(const AABB &p_aabb) const {
+#ifdef MATH_CHECKS
+ if (unlikely(size.x < 0 || size.y < 0 || size.z < 0 || p_aabb.size.x < 0 || p_aabb.size.y < 0 || p_aabb.size.z < 0)) {
+ ERR_PRINT("AABB size is negative, this is not supported. Use AABB.abs() to get an AABB with a positive size.");
+ }
+#endif
Vector3 src_min = position;
Vector3 src_max = position + size;
Vector3 dst_min = p_aabb.position;
@@ -104,6 +114,11 @@ AABB AABB::intersection(const AABB &p_aabb) const {
}
bool AABB::intersects_ray(const Vector3 &p_from, const Vector3 &p_dir, Vector3 *r_clip, Vector3 *r_normal) const {
+#ifdef MATH_CHECKS
+ if (unlikely(size.x < 0 || size.y < 0 || size.z < 0)) {
+ ERR_PRINT("AABB size is negative, this is not supported. Use AABB.abs() to get an AABB with a positive size.");
+ }
+#endif
Vector3 c1, c2;
Vector3 end = position + size;
real_t near = -1e20;
@@ -147,6 +162,11 @@ bool AABB::intersects_ray(const Vector3 &p_from, const Vector3 &p_dir, Vector3 *
}
bool AABB::intersects_segment(const Vector3 &p_from, const Vector3 &p_to, Vector3 *r_clip, Vector3 *r_normal) const {
+#ifdef MATH_CHECKS
+ if (unlikely(size.x < 0 || size.y < 0 || size.z < 0)) {
+ ERR_PRINT("AABB size is negative, this is not supported. Use AABB.abs() to get an AABB with a positive size.");
+ }
+#endif
real_t min = 0, max = 1;
int axis = 0;
real_t sign = 0;
diff --git a/core/math/aabb.h b/core/math/aabb.h
index 97d92fbe37..81124002e2 100644
--- a/core/math/aabb.h
+++ b/core/math/aabb.h
@@ -46,8 +46,8 @@ public:
Vector3 position;
Vector3 size;
- real_t get_area() const; /// get area
- _FORCE_INLINE_ bool has_no_area() const {
+ real_t get_volume() const;
+ _FORCE_INLINE_ bool has_no_volume() const {
return (size.x <= 0 || size.y <= 0 || size.z <= 0);
}
@@ -132,6 +132,11 @@ public:
};
inline bool AABB::intersects(const AABB &p_aabb) const {
+#ifdef MATH_CHECKS
+ if (unlikely(size.x < 0 || size.y < 0 || size.z < 0 || p_aabb.size.x < 0 || p_aabb.size.y < 0 || p_aabb.size.z < 0)) {
+ ERR_PRINT("AABB size is negative, this is not supported. Use AABB.abs() to get an AABB with a positive size.");
+ }
+#endif
if (position.x >= (p_aabb.position.x + p_aabb.size.x)) {
return false;
}
@@ -155,6 +160,11 @@ inline bool AABB::intersects(const AABB &p_aabb) const {
}
inline bool AABB::intersects_inclusive(const AABB &p_aabb) const {
+#ifdef MATH_CHECKS
+ if (unlikely(size.x < 0 || size.y < 0 || size.z < 0 || p_aabb.size.x < 0 || p_aabb.size.y < 0 || p_aabb.size.z < 0)) {
+ ERR_PRINT("AABB size is negative, this is not supported. Use AABB.abs() to get an AABB with a positive size.");
+ }
+#endif
if (position.x > (p_aabb.position.x + p_aabb.size.x)) {
return false;
}
@@ -178,6 +188,11 @@ inline bool AABB::intersects_inclusive(const AABB &p_aabb) const {
}
inline bool AABB::encloses(const AABB &p_aabb) const {
+#ifdef MATH_CHECKS
+ if (unlikely(size.x < 0 || size.y < 0 || size.z < 0 || p_aabb.size.x < 0 || p_aabb.size.y < 0 || p_aabb.size.z < 0)) {
+ ERR_PRINT("AABB size is negative, this is not supported. Use AABB.abs() to get an AABB with a positive size.");
+ }
+#endif
Vector3 src_min = position;
Vector3 src_max = position + size;
Vector3 dst_min = p_aabb.position;
@@ -200,7 +215,7 @@ Vector3 AABB::get_support(const Vector3 &p_normal) const {
(p_normal.x > 0) ? half_extents.x : -half_extents.x,
(p_normal.y > 0) ? half_extents.y : -half_extents.y,
(p_normal.z > 0) ? half_extents.z : -half_extents.z) +
- ofs;
+ ofs;
}
Vector3 AABB::get_endpoint(int p_point) const {
@@ -288,6 +303,11 @@ bool AABB::inside_convex_shape(const Plane *p_planes, int p_plane_count) const {
}
bool AABB::has_point(const Vector3 &p_point) const {
+#ifdef MATH_CHECKS
+ if (unlikely(size.x < 0 || size.y < 0 || size.z < 0)) {
+ ERR_PRINT("AABB size is negative, this is not supported. Use AABB.abs() to get an AABB with a positive size.");
+ }
+#endif
if (p_point.x < position.x) {
return false;
}
@@ -311,6 +331,11 @@ bool AABB::has_point(const Vector3 &p_point) const {
}
inline void AABB::expand_to(const Vector3 &p_vector) {
+#ifdef MATH_CHECKS
+ if (unlikely(size.x < 0 || size.y < 0 || size.z < 0)) {
+ ERR_PRINT("AABB size is negative, this is not supported. Use AABB.abs() to get an AABB with a positive size.");
+ }
+#endif
Vector3 begin = position;
Vector3 end = position + size;
@@ -377,6 +402,11 @@ inline real_t AABB::get_shortest_axis_size() const {
}
bool AABB::smits_intersect_ray(const Vector3 &p_from, const Vector3 &p_dir, real_t t0, real_t t1) const {
+#ifdef MATH_CHECKS
+ if (unlikely(size.x < 0 || size.y < 0 || size.z < 0)) {
+ ERR_PRINT("AABB size is negative, this is not supported. Use AABB.abs() to get an AABB with a positive size.");
+ }
+#endif
real_t divx = 1.0 / p_dir.x;
real_t divy = 1.0 / p_dir.y;
real_t divz = 1.0 / p_dir.z;
diff --git a/core/math/audio_frame.h b/core/math/audio_frame.h
index a5616b8d79..4a11b99fe8 100644
--- a/core/math/audio_frame.h
+++ b/core/math/audio_frame.h
@@ -124,10 +124,9 @@ struct AudioFrame {
r = p_frame.r;
}
- _ALWAYS_INLINE_ AudioFrame &operator=(const AudioFrame &p_frame) {
+ _ALWAYS_INLINE_ void operator=(const AudioFrame &p_frame) {
l = p_frame.l;
r = p_frame.r;
- return *this;
}
_ALWAYS_INLINE_ operator Vector2() const {
diff --git a/core/math/basis.cpp b/core/math/basis.cpp
index a7f89522d7..566300c716 100644
--- a/core/math/basis.cpp
+++ b/core/math/basis.cpp
@@ -58,8 +58,8 @@ void Basis::invert() {
cofac(1, 1, 2, 2), cofac(1, 2, 2, 0), cofac(1, 0, 2, 1)
};
real_t det = elements[0][0] * co[0] +
- elements[0][1] * co[1] +
- elements[0][2] * co[2];
+ elements[0][1] * co[1] +
+ elements[0][2] * co[2];
#ifdef MATH_CHECKS
ERR_FAIL_COND(det == 0);
#endif
@@ -261,7 +261,7 @@ Vector3 Basis::get_scale_abs() const {
}
Vector3 Basis::get_scale_local() const {
- real_t det_sign = SGN(determinant());
+ real_t det_sign = SIGN(determinant());
return det_sign * Vector3(elements[0].length(), elements[1].length(), elements[2].length());
}
@@ -287,11 +287,8 @@ Vector3 Basis::get_scale() const {
// matrix elements.
//
// The rotation part of this decomposition is returned by get_rotation* functions.
- real_t det_sign = SGN(determinant());
- return det_sign * Vector3(
- Vector3(elements[0][0], elements[1][0], elements[2][0]).length(),
- Vector3(elements[0][1], elements[1][1], elements[2][1]).length(),
- Vector3(elements[0][2], elements[1][2], elements[2][2]).length());
+ real_t det_sign = SIGN(determinant());
+ return det_sign * get_scale_abs();
}
// Decomposes a Basis into a rotation-reflection matrix (an element of the group O(3)) and a positive scaling matrix as B = O.S.
@@ -354,7 +351,7 @@ void Basis::rotate(const Quaternion &p_quaternion) {
*this = rotated(p_quaternion);
}
-Vector3 Basis::get_rotation_euler() const {
+Vector3 Basis::get_euler_normalized(EulerOrder p_order) const {
// Assumes that the matrix can be decomposed into a proper rotation and scaling matrix as M = R.S,
// and returns the Euler angles corresponding to the rotation part, complementing get_scale().
// See the comment in get_scale() for further information.
@@ -365,7 +362,7 @@ Vector3 Basis::get_rotation_euler() const {
m.scale(Vector3(-1, -1, -1));
}
- return m.get_euler();
+ return m.get_euler(p_order);
}
Quaternion Basis::get_rotation_quaternion() const {
@@ -424,218 +421,203 @@ void Basis::get_rotation_axis_angle_local(Vector3 &p_axis, real_t &p_angle) cons
p_angle = -p_angle;
}
-// get_euler_xyz returns a vector containing the Euler angles in the format
-// (a1,a2,a3), where a3 is the angle of the first rotation, and a1 is the last
-// (following the convention they are commonly defined in the literature).
-//
-// The current implementation uses XYZ convention (Z is the first rotation),
-// so euler.z is the angle of the (first) rotation around Z axis and so on,
-//
-// And thus, assuming the matrix is a rotation matrix, this function returns
-// the angles in the decomposition R = X(a1).Y(a2).Z(a3) where Z(a) rotates
-// around the z-axis by a and so on.
-Vector3 Basis::get_euler_xyz() const {
- // Euler angles in XYZ convention.
- // See https://en.wikipedia.org/wiki/Euler_angles#Rotation_matrix
- //
- // rot = cy*cz -cy*sz sy
- // cz*sx*sy+cx*sz cx*cz-sx*sy*sz -cy*sx
- // -cx*cz*sy+sx*sz cz*sx+cx*sy*sz cx*cy
-
- Vector3 euler;
- real_t sy = elements[0][2];
- if (sy < (1.0 - CMP_EPSILON)) {
- if (sy > -(1.0 - CMP_EPSILON)) {
- // is this a pure Y rotation?
- if (elements[1][0] == 0.0 && elements[0][1] == 0.0 && elements[1][2] == 0 && elements[2][1] == 0 && elements[1][1] == 1) {
- // return the simplest form (human friendlier in editor and scripts)
- euler.x = 0;
- euler.y = atan2(elements[0][2], elements[0][0]);
- euler.z = 0;
+Vector3 Basis::get_euler(EulerOrder p_order) const {
+ switch (p_order) {
+ case EULER_ORDER_XYZ: {
+ // Euler angles in XYZ convention.
+ // See https://en.wikipedia.org/wiki/Euler_angles#Rotation_matrix
+ //
+ // rot = cy*cz -cy*sz sy
+ // cz*sx*sy+cx*sz cx*cz-sx*sy*sz -cy*sx
+ // -cx*cz*sy+sx*sz cz*sx+cx*sy*sz cx*cy
+
+ Vector3 euler;
+ real_t sy = elements[0][2];
+ if (sy < (1.0 - CMP_EPSILON)) {
+ if (sy > -(1.0 - CMP_EPSILON)) {
+ // is this a pure Y rotation?
+ if (elements[1][0] == 0.0 && elements[0][1] == 0.0 && elements[1][2] == 0 && elements[2][1] == 0 && elements[1][1] == 1) {
+ // return the simplest form (human friendlier in editor and scripts)
+ euler.x = 0;
+ euler.y = atan2(elements[0][2], elements[0][0]);
+ euler.z = 0;
+ } else {
+ euler.x = Math::atan2(-elements[1][2], elements[2][2]);
+ euler.y = Math::asin(sy);
+ euler.z = Math::atan2(-elements[0][1], elements[0][0]);
+ }
+ } else {
+ euler.x = Math::atan2(elements[2][1], elements[1][1]);
+ euler.y = -Math_PI / 2.0;
+ euler.z = 0.0;
+ }
} else {
- euler.x = Math::atan2(-elements[1][2], elements[2][2]);
- euler.y = Math::asin(sy);
- euler.z = Math::atan2(-elements[0][1], elements[0][0]);
+ euler.x = Math::atan2(elements[2][1], elements[1][1]);
+ euler.y = Math_PI / 2.0;
+ euler.z = 0.0;
+ }
+ return euler;
+ } break;
+ case EULER_ORDER_XZY: {
+ // Euler angles in XZY convention.
+ // See https://en.wikipedia.org/wiki/Euler_angles#Rotation_matrix
+ //
+ // rot = cz*cy -sz cz*sy
+ // sx*sy+cx*cy*sz cx*cz cx*sz*sy-cy*sx
+ // cy*sx*sz cz*sx cx*cy+sx*sz*sy
+
+ Vector3 euler;
+ real_t sz = elements[0][1];
+ if (sz < (1.0 - CMP_EPSILON)) {
+ if (sz > -(1.0 - CMP_EPSILON)) {
+ euler.x = Math::atan2(elements[2][1], elements[1][1]);
+ euler.y = Math::atan2(elements[0][2], elements[0][0]);
+ euler.z = Math::asin(-sz);
+ } else {
+ // It's -1
+ euler.x = -Math::atan2(elements[1][2], elements[2][2]);
+ euler.y = 0.0;
+ euler.z = Math_PI / 2.0;
+ }
+ } else {
+ // It's 1
+ euler.x = -Math::atan2(elements[1][2], elements[2][2]);
+ euler.y = 0.0;
+ euler.z = -Math_PI / 2.0;
+ }
+ return euler;
+ } break;
+ case EULER_ORDER_YXZ: {
+ // Euler angles in YXZ convention.
+ // See https://en.wikipedia.org/wiki/Euler_angles#Rotation_matrix
+ //
+ // rot = cy*cz+sy*sx*sz cz*sy*sx-cy*sz cx*sy
+ // cx*sz cx*cz -sx
+ // cy*sx*sz-cz*sy cy*cz*sx+sy*sz cy*cx
+
+ Vector3 euler;
+
+ real_t m12 = elements[1][2];
+
+ if (m12 < (1 - CMP_EPSILON)) {
+ if (m12 > -(1 - CMP_EPSILON)) {
+ // is this a pure X rotation?
+ if (elements[1][0] == 0 && elements[0][1] == 0 && elements[0][2] == 0 && elements[2][0] == 0 && elements[0][0] == 1) {
+ // return the simplest form (human friendlier in editor and scripts)
+ euler.x = atan2(-m12, elements[1][1]);
+ euler.y = 0;
+ euler.z = 0;
+ } else {
+ euler.x = asin(-m12);
+ euler.y = atan2(elements[0][2], elements[2][2]);
+ euler.z = atan2(elements[1][0], elements[1][1]);
+ }
+ } else { // m12 == -1
+ euler.x = Math_PI * 0.5;
+ euler.y = atan2(elements[0][1], elements[0][0]);
+ euler.z = 0;
+ }
+ } else { // m12 == 1
+ euler.x = -Math_PI * 0.5;
+ euler.y = -atan2(elements[0][1], elements[0][0]);
+ euler.z = 0;
}
- } else {
- euler.x = Math::atan2(elements[2][1], elements[1][1]);
- euler.y = -Math_PI / 2.0;
- euler.z = 0.0;
- }
- } else {
- euler.x = Math::atan2(elements[2][1], elements[1][1]);
- euler.y = Math_PI / 2.0;
- euler.z = 0.0;
- }
- return euler;
-}
-
-// set_euler_xyz expects a vector containing the Euler angles in the format
-// (ax,ay,az), where ax is the angle of rotation around x axis,
-// and similar for other axes.
-// The current implementation uses XYZ convention (Z is the first rotation).
-void Basis::set_euler_xyz(const Vector3 &p_euler) {
- real_t c, s;
-
- c = Math::cos(p_euler.x);
- s = Math::sin(p_euler.x);
- Basis xmat(1.0, 0.0, 0.0, 0.0, c, -s, 0.0, s, c);
-
- c = Math::cos(p_euler.y);
- s = Math::sin(p_euler.y);
- Basis ymat(c, 0.0, s, 0.0, 1.0, 0.0, -s, 0.0, c);
-
- c = Math::cos(p_euler.z);
- s = Math::sin(p_euler.z);
- Basis zmat(c, -s, 0.0, s, c, 0.0, 0.0, 0.0, 1.0);
-
- //optimizer will optimize away all this anyway
- *this = xmat * (ymat * zmat);
-}
-
-Vector3 Basis::get_euler_xzy() const {
- // Euler angles in XZY convention.
- // See https://en.wikipedia.org/wiki/Euler_angles#Rotation_matrix
- //
- // rot = cz*cy -sz cz*sy
- // sx*sy+cx*cy*sz cx*cz cx*sz*sy-cy*sx
- // cy*sx*sz cz*sx cx*cy+sx*sz*sy
-
- Vector3 euler;
- real_t sz = elements[0][1];
- if (sz < (1.0 - CMP_EPSILON)) {
- if (sz > -(1.0 - CMP_EPSILON)) {
- euler.x = Math::atan2(elements[2][1], elements[1][1]);
- euler.y = Math::atan2(elements[0][2], elements[0][0]);
- euler.z = Math::asin(-sz);
- } else {
- // It's -1
- euler.x = -Math::atan2(elements[1][2], elements[2][2]);
- euler.y = 0.0;
- euler.z = Math_PI / 2.0;
- }
- } else {
- // It's 1
- euler.x = -Math::atan2(elements[1][2], elements[2][2]);
- euler.y = 0.0;
- euler.z = -Math_PI / 2.0;
- }
- return euler;
-}
-
-void Basis::set_euler_xzy(const Vector3 &p_euler) {
- real_t c, s;
-
- c = Math::cos(p_euler.x);
- s = Math::sin(p_euler.x);
- Basis xmat(1.0, 0.0, 0.0, 0.0, c, -s, 0.0, s, c);
-
- c = Math::cos(p_euler.y);
- s = Math::sin(p_euler.y);
- Basis ymat(c, 0.0, s, 0.0, 1.0, 0.0, -s, 0.0, c);
-
- c = Math::cos(p_euler.z);
- s = Math::sin(p_euler.z);
- Basis zmat(c, -s, 0.0, s, c, 0.0, 0.0, 0.0, 1.0);
-
- *this = xmat * zmat * ymat;
-}
-
-Vector3 Basis::get_euler_yzx() const {
- // Euler angles in YZX convention.
- // See https://en.wikipedia.org/wiki/Euler_angles#Rotation_matrix
- //
- // rot = cy*cz sy*sx-cy*cx*sz cx*sy+cy*sz*sx
- // sz cz*cx -cz*sx
- // -cz*sy cy*sx+cx*sy*sz cy*cx-sy*sz*sx
-
- Vector3 euler;
- real_t sz = elements[1][0];
- if (sz < (1.0 - CMP_EPSILON)) {
- if (sz > -(1.0 - CMP_EPSILON)) {
- euler.x = Math::atan2(-elements[1][2], elements[1][1]);
- euler.y = Math::atan2(-elements[2][0], elements[0][0]);
- euler.z = Math::asin(sz);
- } else {
- // It's -1
- euler.x = Math::atan2(elements[2][1], elements[2][2]);
- euler.y = 0.0;
- euler.z = -Math_PI / 2.0;
- }
- } else {
- // It's 1
- euler.x = Math::atan2(elements[2][1], elements[2][2]);
- euler.y = 0.0;
- euler.z = Math_PI / 2.0;
- }
- return euler;
-}
-
-void Basis::set_euler_yzx(const Vector3 &p_euler) {
- real_t c, s;
-
- c = Math::cos(p_euler.x);
- s = Math::sin(p_euler.x);
- Basis xmat(1.0, 0.0, 0.0, 0.0, c, -s, 0.0, s, c);
-
- c = Math::cos(p_euler.y);
- s = Math::sin(p_euler.y);
- Basis ymat(c, 0.0, s, 0.0, 1.0, 0.0, -s, 0.0, c);
-
- c = Math::cos(p_euler.z);
- s = Math::sin(p_euler.z);
- Basis zmat(c, -s, 0.0, s, c, 0.0, 0.0, 0.0, 1.0);
-
- *this = ymat * zmat * xmat;
-}
-
-// get_euler_yxz returns a vector containing the Euler angles in the YXZ convention,
-// as in first-Z, then-X, last-Y. The angles for X, Y, and Z rotations are returned
-// as the x, y, and z components of a Vector3 respectively.
-Vector3 Basis::get_euler_yxz() const {
- // Euler angles in YXZ convention.
- // See https://en.wikipedia.org/wiki/Euler_angles#Rotation_matrix
- //
- // rot = cy*cz+sy*sx*sz cz*sy*sx-cy*sz cx*sy
- // cx*sz cx*cz -sx
- // cy*sx*sz-cz*sy cy*cz*sx+sy*sz cy*cx
-
- Vector3 euler;
-
- real_t m12 = elements[1][2];
- if (m12 < (1 - CMP_EPSILON)) {
- if (m12 > -(1 - CMP_EPSILON)) {
- // is this a pure X rotation?
- if (elements[1][0] == 0 && elements[0][1] == 0 && elements[0][2] == 0 && elements[2][0] == 0 && elements[0][0] == 1) {
- // return the simplest form (human friendlier in editor and scripts)
- euler.x = atan2(-m12, elements[1][1]);
- euler.y = 0;
+ return euler;
+ } break;
+ case EULER_ORDER_YZX: {
+ // Euler angles in YZX convention.
+ // See https://en.wikipedia.org/wiki/Euler_angles#Rotation_matrix
+ //
+ // rot = cy*cz sy*sx-cy*cx*sz cx*sy+cy*sz*sx
+ // sz cz*cx -cz*sx
+ // -cz*sy cy*sx+cx*sy*sz cy*cx-sy*sz*sx
+
+ Vector3 euler;
+ real_t sz = elements[1][0];
+ if (sz < (1.0 - CMP_EPSILON)) {
+ if (sz > -(1.0 - CMP_EPSILON)) {
+ euler.x = Math::atan2(-elements[1][2], elements[1][1]);
+ euler.y = Math::atan2(-elements[2][0], elements[0][0]);
+ euler.z = Math::asin(sz);
+ } else {
+ // It's -1
+ euler.x = Math::atan2(elements[2][1], elements[2][2]);
+ euler.y = 0.0;
+ euler.z = -Math_PI / 2.0;
+ }
+ } else {
+ // It's 1
+ euler.x = Math::atan2(elements[2][1], elements[2][2]);
+ euler.y = 0.0;
+ euler.z = Math_PI / 2.0;
+ }
+ return euler;
+ } break;
+ case EULER_ORDER_ZXY: {
+ // Euler angles in ZXY convention.
+ // See https://en.wikipedia.org/wiki/Euler_angles#Rotation_matrix
+ //
+ // rot = cz*cy-sz*sx*sy -cx*sz cz*sy+cy*sz*sx
+ // cy*sz+cz*sx*sy cz*cx sz*sy-cz*cy*sx
+ // -cx*sy sx cx*cy
+ Vector3 euler;
+ real_t sx = elements[2][1];
+ if (sx < (1.0 - CMP_EPSILON)) {
+ if (sx > -(1.0 - CMP_EPSILON)) {
+ euler.x = Math::asin(sx);
+ euler.y = Math::atan2(-elements[2][0], elements[2][2]);
+ euler.z = Math::atan2(-elements[0][1], elements[1][1]);
+ } else {
+ // It's -1
+ euler.x = -Math_PI / 2.0;
+ euler.y = Math::atan2(elements[0][2], elements[0][0]);
+ euler.z = 0;
+ }
+ } else {
+ // It's 1
+ euler.x = Math_PI / 2.0;
+ euler.y = Math::atan2(elements[0][2], elements[0][0]);
euler.z = 0;
+ }
+ return euler;
+ } break;
+ case EULER_ORDER_ZYX: {
+ // Euler angles in ZYX convention.
+ // See https://en.wikipedia.org/wiki/Euler_angles#Rotation_matrix
+ //
+ // rot = cz*cy cz*sy*sx-cx*sz sz*sx+cz*cx*cy
+ // cy*sz cz*cx+sz*sy*sx cx*sz*sy-cz*sx
+ // -sy cy*sx cy*cx
+ Vector3 euler;
+ real_t sy = elements[2][0];
+ if (sy < (1.0 - CMP_EPSILON)) {
+ if (sy > -(1.0 - CMP_EPSILON)) {
+ euler.x = Math::atan2(elements[2][1], elements[2][2]);
+ euler.y = Math::asin(-sy);
+ euler.z = Math::atan2(elements[1][0], elements[0][0]);
+ } else {
+ // It's -1
+ euler.x = 0;
+ euler.y = Math_PI / 2.0;
+ euler.z = -Math::atan2(elements[0][1], elements[1][1]);
+ }
} else {
- euler.x = asin(-m12);
- euler.y = atan2(elements[0][2], elements[2][2]);
- euler.z = atan2(elements[1][0], elements[1][1]);
+ // It's 1
+ euler.x = 0;
+ euler.y = -Math_PI / 2.0;
+ euler.z = -Math::atan2(elements[0][1], elements[1][1]);
}
- } else { // m12 == -1
- euler.x = Math_PI * 0.5;
- euler.y = atan2(elements[0][1], elements[0][0]);
- euler.z = 0;
+ return euler;
+ } break;
+ default: {
+ ERR_FAIL_V_MSG(Vector3(), "Invalid parameter for get_euler(order)");
}
- } else { // m12 == 1
- euler.x = -Math_PI * 0.5;
- euler.y = -atan2(elements[0][1], elements[0][0]);
- euler.z = 0;
}
-
- return euler;
+ return Vector3();
}
-// set_euler_yxz expects a vector containing the Euler angles in the format
-// (ax,ay,az), where ax is the angle of rotation around x axis,
-// and similar for other axes.
-// The current implementation uses YXZ convention (Z is the first rotation).
-void Basis::set_euler_yxz(const Vector3 &p_euler) {
+void Basis::set_euler(const Vector3 &p_euler, EulerOrder p_order) {
real_t c, s;
c = Math::cos(p_euler.x);
@@ -650,102 +632,29 @@ void Basis::set_euler_yxz(const Vector3 &p_euler) {
s = Math::sin(p_euler.z);
Basis zmat(c, -s, 0.0, s, c, 0.0, 0.0, 0.0, 1.0);
- //optimizer will optimize away all this anyway
- *this = ymat * xmat * zmat;
-}
-
-Vector3 Basis::get_euler_zxy() const {
- // Euler angles in ZXY convention.
- // See https://en.wikipedia.org/wiki/Euler_angles#Rotation_matrix
- //
- // rot = cz*cy-sz*sx*sy -cx*sz cz*sy+cy*sz*sx
- // cy*sz+cz*sx*sy cz*cx sz*sy-cz*cy*sx
- // -cx*sy sx cx*cy
- Vector3 euler;
- real_t sx = elements[2][1];
- if (sx < (1.0 - CMP_EPSILON)) {
- if (sx > -(1.0 - CMP_EPSILON)) {
- euler.x = Math::asin(sx);
- euler.y = Math::atan2(-elements[2][0], elements[2][2]);
- euler.z = Math::atan2(-elements[0][1], elements[1][1]);
- } else {
- // It's -1
- euler.x = -Math_PI / 2.0;
- euler.y = Math::atan2(elements[0][2], elements[0][0]);
- euler.z = 0;
+ switch (p_order) {
+ case EULER_ORDER_XYZ: {
+ *this = xmat * (ymat * zmat);
+ } break;
+ case EULER_ORDER_XZY: {
+ *this = xmat * zmat * ymat;
+ } break;
+ case EULER_ORDER_YXZ: {
+ *this = ymat * xmat * zmat;
+ } break;
+ case EULER_ORDER_YZX: {
+ *this = ymat * zmat * xmat;
+ } break;
+ case EULER_ORDER_ZXY: {
+ *this = zmat * xmat * ymat;
+ } break;
+ case EULER_ORDER_ZYX: {
+ *this = zmat * ymat * xmat;
+ } break;
+ default: {
+ ERR_FAIL_MSG("Invalid order parameter for set_euler(vec3,order)");
}
- } else {
- // It's 1
- euler.x = Math_PI / 2.0;
- euler.y = Math::atan2(elements[0][2], elements[0][0]);
- euler.z = 0;
}
- return euler;
-}
-
-void Basis::set_euler_zxy(const Vector3 &p_euler) {
- real_t c, s;
-
- c = Math::cos(p_euler.x);
- s = Math::sin(p_euler.x);
- Basis xmat(1.0, 0.0, 0.0, 0.0, c, -s, 0.0, s, c);
-
- c = Math::cos(p_euler.y);
- s = Math::sin(p_euler.y);
- Basis ymat(c, 0.0, s, 0.0, 1.0, 0.0, -s, 0.0, c);
-
- c = Math::cos(p_euler.z);
- s = Math::sin(p_euler.z);
- Basis zmat(c, -s, 0.0, s, c, 0.0, 0.0, 0.0, 1.0);
-
- *this = zmat * xmat * ymat;
-}
-
-Vector3 Basis::get_euler_zyx() const {
- // Euler angles in ZYX convention.
- // See https://en.wikipedia.org/wiki/Euler_angles#Rotation_matrix
- //
- // rot = cz*cy cz*sy*sx-cx*sz sz*sx+cz*cx*cy
- // cy*sz cz*cx+sz*sy*sx cx*sz*sy-cz*sx
- // -sy cy*sx cy*cx
- Vector3 euler;
- real_t sy = elements[2][0];
- if (sy < (1.0 - CMP_EPSILON)) {
- if (sy > -(1.0 - CMP_EPSILON)) {
- euler.x = Math::atan2(elements[2][1], elements[2][2]);
- euler.y = Math::asin(-sy);
- euler.z = Math::atan2(elements[1][0], elements[0][0]);
- } else {
- // It's -1
- euler.x = 0;
- euler.y = Math_PI / 2.0;
- euler.z = -Math::atan2(elements[0][1], elements[1][1]);
- }
- } else {
- // It's 1
- euler.x = 0;
- euler.y = -Math_PI / 2.0;
- euler.z = -Math::atan2(elements[0][1], elements[1][1]);
- }
- return euler;
-}
-
-void Basis::set_euler_zyx(const Vector3 &p_euler) {
- real_t c, s;
-
- c = Math::cos(p_euler.x);
- s = Math::sin(p_euler.x);
- Basis xmat(1.0, 0.0, 0.0, 0.0, c, -s, 0.0, s, c);
-
- c = Math::cos(p_euler.y);
- s = Math::sin(p_euler.y);
- Basis ymat(c, 0.0, s, 0.0, 1.0, 0.0, -s, 0.0, c);
-
- c = Math::cos(p_euler.z);
- s = Math::sin(p_euler.z);
- Basis zmat(c, -s, 0.0, s, c, 0.0, 0.0, 0.0, 1.0);
-
- *this = zmat * ymat * xmat;
}
bool Basis::is_equal_approx(const Basis &p_basis) const {
@@ -770,8 +679,8 @@ bool Basis::operator!=(const Basis &p_matrix) const {
Basis::operator String() const {
return "[X: " + get_axis(0).operator String() +
- ", Y: " + get_axis(1).operator String() +
- ", Z: " + get_axis(2).operator String() + "]";
+ ", Y: " + get_axis(1).operator String() +
+ ", Z: " + get_axis(2).operator String() + "]";
}
Quaternion Basis::get_quaternion() const {
@@ -792,9 +701,9 @@ Quaternion Basis::get_quaternion() const {
temp[1] = ((m.elements[0][2] - m.elements[2][0]) * s);
temp[2] = ((m.elements[1][0] - m.elements[0][1]) * s);
} else {
- int i = m.elements[0][0] < m.elements[1][1] ?
- (m.elements[1][1] < m.elements[2][2] ? 2 : 1) :
- (m.elements[0][0] < m.elements[2][2] ? 2 : 0);
+ int i = m.elements[0][0] < m.elements[1][1]
+ ? (m.elements[1][1] < m.elements[2][2] ? 2 : 1)
+ : (m.elements[0][0] < m.elements[2][2] ? 2 : 0);
int j = (i + 1) % 3;
int k = (i + 2) % 3;
diff --git a/core/math/basis.h b/core/math/basis.h
index eb107d7e4e..e2fdb95685 100644
--- a/core/math/basis.h
+++ b/core/math/basis.h
@@ -85,40 +85,35 @@ public:
void rotate(const Quaternion &p_quaternion);
Basis rotated(const Quaternion &p_quaternion) const;
- Vector3 get_rotation_euler() const;
+ enum EulerOrder {
+ EULER_ORDER_XYZ,
+ EULER_ORDER_XZY,
+ EULER_ORDER_YXZ,
+ EULER_ORDER_YZX,
+ EULER_ORDER_ZXY,
+ EULER_ORDER_ZYX
+ };
+
+ Vector3 get_euler_normalized(EulerOrder p_order = EULER_ORDER_YXZ) const;
void get_rotation_axis_angle(Vector3 &p_axis, real_t &p_angle) const;
void get_rotation_axis_angle_local(Vector3 &p_axis, real_t &p_angle) const;
Quaternion get_rotation_quaternion() const;
- Vector3 get_rotation() const { return get_rotation_euler(); };
void rotate_to_align(Vector3 p_start_direction, Vector3 p_end_direction);
Vector3 rotref_posscale_decomposition(Basis &rotref) const;
- Vector3 get_euler_xyz() const;
- void set_euler_xyz(const Vector3 &p_euler);
-
- Vector3 get_euler_xzy() const;
- void set_euler_xzy(const Vector3 &p_euler);
-
- Vector3 get_euler_yzx() const;
- void set_euler_yzx(const Vector3 &p_euler);
-
- Vector3 get_euler_yxz() const;
- void set_euler_yxz(const Vector3 &p_euler);
-
- Vector3 get_euler_zxy() const;
- void set_euler_zxy(const Vector3 &p_euler);
-
- Vector3 get_euler_zyx() const;
- void set_euler_zyx(const Vector3 &p_euler);
+ Vector3 get_euler(EulerOrder p_order = EULER_ORDER_YXZ) const;
+ void set_euler(const Vector3 &p_euler, EulerOrder p_order = EULER_ORDER_YXZ);
+ static Basis from_euler(const Vector3 &p_euler, EulerOrder p_order = EULER_ORDER_YXZ) {
+ Basis b;
+ b.set_euler(p_euler, p_order);
+ return b;
+ }
Quaternion get_quaternion() const;
void set_quaternion(const Quaternion &p_quaternion);
- Vector3 get_euler() const { return get_euler_yxz(); }
- void set_euler(const Vector3 &p_euler) { set_euler_yxz(p_euler); }
-
void get_axis_angle(Vector3 &r_axis, real_t &r_angle) const;
void set_axis_angle(const Vector3 &p_axis, real_t p_phi);
@@ -250,9 +245,6 @@ public:
Basis(const Quaternion &p_quaternion) { set_quaternion(p_quaternion); };
Basis(const Quaternion &p_quaternion, const Vector3 &p_scale) { set_quaternion_scale(p_quaternion, p_scale); }
- Basis(const Vector3 &p_euler) { set_euler(p_euler); }
- Basis(const Vector3 &p_euler, const Vector3 &p_scale) { set_euler_scale(p_euler, p_scale); }
-
Basis(const Vector3 &p_axis, real_t p_phi) { set_axis_angle(p_axis, p_phi); }
Basis(const Vector3 &p_axis, real_t p_phi, const Vector3 &p_scale) { set_axis_angle_scale(p_axis, p_phi, p_scale); }
static Basis from_scale(const Vector3 &p_scale);
@@ -332,7 +324,7 @@ Vector3 Basis::xform_inv(const Vector3 &p_vector) const {
real_t Basis::determinant() const {
return elements[0][0] * (elements[1][1] * elements[2][2] - elements[2][1] * elements[1][2]) -
- elements[1][0] * (elements[0][1] * elements[2][2] - elements[2][1] * elements[0][2]) +
- elements[2][0] * (elements[0][1] * elements[1][2] - elements[1][1] * elements[0][2]);
+ elements[1][0] * (elements[0][1] * elements[2][2] - elements[2][1] * elements[0][2]) +
+ elements[2][0] * (elements[0][1] * elements[1][2] - elements[1][1] * elements[0][2]);
}
#endif // BASIS_H
diff --git a/core/math/bvh.h b/core/math/bvh.h
index 65b8b102a3..c1eff02178 100644
--- a/core/math/bvh.h
+++ b/core/math/bvh.h
@@ -654,7 +654,7 @@ private:
// remove from changed items (not very efficient yet)
for (int n = 0; n < (int)changed_items.size(); n++) {
if (changed_items[n] == p_handle) {
- changed_items.remove_unordered(n);
+ changed_items.remove_at_unordered(n);
// because we are using an unordered remove,
// the last changed item will now be at spot 'n',
diff --git a/core/math/bvh_logic.inc b/core/math/bvh_logic.inc
index afab08f151..c65002a9fd 100644
--- a/core/math/bvh_logic.inc
+++ b/core/math/bvh_logic.inc
@@ -42,24 +42,24 @@ BVHABB_CLASS _logic_abb_merge(const BVHABB_CLASS &a, const BVHABB_CLASS &b) {
//--------------------------------------------------------------------------------------------------
/**
-@file q3DynamicAABBTree.h
-@author Randy Gaul
-@date 10/10/2014
- Copyright (c) 2014 Randy Gaul http://www.randygaul.net
- This software is provided 'as-is', without any express or implied
- warranty. In no event will the authors be held liable for any damages
- arising from the use of this software.
- Permission is granted to anyone to use this software for any purpose,
- including commercial applications, and to alter it and redistribute it
- freely, subject to the following restrictions:
- 1. The origin of this software must not be misrepresented; you must not
- claim that you wrote the original software. If you use this software
- in a product, an acknowledgment in the product documentation would be
- appreciated but is not required.
- 2. Altered source versions must be plainly marked as such, and must not
- be misrepresented as being the original software.
- 3. This notice may not be removed or altered from any source distribution.
-*/
+ * @file q3DynamicAABBTree.h
+ * @author Randy Gaul
+ * @date 10/10/2014
+ * Copyright (c) 2014 Randy Gaul http://www.randygaul.net
+ * This software is provided 'as-is', without any express or implied
+ * warranty. In no event will the authors be held liable for any damages
+ * arising from the use of this software.
+ * Permission is granted to anyone to use this software for any purpose,
+ * including commercial applications, and to alter it and redistribute it
+ * freely, subject to the following restrictions:
+ * 1. The origin of this software must not be misrepresented; you must not
+ * claim that you wrote the original software. If you use this software
+ * in a product, an acknowledgment in the product documentation would be
+ * appreciated but is not required.
+ * 2. Altered source versions must be plainly marked as such, and must not
+ * be misrepresented as being the original software.
+ * 3. This notice may not be removed or altered from any source distribution.
+ */
//--------------------------------------------------------------------------------------------------
// This function is based on the 'Balance' function from Randy Gaul's qu3e
@@ -67,7 +67,7 @@ BVHABB_CLASS _logic_abb_merge(const BVHABB_CLASS &a, const BVHABB_CLASS &b) {
// It is MODIFIED from qu3e version.
// This is the only function used (and _logic_abb_merge helper function).
int32_t _logic_balance(int32_t iA, uint32_t p_tree_id) {
- // return iA; // uncomment this to bypass balance
+ //return iA; // uncomment this to bypass balance
TNode *A = &_nodes[iA];
@@ -75,12 +75,12 @@ int32_t _logic_balance(int32_t iA, uint32_t p_tree_id) {
return iA;
}
- /* A
- / \
- B C
- / \ / \
- D E F G
- */
+ /* A
+ * / \
+ * B C
+ * / \ / \
+ * D E F G
+ */
CRASH_COND(A->num_children != 2);
int32_t iB = A->children[0];
diff --git a/core/math/bvh_pair.inc b/core/math/bvh_pair.inc
index 839db59a3a..a12acec2b6 100644
--- a/core/math/bvh_pair.inc
+++ b/core/math/bvh_pair.inc
@@ -51,7 +51,7 @@ struct ItemPairs {
for (int n = 0; n < num_pairs; n++) {
if (extended_pairs[n].handle == h) {
userdata = extended_pairs[n].userdata;
- extended_pairs.remove_unordered(n);
+ extended_pairs.remove_at_unordered(n);
num_pairs--;
break;
}
diff --git a/core/math/bvh_split.inc b/core/math/bvh_split.inc
index 6f54d06ce7..f19ee8a7da 100644
--- a/core/math/bvh_split.inc
+++ b/core/math/bvh_split.inc
@@ -30,8 +30,8 @@ void _split_leaf_sort_groups_simple(int &num_a, int &num_b, uint16_t *group_a, u
int order[Point::AXIS_COUNT];
- order[0] = size.min_axis();
- order[Point::AXIS_COUNT - 1] = size.max_axis();
+ order[0] = size.min_axis_index();
+ order[Point::AXIS_COUNT - 1] = size.max_axis_index();
static_assert(Point::AXIS_COUNT <= 3);
if (Point::AXIS_COUNT == 3) {
diff --git a/core/math/camera_matrix.cpp b/core/math/camera_matrix.cpp
index 8066a59281..48984c4d5b 100644
--- a/core/math/camera_matrix.cpp
+++ b/core/math/camera_matrix.cpp
@@ -35,17 +35,17 @@
float CameraMatrix::determinant() const {
return matrix[0][3] * matrix[1][2] * matrix[2][1] * matrix[3][0] - matrix[0][2] * matrix[1][3] * matrix[2][1] * matrix[3][0] -
- matrix[0][3] * matrix[1][1] * matrix[2][2] * matrix[3][0] + matrix[0][1] * matrix[1][3] * matrix[2][2] * matrix[3][0] +
- matrix[0][2] * matrix[1][1] * matrix[2][3] * matrix[3][0] - matrix[0][1] * matrix[1][2] * matrix[2][3] * matrix[3][0] -
- matrix[0][3] * matrix[1][2] * matrix[2][0] * matrix[3][1] + matrix[0][2] * matrix[1][3] * matrix[2][0] * matrix[3][1] +
- matrix[0][3] * matrix[1][0] * matrix[2][2] * matrix[3][1] - matrix[0][0] * matrix[1][3] * matrix[2][2] * matrix[3][1] -
- matrix[0][2] * matrix[1][0] * matrix[2][3] * matrix[3][1] + matrix[0][0] * matrix[1][2] * matrix[2][3] * matrix[3][1] +
- matrix[0][3] * matrix[1][1] * matrix[2][0] * matrix[3][2] - matrix[0][1] * matrix[1][3] * matrix[2][0] * matrix[3][2] -
- matrix[0][3] * matrix[1][0] * matrix[2][1] * matrix[3][2] + matrix[0][0] * matrix[1][3] * matrix[2][1] * matrix[3][2] +
- matrix[0][1] * matrix[1][0] * matrix[2][3] * matrix[3][2] - matrix[0][0] * matrix[1][1] * matrix[2][3] * matrix[3][2] -
- matrix[0][2] * matrix[1][1] * matrix[2][0] * matrix[3][3] + matrix[0][1] * matrix[1][2] * matrix[2][0] * matrix[3][3] +
- matrix[0][2] * matrix[1][0] * matrix[2][1] * matrix[3][3] - matrix[0][0] * matrix[1][2] * matrix[2][1] * matrix[3][3] -
- matrix[0][1] * matrix[1][0] * matrix[2][2] * matrix[3][3] + matrix[0][0] * matrix[1][1] * matrix[2][2] * matrix[3][3];
+ matrix[0][3] * matrix[1][1] * matrix[2][2] * matrix[3][0] + matrix[0][1] * matrix[1][3] * matrix[2][2] * matrix[3][0] +
+ matrix[0][2] * matrix[1][1] * matrix[2][3] * matrix[3][0] - matrix[0][1] * matrix[1][2] * matrix[2][3] * matrix[3][0] -
+ matrix[0][3] * matrix[1][2] * matrix[2][0] * matrix[3][1] + matrix[0][2] * matrix[1][3] * matrix[2][0] * matrix[3][1] +
+ matrix[0][3] * matrix[1][0] * matrix[2][2] * matrix[3][1] - matrix[0][0] * matrix[1][3] * matrix[2][2] * matrix[3][1] -
+ matrix[0][2] * matrix[1][0] * matrix[2][3] * matrix[3][1] + matrix[0][0] * matrix[1][2] * matrix[2][3] * matrix[3][1] +
+ matrix[0][3] * matrix[1][1] * matrix[2][0] * matrix[3][2] - matrix[0][1] * matrix[1][3] * matrix[2][0] * matrix[3][2] -
+ matrix[0][3] * matrix[1][0] * matrix[2][1] * matrix[3][2] + matrix[0][0] * matrix[1][3] * matrix[2][1] * matrix[3][2] +
+ matrix[0][1] * matrix[1][0] * matrix[2][3] * matrix[3][2] - matrix[0][0] * matrix[1][1] * matrix[2][3] * matrix[3][2] -
+ matrix[0][2] * matrix[1][1] * matrix[2][0] * matrix[3][3] + matrix[0][1] * matrix[1][2] * matrix[2][0] * matrix[3][3] +
+ matrix[0][2] * matrix[1][0] * matrix[2][1] * matrix[3][3] - matrix[0][0] * matrix[1][2] * matrix[2][1] * matrix[3][3] -
+ matrix[0][1] * matrix[1][0] * matrix[2][2] * matrix[3][3] + matrix[0][0] * matrix[1][1] * matrix[2][2] * matrix[3][3];
}
void CameraMatrix::set_identity() {
diff --git a/core/math/color.cpp b/core/math/color.cpp
index dc86cacf8f..8310c342ed 100644
--- a/core/math/color.cpp
+++ b/core/math/color.cpp
@@ -107,6 +107,39 @@ uint64_t Color::to_rgba64() const {
return c;
}
+String _to_hex(float p_val) {
+ int v = Math::round(p_val * 255);
+ v = CLAMP(v, 0, 255);
+ String ret;
+
+ for (int i = 0; i < 2; i++) {
+ char32_t c[2] = { 0, 0 };
+ int lv = v & 0xF;
+ if (lv < 10) {
+ c[0] = '0' + lv;
+ } else {
+ c[0] = 'a' + lv - 10;
+ }
+
+ v >>= 4;
+ String cs = (const char32_t *)c;
+ ret = cs + ret;
+ }
+
+ return ret;
+}
+
+String Color::to_html(bool p_alpha) const {
+ String txt;
+ txt += _to_hex(r);
+ txt += _to_hex(g);
+ txt += _to_hex(b);
+ if (p_alpha) {
+ txt += _to_hex(a);
+ }
+ return txt;
+}
+
float Color::get_h() const {
float min = MIN(r, g);
min = MIN(min, b);
@@ -249,20 +282,6 @@ Color Color::hex64(uint64_t p_hex) {
return Color(r, g, b, a);
}
-Color Color::from_rgbe9995(uint32_t p_rgbe) {
- float r = p_rgbe & 0x1ff;
- float g = (p_rgbe >> 9) & 0x1ff;
- float b = (p_rgbe >> 18) & 0x1ff;
- float e = (p_rgbe >> 27);
- float m = Math::pow(2, e - 15.0 - 9.0);
-
- float rd = r * m;
- float gd = g * m;
- float bd = b * m;
-
- return Color(rd, gd, bd, 1.0f);
-}
-
static int _parse_col4(const String &p_str, int p_ofs) {
char character = p_str[p_ofs];
@@ -428,43 +447,24 @@ Color Color::from_string(const String &p_string, const Color &p_default) {
}
}
-String _to_hex(float p_val) {
- int v = Math::round(p_val * 255);
- v = CLAMP(v, 0, 255);
- String ret;
-
- for (int i = 0; i < 2; i++) {
- char32_t c[2] = { 0, 0 };
- int lv = v & 0xF;
- if (lv < 10) {
- c[0] = '0' + lv;
- } else {
- c[0] = 'a' + lv - 10;
- }
-
- v >>= 4;
- String cs = (const char32_t *)c;
- ret = cs + ret;
- }
-
- return ret;
+Color Color::from_hsv(float p_h, float p_s, float p_v, float p_alpha) {
+ Color c;
+ c.set_hsv(p_h, p_s, p_v, p_alpha);
+ return c;
}
-String Color::to_html(bool p_alpha) const {
- String txt;
- txt += _to_hex(r);
- txt += _to_hex(g);
- txt += _to_hex(b);
- if (p_alpha) {
- txt += _to_hex(a);
- }
- return txt;
-}
+Color Color::from_rgbe9995(uint32_t p_rgbe) {
+ float r = p_rgbe & 0x1ff;
+ float g = (p_rgbe >> 9) & 0x1ff;
+ float b = (p_rgbe >> 18) & 0x1ff;
+ float e = (p_rgbe >> 27);
+ float m = Math::pow(2, e - 15.0 - 9.0);
-Color Color::from_hsv(float p_h, float p_s, float p_v, float p_a) const {
- Color c;
- c.set_hsv(p_h, p_s, p_v, p_a);
- return c;
+ float rd = r * m;
+ float gd = g * m;
+ float bd = b * m;
+
+ return Color(rd, gd, bd, 1.0f);
}
Color::operator String() const {
diff --git a/core/math/color.h b/core/math/color.h
index a95dbf4f60..ffd0fd8f6e 100644
--- a/core/math/color.h
+++ b/core/math/color.h
@@ -51,6 +51,7 @@ struct Color {
uint64_t to_rgba64() const;
uint64_t to_argb64() const;
uint64_t to_abgr64() const;
+ String to_html(bool p_alpha = true) const;
float get_h() const;
float get_s() const;
float get_v() const;
@@ -189,8 +190,7 @@ struct Color {
static String get_named_color_name(int p_idx);
static Color get_named_color(int p_idx);
static Color from_string(const String &p_string, const Color &p_default);
- String to_html(bool p_alpha = true) const;
- Color from_hsv(float p_h, float p_s, float p_v, float p_a) const;
+ static Color from_hsv(float p_h, float p_s, float p_v, float p_alpha = 1.0);
static Color from_rgbe9995(uint32_t p_rgbe);
_FORCE_INLINE_ bool operator<(const Color &p_color) const; //used in set keys
diff --git a/core/math/convex_hull.cpp b/core/math/convex_hull.cpp
index f67035c803..6f551319df 100644
--- a/core/math/convex_hull.cpp
+++ b/core/math/convex_hull.cpp
@@ -265,8 +265,7 @@ public:
}
int32_t get_sign() const {
- return ((int64_t)high < 0) ? -1 : (high || low) ? 1 :
- 0;
+ return ((int64_t)high < 0) ? -1 : ((high || low) ? 1 : 0);
}
bool operator<(const Int128 &b) const {
@@ -594,8 +593,6 @@ private:
IntermediateHull() {
}
-
- void print();
};
enum Orientation { NONE,
@@ -609,9 +606,9 @@ private:
PagedAllocator<Face> face_pool;
LocalVector<Vertex *> original_vertices;
int32_t merge_stamp = 0;
- int32_t min_axis = 0;
- int32_t med_axis = 0;
- int32_t max_axis = 0;
+ Vector3::Axis min_axis = Vector3::Axis::AXIS_X;
+ Vector3::Axis med_axis = Vector3::Axis::AXIS_X;
+ Vector3::Axis max_axis = Vector3::Axis::AXIS_X;
int32_t used_edge_pairs = 0;
int32_t max_used_edge_pairs = 0;
@@ -737,8 +734,6 @@ int32_t ConvexHullInternal::Rational64::compare(const Rational64 &b) const {
return 0;
}
- // return (numerator * b.denominator > b.numerator * denominator) ? sign : (numerator * b.denominator < b.numerator * denominator) ? -sign : 0;
-
#ifdef USE_X86_64_ASM
int32_t result;
@@ -759,10 +754,9 @@ int32_t ConvexHullInternal::Rational64::compare(const Rational64 &b) const {
: "=&b"(result), [tmp] "=&r"(tmp), "=a"(dummy)
: "a"(denominator), [bn] "g"(b.numerator), [tn] "g"(numerator), [bd] "g"(b.denominator)
: "%rdx", "cc");
- return result ? result ^ sign // if sign is +1, only bit 0 of result is inverted, which does not change the sign of result (and cannot result in zero)
- // if sign is -1, all bits of result are inverted, which changes the sign of result (and again cannot result in zero)
- :
- 0;
+ // if sign is +1, only bit 0 of result is inverted, which does not change the sign of result (and cannot result in zero)
+ // if sign is -1, all bits of result are inverted, which changes the sign of result (and again cannot result in zero)
+ return result ? result ^ sign : 0;
#else
@@ -795,8 +789,7 @@ int32_t ConvexHullInternal::Rational128::compare(const Rational128 &b) const {
int32_t ConvexHullInternal::Rational128::compare(int64_t b) const {
if (is_int_64) {
int64_t a = sign * (int64_t)numerator.low;
- return (a > b) ? 1 : (a < b) ? -1 :
- 0;
+ return (a > b) ? 1 : ((a < b) ? -1 : 0);
}
if (b > 0) {
if (sign <= 0) {
@@ -1448,8 +1441,7 @@ void ConvexHullInternal::merge(IntermediateHull &p_h0, IntermediateHull &p_h1) {
c1->edges = e;
return;
} else {
- int32_t cmp = !min0 ? 1 : !min1 ? -1 :
- min_cot0.compare(min_cot1);
+ int32_t cmp = !min0 ? 1 : (!min1 ? -1 : min_cot0.compare(min_cot1));
#ifdef DEBUG_CONVEX_HULL
printf(" -> Result %d\n", cmp);
#endif
@@ -1593,12 +1585,12 @@ void ConvexHullInternal::compute(const Vector3 *p_coords, int32_t p_count) {
}
Vector3 s = aabb.size;
- max_axis = s.max_axis();
- min_axis = s.min_axis();
+ max_axis = s.max_axis_index();
+ min_axis = s.min_axis_index();
if (min_axis == max_axis) {
- min_axis = (max_axis + 1) % 3;
+ min_axis = Vector3::Axis((max_axis + 1) % 3);
}
- med_axis = 3 - max_axis - min_axis;
+ med_axis = Vector3::Axis(3 - max_axis - min_axis);
s /= real_t(10216);
if (((med_axis + 1) % 3) != max_axis) {
@@ -1696,7 +1688,7 @@ real_t ConvexHullInternal::shrink(real_t p_amount, real_t p_clamp_amount) {
while (stack.size() > 0) {
Vertex *v = stack[stack.size() - 1];
- stack.remove(stack.size() - 1);
+ stack.remove_at(stack.size() - 1);
Edge *e = v->edges;
if (e) {
do {
diff --git a/core/math/delaunay_2d.h b/core/math/delaunay_2d.h
index 2f80cb5634..779ac96b79 100644
--- a/core/math/delaunay_2d.h
+++ b/core/math/delaunay_2d.h
@@ -123,7 +123,7 @@ public:
for (int j = 0; j < triangles.size(); j++) {
if (triangles[j].bad) {
- triangles.remove(j);
+ triangles.remove_at(j);
j--;
}
}
@@ -154,7 +154,7 @@ public:
}
}
if (invalid) {
- triangles.remove(i);
+ triangles.remove_at(i);
i--;
}
}
diff --git a/core/math/expression.cpp b/core/math/expression.cpp
index 05f2c8dac9..fe277cff96 100644
--- a/core/math/expression.cpp
+++ b/core/math/expression.cpp
@@ -410,6 +410,14 @@ Error Expression::_get_token(Token &r_token) {
} else if (id == "self") {
r_token.type = TK_SELF;
} else {
+ for (int i = 0; i < Variant::VARIANT_MAX; i++) {
+ if (id == Variant::get_type_name(Variant::Type(i))) {
+ r_token.type = TK_BASIC_TYPE;
+ r_token.value = i;
+ return OK;
+ }
+ }
+
if (Variant::has_utility_function(id)) {
r_token.type = TK_BUILTIN_FUNC;
r_token.value = id;
@@ -1087,7 +1095,7 @@ Expression::ENode *Expression::_parse_expression() {
op->nodes[1] = nullptr;
expression.write[i].is_op = false;
expression.write[i].node = op;
- expression.remove(i + 1);
+ expression.remove_at(i + 1);
}
} else {
@@ -1119,8 +1127,8 @@ Expression::ENode *Expression::_parse_expression() {
//replace all 3 nodes by this operator and make it an expression
expression.write[next_op - 1].node = op;
- expression.remove(next_op);
- expression.remove(next_op);
+ expression.remove_at(next_op);
+ expression.remove_at(next_op);
}
}
diff --git a/core/math/face3.h b/core/math/face3.h
index 9e9026e54e..0a8c1c6041 100644
--- a/core/math/face3.h
+++ b/core/math/face3.h
@@ -48,13 +48,13 @@ public:
Vector3 vertex[3];
/**
- *
- * @param p_plane plane used to split the face
- * @param p_res array of at least 3 faces, amount used in function return
- * @param p_is_point_over array of at least 3 booleans, determining which face is over the plane, amount used in function return
- * @param _epsilon constant used for numerical error rounding, to add "thickness" to the plane (so coplanar points can happen)
- * @return amount of faces generated by the split, either 0 (means no split possible), 2 or 3
- */
+ *
+ * @param p_plane plane used to split the face
+ * @param p_res array of at least 3 faces, amount used in function return
+ * @param p_is_point_over array of at least 3 booleans, determining which face is over the plane, amount used in function return
+ * @param _epsilon constant used for numerical error rounding, to add "thickness" to the plane (so coplanar points can happen)
+ * @return amount of faces generated by the split, either 0 (means no split possible), 2 or 3
+ */
int split_by_plane(const Plane &p_plane, Face3 *p_res, bool *p_is_point_over) const;
diff --git a/core/math/geometry_2d.h b/core/math/geometry_2d.h
index 8e5830f9b3..028ac0f4eb 100644
--- a/core/math/geometry_2d.h
+++ b/core/math/geometry_2d.h
@@ -37,8 +37,6 @@
#include "core/templates/vector.h"
class Geometry2D {
- Geometry2D();
-
public:
static real_t get_closest_points_between_segments(const Vector2 &p1, const Vector2 &q1, const Vector2 &p2, const Vector2 &q2, Vector2 &c1, Vector2 &c2) {
Vector2 d1 = q1 - p1; // Direction vector of segment S1.
@@ -183,8 +181,7 @@ public:
D = Vector2(D.x * Bn.x + D.y * Bn.y, D.y * Bn.x - D.x * Bn.y);
// Fail if C x B and D x B have the same sign (segments don't intersect).
- // (equivalent to condition (C.y < 0 && D.y < CMP_EPSILON) || (C.y > 0 && D.y > CMP_EPSILON))
- if (C.y * D.y > CMP_EPSILON) {
+ if ((C.y < -CMP_EPSILON && D.y < -CMP_EPSILON) || (C.y > CMP_EPSILON && D.y > CMP_EPSILON)) {
return false;
}
diff --git a/core/math/geometry_3d.h b/core/math/geometry_3d.h
index 766689e222..6a59b34585 100644
--- a/core/math/geometry_3d.h
+++ b/core/math/geometry_3d.h
@@ -36,8 +36,6 @@
#include "core/templates/vector.h"
class Geometry3D {
- Geometry3D();
-
public:
static void get_closest_points_between_segments(const Vector3 &p1, const Vector3 &p2, const Vector3 &q1, const Vector3 &q2, Vector3 &c1, Vector3 &c2) {
// Do the function 'd' as defined by pb. I think it's a dot product of some sort.
diff --git a/core/math/math_defs.h b/core/math/math_defs.h
index c3a8f910c0..1c6139688b 100644
--- a/core/math/math_defs.h
+++ b/core/math/math_defs.h
@@ -68,37 +68,38 @@ enum Orientation {
VERTICAL
};
-enum HAlign {
- HALIGN_LEFT,
- HALIGN_CENTER,
- HALIGN_RIGHT,
- HALIGN_FILL,
+enum HorizontalAlignment {
+ HORIZONTAL_ALIGNMENT_LEFT,
+ HORIZONTAL_ALIGNMENT_CENTER,
+ HORIZONTAL_ALIGNMENT_RIGHT,
+ HORIZONTAL_ALIGNMENT_FILL,
};
-enum VAlign {
- VALIGN_TOP,
- VALIGN_CENTER,
- VALIGN_BOTTOM
+enum VerticalAlignment {
+ VERTICAL_ALIGNMENT_TOP,
+ VERTICAL_ALIGNMENT_CENTER,
+ VERTICAL_ALIGNMENT_BOTTOM,
+ VERTICAL_ALIGNMENT_FILL,
};
-enum InlineAlign {
+enum InlineAlignment {
// Image alignment points.
- INLINE_ALIGN_TOP_TO = 0b0000,
- INLINE_ALIGN_CENTER_TO = 0b0001,
- INLINE_ALIGN_BOTTOM_TO = 0b0010,
- INLINE_ALIGN_IMAGE_MASK = 0b0011,
+ INLINE_ALIGNMENT_TOP_TO = 0b0000,
+ INLINE_ALIGNMENT_CENTER_TO = 0b0001,
+ INLINE_ALIGNMENT_BOTTOM_TO = 0b0010,
+ INLINE_ALIGNMENT_IMAGE_MASK = 0b0011,
// Text alignment points.
- INLINE_ALIGN_TO_TOP = 0b0000,
- INLINE_ALIGN_TO_CENTER = 0b0100,
- INLINE_ALIGN_TO_BASELINE = 0b1000,
- INLINE_ALIGN_TO_BOTTOM = 0b1100,
- INLINE_ALIGN_TEXT_MASK = 0b1100,
+ INLINE_ALIGNMENT_TO_TOP = 0b0000,
+ INLINE_ALIGNMENT_TO_CENTER = 0b0100,
+ INLINE_ALIGNMENT_TO_BASELINE = 0b1000,
+ INLINE_ALIGNMENT_TO_BOTTOM = 0b1100,
+ INLINE_ALIGNMENT_TEXT_MASK = 0b1100,
// Presets.
- INLINE_ALIGN_TOP = INLINE_ALIGN_TOP_TO | INLINE_ALIGN_TO_TOP,
- INLINE_ALIGN_CENTER = INLINE_ALIGN_CENTER_TO | INLINE_ALIGN_TO_CENTER,
- INLINE_ALIGN_BOTTOM = INLINE_ALIGN_BOTTOM_TO | INLINE_ALIGN_TO_BOTTOM
+ INLINE_ALIGNMENT_TOP = INLINE_ALIGNMENT_TOP_TO | INLINE_ALIGNMENT_TO_TOP,
+ INLINE_ALIGNMENT_CENTER = INLINE_ALIGNMENT_CENTER_TO | INLINE_ALIGNMENT_TO_CENTER,
+ INLINE_ALIGNMENT_BOTTOM = INLINE_ALIGNMENT_BOTTOM_TO | INLINE_ALIGNMENT_TO_BOTTOM
};
enum Side {
@@ -116,10 +117,10 @@ enum Corner {
};
/**
- * The "Real" type is an abstract type used for real numbers, such as 1.5,
- * in contrast to integer numbers. Precision can be controlled with the
- * presence or absence of the REAL_T_IS_DOUBLE define.
- */
+ * The "Real" type is an abstract type used for real numbers, such as 1.5,
+ * in contrast to integer numbers. Precision can be controlled with the
+ * presence or absence of the REAL_T_IS_DOUBLE define.
+ */
#ifdef REAL_T_IS_DOUBLE
typedef double real_t;
#else
diff --git a/core/math/math_funcs.cpp b/core/math/math_funcs.cpp
index bbed257f60..2b6d92fe0e 100644
--- a/core/math/math_funcs.cpp
+++ b/core/math/math_funcs.cpp
@@ -53,6 +53,10 @@ uint32_t Math::rand() {
return default_rand.rand();
}
+double Math::randfn(double mean, double deviation) {
+ return default_rand.randfn(mean, deviation);
+}
+
int Math::step_decimals(double p_step) {
static const int maxn = 10;
static const double sd[maxn] = {
diff --git a/core/math/math_funcs.h b/core/math/math_funcs.h
index 4e4f566517..8df45255c9 100644
--- a/core/math/math_funcs.h
+++ b/core/math/math_funcs.h
@@ -159,7 +159,7 @@ public:
} ieee754;
ieee754.f = p_val;
return ((unsigned)(ieee754.u >> 32) & 0x7fffffff) == 0x7ff00000 &&
- ((unsigned)ieee754.u == 0);
+ ((unsigned)ieee754.u == 0);
#else
return isinf(p_val);
#endif
@@ -266,8 +266,8 @@ public:
float s = CLAMP((p_s - p_from) / (p_to - p_from), 0.0f, 1.0f);
return s * s * (3.0f - 2.0f * s);
}
- static _ALWAYS_INLINE_ double move_toward(double p_from, double p_to, double p_delta) { return abs(p_to - p_from) <= p_delta ? p_to : p_from + SGN(p_to - p_from) * p_delta; }
- static _ALWAYS_INLINE_ float move_toward(float p_from, float p_to, float p_delta) { return abs(p_to - p_from) <= p_delta ? p_to : p_from + SGN(p_to - p_from) * p_delta; }
+ static _ALWAYS_INLINE_ double move_toward(double p_from, double p_to, double p_delta) { return abs(p_to - p_from) <= p_delta ? p_to : p_from + SIGN(p_to - p_from) * p_delta; }
+ static _ALWAYS_INLINE_ float move_toward(float p_from, float p_to, float p_delta) { return abs(p_to - p_from) <= p_delta ? p_to : p_from + SIGN(p_to - p_from) * p_delta; }
static _ALWAYS_INLINE_ double linear2db(double p_linear) { return Math::log(p_linear) * 8.6858896380650365530225783783321; }
static _ALWAYS_INLINE_ float linear2db(float p_linear) { return Math::log(p_linear) * 8.6858896380650365530225783783321; }
@@ -291,6 +291,19 @@ public:
return is_zero_approx(range) ? min : value - (range * Math::floor((value - min) / range));
}
+ static _ALWAYS_INLINE_ float fract(float value) {
+ return value - floor(value);
+ }
+ static _ALWAYS_INLINE_ double fract(double value) {
+ return value - floor(value);
+ }
+ static _ALWAYS_INLINE_ float pingpong(float value, float length) {
+ return (length != 0.0f) ? abs(fract((value - length) / (length * 2.0f)) * length * 2.0f - length) : 0.0f;
+ }
+ static _ALWAYS_INLINE_ double pingpong(double value, double length) {
+ return (length != 0.0) ? abs(fract((value - length) / (length * 2.0)) * length * 2.0 - length) : 0.0;
+ }
+
// double only, as these functions are mainly used by the editor and not performance-critical,
static double ease(double p_x, double p_c);
static int step_decimals(double p_step);
@@ -305,6 +318,7 @@ public:
static uint32_t rand();
static _ALWAYS_INLINE_ double randd() { return (double)rand() / (double)Math::RANDOM_32BIT_MAX; }
static _ALWAYS_INLINE_ float randf() { return (float)rand() / (float)Math::RANDOM_32BIT_MAX; }
+ static double randfn(double mean, double deviation);
static double random(double from, double to);
static float random(float from, float to);
@@ -461,7 +475,7 @@ public:
mantissa = 0;
}
hf = (((uint16_t)sign) << 15) | (uint16_t)((0x1F << 10)) |
- (uint16_t)(mantissa >> 13);
+ (uint16_t)(mantissa >> 13);
}
// check if exponent is <= -15
else if (exp <= 0x38000000) {
@@ -474,8 +488,8 @@ public:
hf = 0; //denormals do not work for 3D, convert to zero
} else {
hf = (((uint16_t)sign) << 15) |
- (uint16_t)((exp - 0x38000000) >> 13) |
- (uint16_t)(mantissa >> 13);
+ (uint16_t)((exp - 0x38000000) >> 13) |
+ (uint16_t)(mantissa >> 13);
}
return hf;
diff --git a/core/math/plane.cpp b/core/math/plane.cpp
index 3c78b55b90..59f7918258 100644
--- a/core/math/plane.cpp
+++ b/core/math/plane.cpp
@@ -88,7 +88,7 @@ bool Plane::intersect_3(const Plane &p_plane1, const Plane &p_plane2, Vector3 *r
*r_result = ((vec3_cross(normal1, normal2) * p_plane0.d) +
(vec3_cross(normal2, normal0) * p_plane1.d) +
(vec3_cross(normal0, normal1) * p_plane2.d)) /
- denom;
+ denom;
}
return true;
diff --git a/core/math/quaternion.cpp b/core/math/quaternion.cpp
index 3f1d2c58e5..944474686a 100644
--- a/core/math/quaternion.cpp
+++ b/core/math/quaternion.cpp
@@ -44,7 +44,7 @@ real_t Quaternion::angle_to(const Quaternion &p_to) const {
// This implementation uses XYZ convention (Z is the first rotation).
Vector3 Quaternion::get_euler_xyz() const {
Basis m(*this);
- return m.get_euler_xyz();
+ return m.get_euler(Basis::EULER_ORDER_XYZ);
}
// get_euler_yxz returns a vector containing the Euler angles in the format
@@ -56,7 +56,7 @@ Vector3 Quaternion::get_euler_yxz() const {
ERR_FAIL_COND_V_MSG(!is_normalized(), Vector3(0, 0, 0), "The quaternion must be normalized.");
#endif
Basis m(*this);
- return m.get_euler_yxz();
+ return m.get_euler(Basis::EULER_ORDER_YXZ);
}
void Quaternion::operator*=(const Quaternion &p_q) {
@@ -189,6 +189,15 @@ Quaternion::operator String() const {
return "(" + String::num_real(x, false) + ", " + String::num_real(y, false) + ", " + String::num_real(z, false) + ", " + String::num_real(w, false) + ")";
}
+Vector3 Quaternion::get_axis() const {
+ real_t r = ((real_t)1) / Math::sqrt(1 - w * w);
+ return Vector3(x * r, y * r, z * r);
+}
+
+float Quaternion::get_angle() const {
+ return 2 * Math::acos(w);
+}
+
Quaternion::Quaternion(const Vector3 &p_axis, real_t p_angle) {
#ifdef MATH_CHECKS
ERR_FAIL_COND_MSG(!p_axis.is_normalized(), "The axis Vector3 must be normalized.");
diff --git a/core/math/quaternion.h b/core/math/quaternion.h
index 35324323b3..457d167516 100644
--- a/core/math/quaternion.h
+++ b/core/math/quaternion.h
@@ -72,6 +72,9 @@ public:
Quaternion slerpni(const Quaternion &p_to, const real_t &p_weight) const;
Quaternion cubic_slerp(const Quaternion &p_b, const Quaternion &p_pre_a, const Quaternion &p_post_b, const real_t &p_weight) const;
+ Vector3 get_axis() const;
+ float get_angle() const;
+
_FORCE_INLINE_ void get_axis_angle(Vector3 &r_axis, real_t &r_angle) const {
r_angle = 2 * Math::acos(w);
real_t r = ((real_t)1) / Math::sqrt(1 - w * w);
@@ -83,13 +86,6 @@ public:
void operator*=(const Quaternion &p_q);
Quaternion operator*(const Quaternion &p_q) const;
- Quaternion operator*(const Vector3 &v) const {
- return Quaternion(w * v.x + y * v.z - z * v.y,
- w * v.y + z * v.x - x * v.z,
- w * v.z + x * v.y - y * v.x,
- -x * v.x - y * v.y - z * v.z);
- }
-
_FORCE_INLINE_ Vector3 xform(const Vector3 &v) const {
#ifdef MATH_CHECKS
ERR_FAIL_COND_V_MSG(!is_normalized(), v, "The quaternion must be normalized.");
@@ -138,12 +134,11 @@ public:
w(p_q.w) {
}
- Quaternion &operator=(const Quaternion &p_q) {
+ void operator=(const Quaternion &p_q) {
x = p_q.x;
y = p_q.y;
z = p_q.z;
w = p_q.w;
- return *this;
}
Quaternion(const Vector3 &v0, const Vector3 &v1) // shortest arc
diff --git a/core/math/rect2.cpp b/core/math/rect2.cpp
index f64bf560c8..0e6127b017 100644
--- a/core/math/rect2.cpp
+++ b/core/math/rect2.cpp
@@ -35,6 +35,11 @@ bool Rect2::is_equal_approx(const Rect2 &p_rect) const {
}
bool Rect2::intersects_segment(const Point2 &p_from, const Point2 &p_to, Point2 *r_pos, Point2 *r_normal) const {
+#ifdef MATH_CHECKS
+ if (unlikely(size.x < 0 || size.y < 0)) {
+ ERR_PRINT("Rect2 size is negative, this is not supported. Use Rect2.abs() to get a Rect2 with a positive size.");
+ }
+#endif
real_t min = 0, max = 1;
int axis = 0;
real_t sign = 0;
@@ -95,6 +100,11 @@ bool Rect2::intersects_segment(const Point2 &p_from, const Point2 &p_to, Point2
}
bool Rect2::intersects_transformed(const Transform2D &p_xform, const Rect2 &p_rect) const {
+#ifdef MATH_CHECKS
+ if (unlikely(size.x < 0 || size.y < 0 || p_rect.size.x < 0 || p_rect.size.y < 0)) {
+ ERR_PRINT("Rect2 size is negative, this is not supported. Use Rect2.abs() to get a Rect2 with a positive size.");
+ }
+#endif
//SAT intersection between local and transformed rect2
Vector2 xf_points[4] = {
diff --git a/core/math/rect2.h b/core/math/rect2.h
index 2557959fa2..7029204cf1 100644
--- a/core/math/rect2.h
+++ b/core/math/rect2.h
@@ -49,6 +49,11 @@ struct Rect2 {
_FORCE_INLINE_ Vector2 get_center() const { return position + (size * 0.5); }
inline bool intersects(const Rect2 &p_rect, const bool p_include_borders = false) const {
+#ifdef MATH_CHECKS
+ if (unlikely(size.x < 0 || size.y < 0 || p_rect.size.x < 0 || p_rect.size.y < 0)) {
+ ERR_PRINT("Rect2 size is negative, this is not supported. Use Rect2.abs() to get a Rect2 with a positive size.");
+ }
+#endif
if (p_include_borders) {
if (position.x > (p_rect.position.x + p_rect.size.width)) {
return false;
@@ -81,6 +86,11 @@ struct Rect2 {
}
inline real_t distance_to(const Vector2 &p_point) const {
+#ifdef MATH_CHECKS
+ if (unlikely(size.x < 0 || size.y < 0)) {
+ ERR_PRINT("Rect2 size is negative, this is not supported. Use Rect2.abs() to get a Rect2 with a positive size.");
+ }
+#endif
real_t dist = 0.0;
bool inside = true;
@@ -117,9 +127,14 @@ struct Rect2 {
bool intersects_segment(const Point2 &p_from, const Point2 &p_to, Point2 *r_pos = nullptr, Point2 *r_normal = nullptr) const;
inline bool encloses(const Rect2 &p_rect) const {
+#ifdef MATH_CHECKS
+ if (unlikely(size.x < 0 || size.y < 0 || p_rect.size.x < 0 || p_rect.size.y < 0)) {
+ ERR_PRINT("Rect2 size is negative, this is not supported. Use Rect2.abs() to get a Rect2 with a positive size.");
+ }
+#endif
return (p_rect.position.x >= position.x) && (p_rect.position.y >= position.y) &&
- ((p_rect.position.x + p_rect.size.x) <= (position.x + size.x)) &&
- ((p_rect.position.y + p_rect.size.y) <= (position.y + size.y));
+ ((p_rect.position.x + p_rect.size.x) <= (position.x + size.x)) &&
+ ((p_rect.position.y + p_rect.size.y) <= (position.y + size.y));
}
_FORCE_INLINE_ bool has_no_area() const {
@@ -147,7 +162,11 @@ struct Rect2 {
}
inline Rect2 merge(const Rect2 &p_rect) const { ///< return a merged rect
-
+#ifdef MATH_CHECKS
+ if (unlikely(size.x < 0 || size.y < 0 || p_rect.size.x < 0 || p_rect.size.y < 0)) {
+ ERR_PRINT("Rect2 size is negative, this is not supported. Use Rect2.abs() to get a Rect2 with a positive size.");
+ }
+#endif
Rect2 new_rect;
new_rect.position.x = MIN(p_rect.position.x, position.x);
@@ -161,6 +180,11 @@ struct Rect2 {
return new_rect;
}
inline bool has_point(const Point2 &p_point) const {
+#ifdef MATH_CHECKS
+ if (unlikely(size.x < 0 || size.y < 0)) {
+ ERR_PRINT("Rect2 size is negative, this is not supported. Use Rect2.abs() to get a Rect2 with a positive size.");
+ }
+#endif
if (p_point.x < position.x) {
return false;
}
@@ -183,6 +207,11 @@ struct Rect2 {
bool operator!=(const Rect2 &p_rect) const { return position != p_rect.position || size != p_rect.size; }
inline Rect2 grow(real_t p_amount) const {
+#ifdef MATH_CHECKS
+ if (unlikely(size.x < 0 || size.y < 0)) {
+ ERR_PRINT("Rect2 size is negative, this is not supported. Use Rect2.abs() to get a Rect2 with a positive size.");
+ }
+#endif
Rect2 g = *this;
g.grow_by(p_amount);
return g;
@@ -209,6 +238,11 @@ struct Rect2 {
}
inline Rect2 grow_individual(real_t p_left, real_t p_top, real_t p_right, real_t p_bottom) const {
+#ifdef MATH_CHECKS
+ if (unlikely(size.x < 0 || size.y < 0)) {
+ ERR_PRINT("Rect2 size is negative, this is not supported. Use Rect2.abs() to get a Rect2 with a positive size.");
+ }
+#endif
Rect2 g = *this;
g.position.x -= p_left;
g.position.y -= p_top;
@@ -225,7 +259,11 @@ struct Rect2 {
}
inline void expand_to(const Vector2 &p_vector) { //in place function for speed
-
+#ifdef MATH_CHECKS
+ if (unlikely(size.x < 0 || size.y < 0)) {
+ ERR_PRINT("Rect2 size is negative, this is not supported. Use Rect2.abs() to get a Rect2 with a positive size.");
+ }
+#endif
Vector2 begin = position;
Vector2 end = position + size;
@@ -257,7 +295,7 @@ struct Rect2 {
return Vector2(
(p_normal.x > 0) ? -half_extents.x : half_extents.x,
(p_normal.y > 0) ? -half_extents.y : half_extents.y) +
- ofs;
+ ofs;
}
_FORCE_INLINE_ bool intersects_filled_polygon(const Vector2 *p_points, int p_point_count) const {
@@ -349,6 +387,11 @@ struct Rect2i {
_FORCE_INLINE_ Vector2i get_center() const { return position + (size / 2); }
inline bool intersects(const Rect2i &p_rect) const {
+#ifdef MATH_CHECKS
+ if (unlikely(size.x < 0 || size.y < 0 || p_rect.size.x < 0 || p_rect.size.y < 0)) {
+ ERR_PRINT("Rect2i size is negative, this is not supported. Use Rect2i.abs() to get a Rect2i with a positive size.");
+ }
+#endif
if (position.x > (p_rect.position.x + p_rect.size.width)) {
return false;
}
@@ -366,9 +409,14 @@ struct Rect2i {
}
inline bool encloses(const Rect2i &p_rect) const {
+#ifdef MATH_CHECKS
+ if (unlikely(size.x < 0 || size.y < 0 || p_rect.size.x < 0 || p_rect.size.y < 0)) {
+ ERR_PRINT("Rect2i size is negative, this is not supported. Use Rect2i.abs() to get a Rect2i with a positive size.");
+ }
+#endif
return (p_rect.position.x >= position.x) && (p_rect.position.y >= position.y) &&
- ((p_rect.position.x + p_rect.size.x) < (position.x + size.x)) &&
- ((p_rect.position.y + p_rect.size.y) < (position.y + size.y));
+ ((p_rect.position.x + p_rect.size.x) < (position.x + size.x)) &&
+ ((p_rect.position.y + p_rect.size.y) < (position.y + size.y));
}
_FORCE_INLINE_ bool has_no_area() const {
@@ -389,14 +437,18 @@ struct Rect2i {
Point2i p_rect_end = p_rect.position + p_rect.size;
Point2i end = position + size;
- new_rect.size.x = (int)(MIN(p_rect_end.x, end.x) - new_rect.position.x);
- new_rect.size.y = (int)(MIN(p_rect_end.y, end.y) - new_rect.position.y);
+ new_rect.size.x = MIN(p_rect_end.x, end.x) - new_rect.position.x;
+ new_rect.size.y = MIN(p_rect_end.y, end.y) - new_rect.position.y;
return new_rect;
}
inline Rect2i merge(const Rect2i &p_rect) const { ///< return a merged rect
-
+#ifdef MATH_CHECKS
+ if (unlikely(size.x < 0 || size.y < 0 || p_rect.size.x < 0 || p_rect.size.y < 0)) {
+ ERR_PRINT("Rect2i size is negative, this is not supported. Use Rect2i.abs() to get a Rect2i with a positive size.");
+ }
+#endif
Rect2i new_rect;
new_rect.position.x = MIN(p_rect.position.x, position.x);
@@ -410,6 +462,11 @@ struct Rect2i {
return new_rect;
}
bool has_point(const Point2i &p_point) const {
+#ifdef MATH_CHECKS
+ if (unlikely(size.x < 0 || size.y < 0)) {
+ ERR_PRINT("Rect2i size is negative, this is not supported. Use Rect2i.abs() to get a Rect2i with a positive size.");
+ }
+#endif
if (p_point.x < position.x) {
return false;
}
@@ -431,6 +488,11 @@ struct Rect2i {
bool operator!=(const Rect2i &p_rect) const { return position != p_rect.position || size != p_rect.size; }
Rect2i grow(int p_amount) const {
+#ifdef MATH_CHECKS
+ if (unlikely(size.x < 0 || size.y < 0)) {
+ ERR_PRINT("Rect2i size is negative, this is not supported. Use Rect2i.abs() to get a Rect2i with a positive size.");
+ }
+#endif
Rect2i g = *this;
g.position.x -= p_amount;
g.position.y -= p_amount;
@@ -453,6 +515,11 @@ struct Rect2i {
}
inline Rect2i grow_individual(int p_left, int p_top, int p_right, int p_bottom) const {
+#ifdef MATH_CHECKS
+ if (unlikely(size.x < 0 || size.y < 0)) {
+ ERR_PRINT("Rect2i size is negative, this is not supported. Use Rect2i.abs() to get a Rect2i with a positive size.");
+ }
+#endif
Rect2i g = *this;
g.position.x -= p_left;
g.position.y -= p_top;
@@ -469,6 +536,11 @@ struct Rect2i {
}
inline void expand_to(const Point2i &p_vector) {
+#ifdef MATH_CHECKS
+ if (unlikely(size.x < 0 || size.y < 0)) {
+ ERR_PRINT("Rect2i size is negative, this is not supported. Use Rect2i.abs() to get a Rect2i with a positive size.");
+ }
+#endif
Point2i begin = position;
Point2i end = position + size;
diff --git a/core/math/transform_2d.cpp b/core/math/transform_2d.cpp
index 496a557844..4bdeaa2a58 100644
--- a/core/math/transform_2d.cpp
+++ b/core/math/transform_2d.cpp
@@ -69,12 +69,12 @@ void Transform2D::rotate(const real_t p_phi) {
real_t Transform2D::get_skew() const {
real_t det = basis_determinant();
- return Math::acos(elements[0].normalized().dot(SGN(det) * elements[1].normalized())) - Math_PI * 0.5;
+ return Math::acos(elements[0].normalized().dot(SIGN(det) * elements[1].normalized())) - Math_PI * 0.5;
}
void Transform2D::set_skew(const real_t p_angle) {
real_t det = basis_determinant();
- elements[1] = SGN(det) * elements[0].rotated((Math_PI * 0.5 + p_angle)).normalized() * elements[1].length();
+ elements[1] = SIGN(det) * elements[0].rotated((Math_PI * 0.5 + p_angle)).normalized() * elements[1].length();
}
real_t Transform2D::get_rotation() const {
@@ -111,7 +111,7 @@ Transform2D::Transform2D(const real_t p_rot, const Size2 &p_scale, const real_t
}
Size2 Transform2D::get_scale() const {
- real_t det_sign = SGN(basis_determinant());
+ real_t det_sign = SIGN(basis_determinant());
return Size2(elements[0].length(), det_sign * elements[1].length());
}
@@ -298,6 +298,6 @@ Transform2D Transform2D::operator*(const real_t p_val) const {
Transform2D::operator String() const {
return "[X: " + elements[0].operator String() +
- ", Y: " + elements[1].operator String() +
- ", O: " + elements[2].operator String() + "]";
+ ", Y: " + elements[1].operator String() +
+ ", O: " + elements[2].operator String() + "]";
}
diff --git a/core/math/transform_2d.h b/core/math/transform_2d.h
index 6ed3af2ba7..8a0e876d96 100644
--- a/core/math/transform_2d.h
+++ b/core/math/transform_2d.h
@@ -164,7 +164,7 @@ Vector2 Transform2D::xform(const Vector2 &p_vec) const {
return Vector2(
tdotx(p_vec),
tdoty(p_vec)) +
- elements[2];
+ elements[2];
}
Vector2 Transform2D::xform_inv(const Vector2 &p_vec) const {
diff --git a/core/math/transform_3d.cpp b/core/math/transform_3d.cpp
index 4f4943c8ef..78ef117443 100644
--- a/core/math/transform_3d.cpp
+++ b/core/math/transform_3d.cpp
@@ -175,9 +175,9 @@ Transform3D Transform3D::operator*(const real_t p_val) const {
Transform3D::operator String() const {
return "[X: " + basis.get_axis(0).operator String() +
- ", Y: " + basis.get_axis(1).operator String() +
- ", Z: " + basis.get_axis(2).operator String() +
- ", O: " + origin.operator String() + "]";
+ ", Y: " + basis.get_axis(1).operator String() +
+ ", Z: " + basis.get_axis(2).operator String() +
+ ", O: " + origin.operator String() + "]";
}
Transform3D::Transform3D(const Basis &p_basis, const Vector3 &p_origin) :
diff --git a/core/math/triangulate.cpp b/core/math/triangulate.cpp
index fa1588dbc5..28f1d96b14 100644
--- a/core/math/triangulate.cpp
+++ b/core/math/triangulate.cpp
@@ -42,18 +42,13 @@ real_t Triangulate::get_area(const Vector<Vector2> &contour) {
return A * 0.5;
}
-/*
- is_inside_triangle decides if a point P is Inside of the triangle
- defined by A, B, C.
- */
-
+/* `is_inside_triangle` decides if a point P is inside the triangle
+ * defined by A, B, C. */
bool Triangulate::is_inside_triangle(real_t Ax, real_t Ay,
real_t Bx, real_t By,
real_t Cx, real_t Cy,
real_t Px, real_t Py,
- bool include_edges)
-
-{
+ bool include_edges) {
real_t ax, ay, bx, by, cx, cy, apx, apy, bpx, bpy, cpx, cpy;
real_t cCROSSap, bCROSScp, aCROSSbp;
diff --git a/core/math/vector2.cpp b/core/math/vector2.cpp
index 16e43d7d06..718e94eee4 100644
--- a/core/math/vector2.cpp
+++ b/core/math/vector2.cpp
@@ -79,7 +79,7 @@ real_t Vector2::angle_to(const Vector2 &p_vector2) const {
}
real_t Vector2::angle_to_point(const Vector2 &p_vector2) const {
- return (*this - p_vector2).angle();
+ return (p_vector2 - *this).angle();
}
real_t Vector2::dot(const Vector2 &p_other) const {
@@ -91,7 +91,7 @@ real_t Vector2::cross(const Vector2 &p_other) const {
}
Vector2 Vector2::sign() const {
- return Vector2(SGN(x), SGN(y));
+ return Vector2(SIGN(x), SIGN(y));
}
Vector2 Vector2::floor() const {
@@ -160,10 +160,11 @@ Vector2 Vector2::cubic_interpolate(const Vector2 &p_b, const Vector2 &p_pre_a, c
real_t t3 = t2 * t;
Vector2 out;
- out = 0.5 * ((p1 * 2.0) +
- (-p0 + p2) * t +
- (2.0 * p0 - 5.0 * p1 + 4 * p2 - p3) * t2 +
- (-p0 + 3.0 * p1 - 3.0 * p2 + p3) * t3);
+ out = 0.5 *
+ ((p1 * 2.0) +
+ (-p0 + p2) * t +
+ (2.0 * p0 - 5.0 * p1 + 4 * p2 - p3) * t2 +
+ (-p0 + 3.0 * p1 - 3.0 * p2 + p3) * t3);
return out;
}
diff --git a/core/math/vector2.h b/core/math/vector2.h
index 332c0475fa..c0a189e040 100644
--- a/core/math/vector2.h
+++ b/core/math/vector2.h
@@ -70,12 +70,12 @@ struct Vector2 {
x = y = p_value;
}
- _FORCE_INLINE_ int min_axis() const {
- return x < y ? 0 : 1;
+ _FORCE_INLINE_ Vector2::Axis min_axis_index() const {
+ return x < y ? Vector2::AXIS_X : Vector2::AXIS_Y;
}
- _FORCE_INLINE_ int max_axis() const {
- return x < y ? 1 : 0;
+ _FORCE_INLINE_ Vector2::Axis max_axis_index() const {
+ return x < y ? Vector2::AXIS_Y : Vector2::AXIS_X;
}
void normalize();
@@ -301,12 +301,12 @@ struct Vector2i {
return p_idx ? y : x;
}
- _FORCE_INLINE_ int min_axis() const {
- return x < y ? 0 : 1;
+ _FORCE_INLINE_ Vector2i::Axis min_axis_index() const {
+ return x < y ? Vector2i::AXIS_X : Vector2i::AXIS_Y;
}
- _FORCE_INLINE_ int max_axis() const {
- return x < y ? 1 : 0;
+ _FORCE_INLINE_ Vector2i::Axis max_axis_index() const {
+ return x < y ? Vector2i::AXIS_Y : Vector2i::AXIS_X;
}
Vector2i min(const Vector2i &p_vector2i) const {
@@ -345,7 +345,7 @@ struct Vector2i {
bool operator!=(const Vector2i &p_vec2) const;
real_t aspect() const { return width / (real_t)height; }
- Vector2i sign() const { return Vector2i(SGN(x), SGN(y)); }
+ Vector2i sign() const { return Vector2i(SIGN(x), SIGN(y)); }
Vector2i abs() const { return Vector2i(ABS(x), ABS(y)); }
Vector2i clamp(const Vector2i &p_min, const Vector2i &p_max) const;
diff --git a/core/math/vector3.cpp b/core/math/vector3.cpp
index fa212c178a..b9bd04b8c1 100644
--- a/core/math/vector3.cpp
+++ b/core/math/vector3.cpp
@@ -93,10 +93,11 @@ Vector3 Vector3::cubic_interpolate(const Vector3 &p_b, const Vector3 &p_pre_a, c
real_t t3 = t2 * t;
Vector3 out;
- out = 0.5 * ((p1 * 2.0) +
- (-p0 + p2) * t +
- (2.0 * p0 - 5.0 * p1 + 4.0 * p2 - p3) * t2 +
- (-p0 + 3.0 * p1 - 3.0 * p2 + p3) * t3);
+ out = 0.5 *
+ ((p1 * 2.0) +
+ (-p0 + p2) * t +
+ (2.0 * p0 - 5.0 * p1 + 4.0 * p2 - p3) * t2 +
+ (-p0 + 3.0 * p1 - 3.0 * p2 + p3) * t3);
return out;
}
@@ -107,10 +108,10 @@ Vector3 Vector3::move_toward(const Vector3 &p_to, const real_t p_delta) const {
return len <= p_delta || len < CMP_EPSILON ? p_to : v + vd / len * p_delta;
}
-Basis Vector3::outer(const Vector3 &p_b) const {
- Vector3 row0(x * p_b.x, x * p_b.y, x * p_b.z);
- Vector3 row1(y * p_b.x, y * p_b.y, y * p_b.z);
- Vector3 row2(z * p_b.x, z * p_b.y, z * p_b.z);
+Basis Vector3::outer(const Vector3 &p_with) const {
+ Vector3 row0(x * p_with.x, x * p_with.y, x * p_with.z);
+ Vector3 row1(y * p_with.x, y * p_with.y, y * p_with.z);
+ Vector3 row2(z * p_with.x, z * p_with.y, z * p_with.z);
return Basis(row0, row1, row2);
}
diff --git a/core/math/vector3.h b/core/math/vector3.h
index e65ac31c02..c0f80e8f11 100644
--- a/core/math/vector3.h
+++ b/core/math/vector3.h
@@ -32,9 +32,9 @@
#define VECTOR3_H
#include "core/math/math_funcs.h"
+#include "core/math/vector2.h"
#include "core/math/vector3i.h"
#include "core/string/ustring.h"
-
class Basis;
struct Vector3 {
@@ -71,12 +71,12 @@ struct Vector3 {
x = y = z = p_value;
}
- _FORCE_INLINE_ int min_axis() const {
- return x < y ? (x < z ? 0 : 2) : (y < z ? 1 : 2);
+ _FORCE_INLINE_ Vector3::Axis min_axis_index() const {
+ return x < y ? (x < z ? Vector3::AXIS_X : Vector3::AXIS_Z) : (y < z ? Vector3::AXIS_Y : Vector3::AXIS_Z);
}
- _FORCE_INLINE_ int max_axis() const {
- return x < y ? (y < z ? 2 : 1) : (x < z ? 2 : 0);
+ _FORCE_INLINE_ Vector3::Axis max_axis_index() const {
+ return x < y ? (y < z ? Vector3::AXIS_Z : Vector3::AXIS_Y) : (x < z ? Vector3::AXIS_Z : Vector3::AXIS_X);
}
_FORCE_INLINE_ real_t length() const;
@@ -103,9 +103,34 @@ struct Vector3 {
Vector3 cubic_interpolate(const Vector3 &p_b, const Vector3 &p_pre_a, const Vector3 &p_post_b, const real_t p_weight) const;
Vector3 move_toward(const Vector3 &p_to, const real_t p_delta) const;
- _FORCE_INLINE_ Vector3 cross(const Vector3 &p_b) const;
- _FORCE_INLINE_ real_t dot(const Vector3 &p_b) const;
- Basis outer(const Vector3 &p_b) const;
+ _FORCE_INLINE_ Vector2 octahedron_encode() const {
+ Vector3 n = *this;
+ n /= Math::abs(n.x) + Math::abs(n.y) + Math::abs(n.z);
+ Vector2 o;
+ if (n.z >= 0.0) {
+ o.x = n.x;
+ o.y = n.y;
+ } else {
+ o.x = (1.0 - Math::abs(n.y)) * (n.x >= 0.0 ? 1.0 : -1.0);
+ o.y = (1.0 - Math::abs(n.x)) * (n.y >= 0.0 ? 1.0 : -1.0);
+ }
+ o.x = o.x * 0.5 + 0.5;
+ o.y = o.y * 0.5 + 0.5;
+ return o;
+ }
+
+ static _FORCE_INLINE_ Vector3 octahedron_decode(const Vector2 &p_oct) {
+ Vector2 f(p_oct.x * 2.0 - 1.0, p_oct.y * 2.0 - 1.0);
+ Vector3 n(f.x, f.y, 1.0f - Math::abs(f.x) - Math::abs(f.y));
+ float t = CLAMP(-n.z, 0.0, 1.0);
+ n.x += n.x >= 0 ? -t : t;
+ n.y += n.y >= 0 ? -t : t;
+ return n.normalized();
+ }
+
+ _FORCE_INLINE_ Vector3 cross(const Vector3 &p_with) const;
+ _FORCE_INLINE_ real_t dot(const Vector3 &p_with) const;
+ Basis outer(const Vector3 &p_with) const;
_FORCE_INLINE_ Vector3 abs() const;
_FORCE_INLINE_ Vector3 floor() const;
@@ -174,17 +199,17 @@ struct Vector3 {
}
};
-Vector3 Vector3::cross(const Vector3 &p_b) const {
+Vector3 Vector3::cross(const Vector3 &p_with) const {
Vector3 ret(
- (y * p_b.z) - (z * p_b.y),
- (z * p_b.x) - (x * p_b.z),
- (x * p_b.y) - (y * p_b.x));
+ (y * p_with.z) - (z * p_with.y),
+ (z * p_with.x) - (x * p_with.z),
+ (x * p_with.y) - (y * p_with.x));
return ret;
}
-real_t Vector3::dot(const Vector3 &p_b) const {
- return x * p_b.x + y * p_b.y + z * p_b.z;
+real_t Vector3::dot(const Vector3 &p_with) const {
+ return x * p_with.x + y * p_with.y + z * p_with.z;
}
Vector3 Vector3::abs() const {
@@ -192,7 +217,7 @@ Vector3 Vector3::abs() const {
}
Vector3 Vector3::sign() const {
- return Vector3(SGN(x), SGN(y), SGN(z));
+ return Vector3(SIGN(x), SIGN(y), SIGN(z));
}
Vector3 Vector3::floor() const {
diff --git a/core/math/vector3i.cpp b/core/math/vector3i.cpp
index d3a57af77c..7812a0b41c 100644
--- a/core/math/vector3i.cpp
+++ b/core/math/vector3i.cpp
@@ -40,12 +40,12 @@ int32_t Vector3i::get_axis(const int p_axis) const {
return operator[](p_axis);
}
-int Vector3i::min_axis() const {
- return x < y ? (x < z ? 0 : 2) : (y < z ? 1 : 2);
+Vector3i::Axis Vector3i::min_axis_index() const {
+ return x < y ? (x < z ? Vector3i::AXIS_X : Vector3i::AXIS_Z) : (y < z ? Vector3i::AXIS_Y : Vector3i::AXIS_Z);
}
-int Vector3i::max_axis() const {
- return x < y ? (y < z ? 2 : 1) : (x < z ? 2 : 0);
+Vector3i::Axis Vector3i::max_axis_index() const {
+ return x < y ? (y < z ? Vector3i::AXIS_Z : Vector3i::AXIS_Y) : (x < z ? Vector3i::AXIS_Z : Vector3i::AXIS_X);
}
Vector3i Vector3i::clamp(const Vector3i &p_min, const Vector3i &p_max) const {
diff --git a/core/math/vector3i.h b/core/math/vector3i.h
index 9308d09045..fba29a1f8d 100644
--- a/core/math/vector3i.h
+++ b/core/math/vector3i.h
@@ -62,8 +62,8 @@ struct Vector3i {
void set_axis(const int p_axis, const int32_t p_value);
int32_t get_axis(const int p_axis) const;
- int min_axis() const;
- int max_axis() const;
+ Vector3i::Axis min_axis_index() const;
+ Vector3i::Axis max_axis_index() const;
_FORCE_INLINE_ void zero();
@@ -115,7 +115,7 @@ Vector3i Vector3i::abs() const {
}
Vector3i Vector3i::sign() const {
- return Vector3i(SGN(x), SGN(y), SGN(z));
+ return Vector3i(SIGN(x), SIGN(y), SIGN(z));
}
/* Operators */
diff --git a/core/multiplayer/multiplayer_replicator.cpp b/core/multiplayer/multiplayer_replicator.cpp
index 6604510394..c57562552a 100644
--- a/core/multiplayer/multiplayer_replicator.cpp
+++ b/core/multiplayer/multiplayer_replicator.cpp
@@ -207,7 +207,7 @@ Error MultiplayerReplicator::_send_default_spawn_despawn(int p_peer_id, const Re
const Vector<StringName> names = rel_path.get_names();
ERR_FAIL_COND_V(names.size() < 2, ERR_INVALID_PARAMETER);
- NodePath parent = NodePath(names.subarray(0, names.size() - 2), false);
+ NodePath parent = NodePath(names.slice(0, names.size() - 1), false);
ERR_FAIL_COND_V_MSG(!root_node->has_node(parent), ERR_INVALID_PARAMETER, "Path not found: " + parent);
int path_id = 0;
diff --git a/core/object/class_db.cpp b/core/object/class_db.cpp
index 4b3c8b123f..bbd3b7b8de 100644
--- a/core/object/class_db.cpp
+++ b/core/object/class_db.cpp
@@ -497,22 +497,6 @@ void ClassDB::add_compatibility_class(const StringName &p_class, const StringNam
compat_classes[p_class] = p_fallback;
}
-thread_local bool initializing_with_extension = false;
-thread_local ObjectNativeExtension *initializing_extension = nullptr;
-thread_local GDExtensionClassInstancePtr initializing_extension_instance = nullptr;
-
-void ClassDB::instance_get_native_extension_data(ObjectNativeExtension **r_extension, GDExtensionClassInstancePtr *r_extension_instance, Object *p_base) {
- if (initializing_with_extension) {
- *r_extension = initializing_extension;
- *r_extension_instance = initializing_extension_instance;
- initializing_with_extension = false;
- initializing_extension->set_object_instance(*r_extension_instance, p_base);
- } else {
- *r_extension = nullptr;
- *r_extension_instance = nullptr;
- }
-}
-
Object *ClassDB::instantiate(const StringName &p_class) {
ClassInfo *ti;
{
@@ -533,21 +517,31 @@ Object *ClassDB::instantiate(const StringName &p_class) {
return nullptr;
}
#endif
- if (ti->native_extension) {
- initializing_with_extension = true;
- initializing_extension = ti->native_extension;
- initializing_extension_instance = ti->native_extension->create_instance(ti->native_extension->class_userdata);
+ if (ti->native_extension && ti->native_extension->create_instance) {
+ return (Object *)ti->native_extension->create_instance(ti->native_extension->class_userdata);
+ } else {
+ return ti->creation_func();
}
- return ti->creation_func();
}
-Object *ClassDB::construct_object(Object *(*p_create_func)(), ObjectNativeExtension *p_extension) {
- if (p_extension) {
- initializing_with_extension = true;
- initializing_extension = p_extension;
- initializing_extension_instance = p_extension->create_instance(p_extension->class_userdata);
+void ClassDB::set_object_extension_instance(Object *p_object, const StringName &p_class, GDExtensionClassInstancePtr p_instance) {
+ ERR_FAIL_COND(!p_object);
+ ClassInfo *ti;
+ {
+ OBJTYPE_RLOCK;
+ ti = classes.getptr(p_class);
+ if (!ti || ti->disabled || !ti->creation_func || (ti->native_extension && !ti->native_extension->create_instance)) {
+ if (compat_classes.has(p_class)) {
+ ti = classes.getptr(compat_classes[p_class]);
+ }
+ }
+ ERR_FAIL_COND_MSG(!ti, "Cannot get class '" + String(p_class) + "'.");
+ ERR_FAIL_COND_MSG(ti->disabled, "Class '" + String(p_class) + "' is disabled.");
+ ERR_FAIL_COND_MSG(!ti->native_extension, "Class '" + String(p_class) + "' has no native extension.");
}
- return p_create_func();
+
+ p_object->_extension = ti->native_extension;
+ p_object->_extension_instance = p_instance;
}
bool ClassDB::can_instantiate(const StringName &p_class) {
@@ -737,7 +731,7 @@ void ClassDB::bind_integer_constant(const StringName &p_class, const StringName
type->constant_map[p_name] = p_constant;
String enum_name = p_enum;
- if (enum_name != String()) {
+ if (!enum_name.is_empty()) {
if (enum_name.find(".") != -1) {
enum_name = enum_name.get_slicec('.', 1);
}
diff --git a/core/object/class_db.h b/core/object/class_db.h
index d9eec4e4a8..ca9c1def29 100644
--- a/core/object/class_db.h
+++ b/core/object/class_db.h
@@ -211,8 +211,7 @@ public:
static bool is_parent_class(const StringName &p_class, const StringName &p_inherits);
static bool can_instantiate(const StringName &p_class);
static Object *instantiate(const StringName &p_class);
- static Object *construct_object(Object *(*p_create_func)(), ObjectNativeExtension *p_extension);
- static void instance_get_native_extension_data(ObjectNativeExtension **r_extension, GDExtensionClassInstancePtr *r_extension_instance, Object *p_base);
+ static void set_object_extension_instance(Object *p_object, const StringName &p_class, GDExtensionClassInstancePtr p_instance);
static APIType get_api_type(const StringName &p_class);
@@ -331,7 +330,7 @@ public:
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_array_count(const StringName &p_class, const String &p_label, const StringName &p_count_property, const StringName &p_count_setter, const StringName &p_count_getter, const String &p_array_element_prefix, uint32_t p_count_usage = PROPERTY_USAGE_EDITOR);
+ static void add_property_array_count(const StringName &p_class, const String &p_label, const StringName &p_count_property, const StringName &p_count_setter, const StringName &p_count_getter, const String &p_array_element_prefix, uint32_t p_count_usage = PROPERTY_USAGE_DEFAULT);
static void add_property_array(const StringName &p_class, const StringName &p_path, const String &p_array_element_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);
diff --git a/core/object/make_virtuals.py b/core/object/make_virtuals.py
index 86c2891e5d..e961745d96 100644
--- a/core/object/make_virtuals.py
+++ b/core/object/make_virtuals.py
@@ -1,7 +1,8 @@
proto = """
#define GDVIRTUAL$VER($RET m_name $ARG) \\
StringName _gdvirtual_##m_name##_sn = #m_name;\\
-GDNativeExtensionClassCallVirtual _gdvirtual_##m_name = (_get_extension() && _get_extension()->get_virtual) ? _get_extension()->get_virtual(_get_extension()->class_userdata, #m_name) : (GDNativeExtensionClassCallVirtual) nullptr;\\
+mutable bool _gdvirtual_##m_name##_initialized = false;\\
+mutable GDNativeExtensionClassCallVirtual _gdvirtual_##m_name = nullptr;\\
_FORCE_INLINE_ bool _gdvirtual_##m_name##_call($CALLARGS) $CONST { \\
ScriptInstance *script_instance = ((Object*)(this))->get_script_instance();\\
if (script_instance) {\\
@@ -13,6 +14,10 @@ _FORCE_INLINE_ bool _gdvirtual_##m_name##_call($CALLARGS) $CONST { \\
return true;\\
} \\
}\\
+ if (unlikely(_get_extension() && !_gdvirtual_##m_name##_initialized)) {\\
+ _gdvirtual_##m_name = (_get_extension() && _get_extension()->get_virtual) ? _get_extension()->get_virtual(_get_extension()->class_userdata, #m_name) : (GDNativeExtensionClassCallVirtual) nullptr;\\
+ _gdvirtual_##m_name##_initialized = true;\\
+ }\\
if (_gdvirtual_##m_name) {\\
$CALLPTRARGS\\
$CALLPTRRETDEF\\
@@ -28,6 +33,10 @@ _FORCE_INLINE_ bool _gdvirtual_##m_name##_overridden() const { \\
if (script_instance) {\\
return script_instance->has_method(_gdvirtual_##m_name##_sn);\\
}\\
+ if (unlikely(_get_extension() && !_gdvirtual_##m_name##_initialized)) {\\
+ _gdvirtual_##m_name = (_get_extension() && _get_extension()->get_virtual) ? _get_extension()->get_virtual(_get_extension()->class_userdata, #m_name) : (GDNativeExtensionClassCallVirtual) nullptr;\\
+ _gdvirtual_##m_name##_initialized = true;\\
+ }\\
if (_gdvirtual_##m_name) {\\
return true;\\
}\\
diff --git a/core/object/method_bind.cpp b/core/object/method_bind.cpp
index d1d8b075fe..642e27c41d 100644
--- a/core/object/method_bind.cpp
+++ b/core/object/method_bind.cpp
@@ -130,9 +130,7 @@ MethodBind::MethodBind() {
}
MethodBind::~MethodBind() {
-#ifdef DEBUG_METHODS_ENABLED
if (argument_types) {
memdelete_arr(argument_types);
}
-#endif
}
diff --git a/core/object/object.cpp b/core/object/object.cpp
index b5797a4633..14d4e0bee6 100644
--- a/core/object/object.cpp
+++ b/core/object/object.cpp
@@ -628,7 +628,10 @@ void Object::get_property_list(List<PropertyInfo> *p_list, bool p_reversed) cons
script_instance->get_property_list(p_list);
}
- _get_property_listv(p_list, p_reversed);
+ if (_extension) {
+ p_list->push_back(PropertyInfo(Variant::NIL, _extension->class_name, PROPERTY_HINT_NONE, String(), PROPERTY_USAGE_CATEGORY));
+ ClassDB::get_property_list(_extension->class_name, p_list, true, this);
+ }
if (_extension && _extension->get_property_list) {
uint32_t pcount;
@@ -641,11 +644,13 @@ void Object::get_property_list(List<PropertyInfo> *p_list, bool p_reversed) cons
}
}
+ _get_property_listv(p_list, p_reversed);
+
if (!is_class("Script")) { // can still be set, but this is for user-friendliness
p_list->push_back(PropertyInfo(Variant::OBJECT, "script", PROPERTY_HINT_RESOURCE_TYPE, "Script", PROPERTY_USAGE_DEFAULT));
}
if (!metadata.is_empty()) {
- p_list->push_back(PropertyInfo(Variant::DICTIONARY, "__meta__", PROPERTY_HINT_NONE, "", PROPERTY_USAGE_NOEDITOR | PROPERTY_USAGE_INTERNAL));
+ p_list->push_back(PropertyInfo(Variant::DICTIONARY, "__meta__", PROPERTY_HINT_NONE, "", PROPERTY_USAGE_NO_EDITOR | PROPERTY_USAGE_INTERNAL));
}
if (script_instance && !p_reversed) {
p_list->push_back(PropertyInfo(Variant::NIL, "Script Variables", PROPERTY_HINT_NONE, String(), PROPERTY_USAGE_CATEGORY));
@@ -985,7 +990,7 @@ void Object::get_meta_list(List<StringName> *p_list) const {
}
void Object::add_user_signal(const MethodInfo &p_signal) {
- ERR_FAIL_COND_MSG(p_signal.name == "", "Signal name cannot be empty.");
+ ERR_FAIL_COND_MSG(p_signal.name.is_empty(), "Signal name cannot be empty.");
ERR_FAIL_COND_MSG(ClassDB::has_signal(get_class_name(), p_signal.name), "User signal's name conflicts with a built-in signal of '" + get_class_name() + "'.");
ERR_FAIL_COND_MSG(signal_map.has(p_signal.name), "Trying to add already existing signal '" + p_signal.name + "'.");
SignalData s;
@@ -1248,7 +1253,7 @@ void Object::get_signal_list(List<MethodInfo> *p_signals) const {
const StringName *S = nullptr;
while ((S = signal_map.next(S))) {
- if (signal_map[*S].user.name != "") {
+ if (!signal_map[*S].user.name.is_empty()) {
//user signal
p_signals->push_back(signal_map[*S].user);
}
@@ -1398,14 +1403,14 @@ void Object::_disconnect(const StringName &p_signal, const Callable &p_callable,
SignalData *s = signal_map.getptr(p_signal);
if (!s) {
bool signal_is_valid = ClassDB::has_signal(get_class_name(), p_signal) ||
- (!script.is_null() && Ref<Script>(script)->has_script_signal(p_signal));
+ (!script.is_null() && Ref<Script>(script)->has_script_signal(p_signal));
ERR_FAIL_COND_MSG(signal_is_valid, "Attempt to disconnect a nonexistent connection from '" + to_string() + "'. Signal: '" + p_signal + "', callable: '" + p_callable + "'.");
}
ERR_FAIL_COND_MSG(!s, vformat("Disconnecting nonexistent signal '%s' in %s.", p_signal, to_string()));
ERR_FAIL_COND_MSG(!s->slot_map.has(*p_callable.get_base_comparator()), "Disconnecting nonexistent signal '" + p_signal + "', callable: " + p_callable + ".");
- SignalData::Slot *slot = &s->slot_map[p_callable];
+ SignalData::Slot *slot = &s->slot_map[*p_callable.get_base_comparator()];
if (!p_force) {
slot->reference_count--; // by default is zero, if it was not referenced it will go below it
@@ -1475,7 +1480,7 @@ void Object::_clear_internal_resource_paths(const Variant &p_var) {
return;
}
- if (!r->get_path().begins_with("res://") || r->get_path().find("::") == -1) {
+ if (!r->is_built_in()) {
return; //not an internal resource
}
@@ -1675,7 +1680,7 @@ void Object::get_translatable_strings(List<String> *p_strings) const {
String text = get(E.name);
- if (text == "") {
+ if (text.is_empty()) {
continue;
}
@@ -1833,8 +1838,6 @@ void Object::_construct_object(bool p_reference) {
type_is_reference = p_reference;
_instance_id = ObjectDB::add_instance(this);
- ClassDB::instance_get_native_extension_data(&_extension, &_extension_instance, this);
-
#ifdef DEBUG_ENABLED
_lock_index.init(1);
#endif
diff --git a/core/object/object.h b/core/object/object.h
index a44d921bff..fc6e6a3660 100644
--- a/core/object/object.h
+++ b/core/object/object.h
@@ -137,7 +137,7 @@ enum PropertyUsageFlags {
PROPERTY_USAGE_DEFAULT = PROPERTY_USAGE_STORAGE | PROPERTY_USAGE_EDITOR | PROPERTY_USAGE_NETWORK,
PROPERTY_USAGE_DEFAULT_INTL = PROPERTY_USAGE_STORAGE | PROPERTY_USAGE_EDITOR | PROPERTY_USAGE_NETWORK | PROPERTY_USAGE_INTERNATIONALIZED,
- PROPERTY_USAGE_NOEDITOR = PROPERTY_USAGE_STORAGE | PROPERTY_USAGE_NETWORK,
+ PROPERTY_USAGE_NO_EDITOR = PROPERTY_USAGE_STORAGE | PROPERTY_USAGE_NETWORK,
};
#define ADD_SIGNAL(m_signal) ::ClassDB::add_signal(get_class_static(), m_signal)
@@ -284,7 +284,6 @@ struct ObjectNativeExtension {
GDNativeExtensionClassCreateInstance create_instance;
GDNativeExtensionClassFreeInstance free_instance;
- GDNativeExtensionClassObjectInstance set_object_instance;
GDNativeExtensionClassGetVirtual get_virtual;
};
@@ -353,7 +352,7 @@ public:
static String get_category_static() { \
String category = m_inherits::get_category_static(); \
if (_get_category != m_inherits::_get_category) { \
- if (category != "") { \
+ if (!category.is_empty()) { \
category += "/"; \
} \
category += _get_category(); \
@@ -403,7 +402,7 @@ protected:
initialize_class(); \
} \
_FORCE_INLINE_ bool (Object::*_get_get() const)(const StringName &p_name, Variant &) const { \
- return (bool (Object::*)(const StringName &, Variant &) const) & m_class::_get; \
+ return (bool(Object::*)(const StringName &, Variant &) const) & m_class::_get; \
} \
virtual bool _getv(const StringName &p_name, Variant &r_ret) const override { \
if (m_class::_get_get() != m_inherits::_get_get()) { \
@@ -414,7 +413,7 @@ protected:
return m_inherits::_getv(p_name, r_ret); \
} \
_FORCE_INLINE_ bool (Object::*_get_set() const)(const StringName &p_name, const Variant &p_property) { \
- return (bool (Object::*)(const StringName &, const Variant &)) & m_class::_set; \
+ return (bool(Object::*)(const StringName &, const Variant &)) & m_class::_set; \
} \
virtual bool _setv(const StringName &p_name, const Variant &p_property) override { \
if (m_inherits::_setv(p_name, p_property)) { \
@@ -426,7 +425,7 @@ protected:
return false; \
} \
_FORCE_INLINE_ void (Object::*_get_get_property_list() const)(List<PropertyInfo> * p_list) const { \
- return (void (Object::*)(List<PropertyInfo> *) const) & m_class::_get_property_list; \
+ return (void(Object::*)(List<PropertyInfo> *) const) & m_class::_get_property_list; \
} \
virtual void _get_property_listv(List<PropertyInfo> *p_list, bool p_reversed) const override { \
if (!p_reversed) { \
@@ -447,7 +446,7 @@ protected:
} \
} \
_FORCE_INLINE_ void (Object::*_get_notification() const)(int) { \
- return (void (Object::*)(int)) & m_class::_notification; \
+ return (void(Object::*)(int)) & m_class::_notification; \
} \
virtual void _notificationv(int p_notification, bool p_reversed) override { \
if (!p_reversed) { \
diff --git a/core/object/script_language.cpp b/core/object/script_language.cpp
index b0ce46ca2b..8ec1a973e7 100644
--- a/core/object/script_language.cpp
+++ b/core/object/script_language.cpp
@@ -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) {
+ if (defval == E->get()) {
to_remove.push_back(E->key());
}
}
@@ -549,7 +549,7 @@ void PlaceHolderScriptInstance::property_set_fallback(const StringName &p_name,
}
}
if (!found) {
- properties.push_back(PropertyInfo(p_value.get_type(), p_name, PROPERTY_HINT_NONE, "", PROPERTY_USAGE_NOEDITOR | PROPERTY_USAGE_SCRIPT_VARIABLE));
+ properties.push_back(PropertyInfo(p_value.get_type(), p_name, PROPERTY_HINT_NONE, "", PROPERTY_USAGE_NO_EDITOR | PROPERTY_USAGE_SCRIPT_VARIABLE));
}
}
diff --git a/core/object/undo_redo.cpp b/core/object/undo_redo.cpp
index 9c84c2add7..3459506860 100644
--- a/core/object/undo_redo.cpp
+++ b/core/object/undo_redo.cpp
@@ -76,7 +76,7 @@ bool UndoRedo::_redo(bool p_execute) {
}
void UndoRedo::create_action(const String &p_name, MergeMode p_mode) {
- uint32_t ticks = OS::get_singleton()->get_ticks_msec();
+ uint64_t ticks = OS::get_singleton()->get_ticks_msec();
if (action_level == 0) {
_discard_redo();
@@ -282,7 +282,7 @@ void UndoRedo::_pop_history_tail() {
}
}
- actions.remove(0);
+ actions.remove_at(0);
if (current_action >= 0) {
current_action--;
}
diff --git a/core/os/keyboard.cpp b/core/os/keyboard.cpp
index 4c5f0b5220..fdc43da7a5 100644
--- a/core/os/keyboard.cpp
+++ b/core/os/keyboard.cpp
@@ -33,400 +33,399 @@
#include "core/os/os.h"
struct _KeyCodeText {
- int code;
+ Key code;
const char *text;
};
static const _KeyCodeText _keycodes[] = {
/* clang-format off */
- {KEY_ESCAPE ,"Escape"},
- {KEY_TAB ,"Tab"},
- {KEY_BACKTAB ,"BackTab"},
- {KEY_BACKSPACE ,"BackSpace"},
- {KEY_ENTER ,"Enter"},
- {KEY_KP_ENTER ,"Kp Enter"},
- {KEY_INSERT ,"Insert"},
- {KEY_DELETE ,"Delete"},
- {KEY_PAUSE ,"Pause"},
- {KEY_PRINT ,"Print"},
- {KEY_SYSREQ ,"SysReq"},
- {KEY_CLEAR ,"Clear"},
- {KEY_HOME ,"Home"},
- {KEY_END ,"End"},
- {KEY_LEFT ,"Left"},
- {KEY_UP ,"Up"},
- {KEY_RIGHT ,"Right"},
- {KEY_DOWN ,"Down"},
- {KEY_PAGEUP ,"PageUp"},
- {KEY_PAGEDOWN ,"PageDown"},
- {KEY_SHIFT ,"Shift"},
- {KEY_CTRL ,"Ctrl"},
+ {Key::ESCAPE ,"Escape"},
+ {Key::TAB ,"Tab"},
+ {Key::BACKTAB ,"BackTab"},
+ {Key::BACKSPACE ,"BackSpace"},
+ {Key::ENTER ,"Enter"},
+ {Key::KP_ENTER ,"Kp Enter"},
+ {Key::INSERT ,"Insert"},
+ {Key::KEY_DELETE ,"Delete"},
+ {Key::PAUSE ,"Pause"},
+ {Key::PRINT ,"Print"},
+ {Key::SYSREQ ,"SysReq"},
+ {Key::CLEAR ,"Clear"},
+ {Key::HOME ,"Home"},
+ {Key::END ,"End"},
+ {Key::LEFT ,"Left"},
+ {Key::UP ,"Up"},
+ {Key::RIGHT ,"Right"},
+ {Key::DOWN ,"Down"},
+ {Key::PAGEUP ,"PageUp"},
+ {Key::PAGEDOWN ,"PageDown"},
+ {Key::SHIFT ,"Shift"},
+ {Key::CTRL ,"Ctrl"},
#ifdef OSX_ENABLED
- {KEY_META ,"Command"},
+ {Key::META ,"Command"},
#else
- {KEY_META ,"Meta"},
+ {Key::META ,"Meta"},
#endif
- {KEY_ALT ,"Alt"},
- {KEY_CAPSLOCK ,"CapsLock"},
- {KEY_NUMLOCK ,"NumLock"},
- {KEY_SCROLLLOCK ,"ScrollLock"},
- {KEY_F1 ,"F1"},
- {KEY_F2 ,"F2"},
- {KEY_F3 ,"F3"},
- {KEY_F4 ,"F4"},
- {KEY_F5 ,"F5"},
- {KEY_F6 ,"F6"},
- {KEY_F7 ,"F7"},
- {KEY_F8 ,"F8"},
- {KEY_F9 ,"F9"},
- {KEY_F10 ,"F10"},
- {KEY_F11 ,"F11"},
- {KEY_F12 ,"F12"},
- {KEY_F13 ,"F13"},
- {KEY_F14 ,"F14"},
- {KEY_F15 ,"F15"},
- {KEY_F16 ,"F16"},
- {KEY_KP_MULTIPLY ,"Kp Multiply"},
- {KEY_KP_DIVIDE ,"Kp Divide"},
- {KEY_KP_SUBTRACT ,"Kp Subtract"},
- {KEY_KP_PERIOD ,"Kp Period"},
- {KEY_KP_ADD ,"Kp Add"},
- {KEY_KP_0 ,"Kp 0"},
- {KEY_KP_1 ,"Kp 1"},
- {KEY_KP_2 ,"Kp 2"},
- {KEY_KP_3 ,"Kp 3"},
- {KEY_KP_4 ,"Kp 4"},
- {KEY_KP_5 ,"Kp 5"},
- {KEY_KP_6 ,"Kp 6"},
- {KEY_KP_7 ,"Kp 7"},
- {KEY_KP_8 ,"Kp 8"},
- {KEY_KP_9 ,"Kp 9"},
- {KEY_SUPER_L ,"Super L"},
- {KEY_SUPER_R ,"Super R"},
- {KEY_MENU ,"Menu"},
- {KEY_HYPER_L ,"Hyper L"},
- {KEY_HYPER_R ,"Hyper R"},
- {KEY_HELP ,"Help"},
- {KEY_DIRECTION_L ,"Direction L"},
- {KEY_DIRECTION_R ,"Direction R"},
- {KEY_BACK ,"Back"},
- {KEY_FORWARD ,"Forward"},
- {KEY_STOP ,"Stop"},
- {KEY_REFRESH ,"Refresh"},
- {KEY_VOLUMEDOWN ,"VolumeDown"},
- {KEY_VOLUMEMUTE ,"VolumeMute"},
- {KEY_VOLUMEUP ,"VolumeUp"},
- {KEY_BASSBOOST ,"BassBoost"},
- {KEY_BASSUP ,"BassUp"},
- {KEY_BASSDOWN ,"BassDown"},
- {KEY_TREBLEUP ,"TrebleUp"},
- {KEY_TREBLEDOWN ,"TrebleDown"},
- {KEY_MEDIAPLAY ,"MediaPlay"},
- {KEY_MEDIASTOP ,"MediaStop"},
- {KEY_MEDIAPREVIOUS ,"MediaPrevious"},
- {KEY_MEDIANEXT ,"MediaNext"},
- {KEY_MEDIARECORD ,"MediaRecord"},
- {KEY_HOMEPAGE ,"HomePage"},
- {KEY_FAVORITES ,"Favorites"},
- {KEY_SEARCH ,"Search"},
- {KEY_STANDBY ,"StandBy"},
- {KEY_LAUNCHMAIL ,"LaunchMail"},
- {KEY_LAUNCHMEDIA ,"LaunchMedia"},
- {KEY_LAUNCH0 ,"Launch0"},
- {KEY_LAUNCH1 ,"Launch1"},
- {KEY_LAUNCH2 ,"Launch2"},
- {KEY_LAUNCH3 ,"Launch3"},
- {KEY_LAUNCH4 ,"Launch4"},
- {KEY_LAUNCH5 ,"Launch5"},
- {KEY_LAUNCH6 ,"Launch6"},
- {KEY_LAUNCH7 ,"Launch7"},
- {KEY_LAUNCH8 ,"Launch8"},
- {KEY_LAUNCH9 ,"Launch9"},
- {KEY_LAUNCHA ,"LaunchA"},
- {KEY_LAUNCHB ,"LaunchB"},
- {KEY_LAUNCHC ,"LaunchC"},
- {KEY_LAUNCHD ,"LaunchD"},
- {KEY_LAUNCHE ,"LaunchE"},
- {KEY_LAUNCHF ,"LaunchF"},
-
- {KEY_UNKNOWN ,"Unknown"},
-
- {KEY_SPACE ,"Space"},
- {KEY_EXCLAM ,"Exclam"},
- {KEY_QUOTEDBL ,"QuoteDbl"},
- {KEY_NUMBERSIGN ,"NumberSign"},
- {KEY_DOLLAR ,"Dollar"},
- {KEY_PERCENT ,"Percent"},
- {KEY_AMPERSAND ,"Ampersand"},
- {KEY_APOSTROPHE ,"Apostrophe"},
- {KEY_PARENLEFT ,"ParenLeft"},
- {KEY_PARENRIGHT ,"ParenRight"},
- {KEY_ASTERISK ,"Asterisk"},
- {KEY_PLUS ,"Plus"},
- {KEY_COMMA ,"Comma"},
- {KEY_MINUS ,"Minus"},
- {KEY_PERIOD ,"Period"},
- {KEY_SLASH ,"Slash"},
- {KEY_0 ,"0"},
- {KEY_1 ,"1"},
- {KEY_2 ,"2"},
- {KEY_3 ,"3"},
- {KEY_4 ,"4"},
- {KEY_5 ,"5"},
- {KEY_6 ,"6"},
- {KEY_7 ,"7"},
- {KEY_8 ,"8"},
- {KEY_9 ,"9"},
- {KEY_COLON ,"Colon"},
- {KEY_SEMICOLON ,"Semicolon"},
- {KEY_LESS ,"Less"},
- {KEY_EQUAL ,"Equal"},
- {KEY_GREATER ,"Greater"},
- {KEY_QUESTION ,"Question"},
- {KEY_AT ,"At"},
- {KEY_A ,"A"},
- {KEY_B ,"B"},
- {KEY_C ,"C"},
- {KEY_D ,"D"},
- {KEY_E ,"E"},
- {KEY_F ,"F"},
- {KEY_G ,"G"},
- {KEY_H ,"H"},
- {KEY_I ,"I"},
- {KEY_J ,"J"},
- {KEY_K ,"K"},
- {KEY_L ,"L"},
- {KEY_M ,"M"},
- {KEY_N ,"N"},
- {KEY_O ,"O"},
- {KEY_P ,"P"},
- {KEY_Q ,"Q"},
- {KEY_R ,"R"},
- {KEY_S ,"S"},
- {KEY_T ,"T"},
- {KEY_U ,"U"},
- {KEY_V ,"V"},
- {KEY_W ,"W"},
- {KEY_X ,"X"},
- {KEY_Y ,"Y"},
- {KEY_Z ,"Z"},
- {KEY_BRACKETLEFT ,"BracketLeft"},
- {KEY_BACKSLASH ,"BackSlash"},
- {KEY_BRACKETRIGHT ,"BracketRight"},
- {KEY_ASCIICIRCUM ,"AsciiCircum"},
- {KEY_UNDERSCORE ,"UnderScore"},
- {KEY_QUOTELEFT ,"QuoteLeft"},
- {KEY_BRACELEFT ,"BraceLeft"},
- {KEY_BAR ,"Bar"},
- {KEY_BRACERIGHT ,"BraceRight"},
- {KEY_ASCIITILDE ,"AsciiTilde"},
- {KEY_NOBREAKSPACE ,"NoBreakSpace"},
- {KEY_EXCLAMDOWN ,"ExclamDown"},
- {KEY_CENT ,"Cent"},
- {KEY_STERLING ,"Sterling"},
- {KEY_CURRENCY ,"Currency"},
- {KEY_YEN ,"Yen"},
- {KEY_BROKENBAR ,"BrokenBar"},
- {KEY_SECTION ,"Section"},
- {KEY_DIAERESIS ,"Diaeresis"},
- {KEY_COPYRIGHT ,"Copyright"},
- {KEY_ORDFEMININE ,"Ordfeminine"},
- {KEY_GUILLEMOTLEFT ,"GuillemotLeft"},
- {KEY_NOTSIGN ,"NotSign"},
- {KEY_HYPHEN ,"Hyphen"},
- {KEY_REGISTERED ,"Registered"},
- {KEY_MACRON ,"Macron"},
- {KEY_DEGREE ,"Degree"},
- {KEY_PLUSMINUS ,"PlusMinus"},
- {KEY_TWOSUPERIOR ,"TwoSuperior"},
- {KEY_THREESUPERIOR ,"ThreeSuperior"},
- {KEY_ACUTE ,"Acute"},
- {KEY_MU ,"Mu"},
- {KEY_PARAGRAPH ,"Paragraph"},
- {KEY_PERIODCENTERED ,"PeriodCentered"},
- {KEY_CEDILLA ,"Cedilla"},
- {KEY_ONESUPERIOR ,"OneSuperior"},
- {KEY_MASCULINE ,"Masculine"},
- {KEY_GUILLEMOTRIGHT ,"GuillemotRight"},
- {KEY_ONEQUARTER ,"OneQuarter"},
- {KEY_ONEHALF ,"OneHalf"},
- {KEY_THREEQUARTERS ,"ThreeQuarters"},
- {KEY_QUESTIONDOWN ,"QuestionDown"},
- {KEY_AGRAVE ,"Agrave"},
- {KEY_AACUTE ,"Aacute"},
- {KEY_ACIRCUMFLEX ,"AcircumFlex"},
- {KEY_ATILDE ,"Atilde"},
- {KEY_ADIAERESIS ,"Adiaeresis"},
- {KEY_ARING ,"Aring"},
- {KEY_AE ,"Ae"},
- {KEY_CCEDILLA ,"Ccedilla"},
- {KEY_EGRAVE ,"Egrave"},
- {KEY_EACUTE ,"Eacute"},
- {KEY_ECIRCUMFLEX ,"Ecircumflex"},
- {KEY_EDIAERESIS ,"Ediaeresis"},
- {KEY_IGRAVE ,"Igrave"},
- {KEY_IACUTE ,"Iacute"},
- {KEY_ICIRCUMFLEX ,"Icircumflex"},
- {KEY_IDIAERESIS ,"Idiaeresis"},
- {KEY_ETH ,"Eth"},
- {KEY_NTILDE ,"Ntilde"},
- {KEY_OGRAVE ,"Ograve"},
- {KEY_OACUTE ,"Oacute"},
- {KEY_OCIRCUMFLEX ,"Ocircumflex"},
- {KEY_OTILDE ,"Otilde"},
- {KEY_ODIAERESIS ,"Odiaeresis"},
- {KEY_MULTIPLY ,"Multiply"},
- {KEY_OOBLIQUE ,"Ooblique"},
- {KEY_UGRAVE ,"Ugrave"},
- {KEY_UACUTE ,"Uacute"},
- {KEY_UCIRCUMFLEX ,"Ucircumflex"},
- {KEY_UDIAERESIS ,"Udiaeresis"},
- {KEY_YACUTE ,"Yacute"},
- {KEY_THORN ,"Thorn"},
- {KEY_SSHARP ,"Ssharp"},
-
- {KEY_DIVISION ,"Division"},
- {KEY_YDIAERESIS ,"Ydiaeresis"},
- {0 ,nullptr}
+ {Key::ALT ,"Alt"},
+ {Key::CAPSLOCK ,"CapsLock"},
+ {Key::NUMLOCK ,"NumLock"},
+ {Key::SCROLLLOCK ,"ScrollLock"},
+ {Key::F1 ,"F1"},
+ {Key::F2 ,"F2"},
+ {Key::F3 ,"F3"},
+ {Key::F4 ,"F4"},
+ {Key::F5 ,"F5"},
+ {Key::F6 ,"F6"},
+ {Key::F7 ,"F7"},
+ {Key::F8 ,"F8"},
+ {Key::F9 ,"F9"},
+ {Key::F10 ,"F10"},
+ {Key::F11 ,"F11"},
+ {Key::F12 ,"F12"},
+ {Key::F13 ,"F13"},
+ {Key::F14 ,"F14"},
+ {Key::F15 ,"F15"},
+ {Key::F16 ,"F16"},
+ {Key::KP_MULTIPLY ,"Kp Multiply"},
+ {Key::KP_DIVIDE ,"Kp Divide"},
+ {Key::KP_SUBTRACT ,"Kp Subtract"},
+ {Key::KP_PERIOD ,"Kp Period"},
+ {Key::KP_ADD ,"Kp Add"},
+ {Key::KP_0 ,"Kp 0"},
+ {Key::KP_1 ,"Kp 1"},
+ {Key::KP_2 ,"Kp 2"},
+ {Key::KP_3 ,"Kp 3"},
+ {Key::KP_4 ,"Kp 4"},
+ {Key::KP_5 ,"Kp 5"},
+ {Key::KP_6 ,"Kp 6"},
+ {Key::KP_7 ,"Kp 7"},
+ {Key::KP_8 ,"Kp 8"},
+ {Key::KP_9 ,"Kp 9"},
+ {Key::SUPER_L ,"Super L"},
+ {Key::SUPER_R ,"Super R"},
+ {Key::MENU ,"Menu"},
+ {Key::HYPER_L ,"Hyper L"},
+ {Key::HYPER_R ,"Hyper R"},
+ {Key::HELP ,"Help"},
+ {Key::DIRECTION_L ,"Direction L"},
+ {Key::DIRECTION_R ,"Direction R"},
+ {Key::BACK ,"Back"},
+ {Key::FORWARD ,"Forward"},
+ {Key::STOP ,"Stop"},
+ {Key::REFRESH ,"Refresh"},
+ {Key::VOLUMEDOWN ,"VolumeDown"},
+ {Key::VOLUMEMUTE ,"VolumeMute"},
+ {Key::VOLUMEUP ,"VolumeUp"},
+ {Key::BASSBOOST ,"BassBoost"},
+ {Key::BASSUP ,"BassUp"},
+ {Key::BASSDOWN ,"BassDown"},
+ {Key::TREBLEUP ,"TrebleUp"},
+ {Key::TREBLEDOWN ,"TrebleDown"},
+ {Key::MEDIAPLAY ,"MediaPlay"},
+ {Key::MEDIASTOP ,"MediaStop"},
+ {Key::MEDIAPREVIOUS ,"MediaPrevious"},
+ {Key::MEDIANEXT ,"MediaNext"},
+ {Key::MEDIARECORD ,"MediaRecord"},
+ {Key::HOMEPAGE ,"HomePage"},
+ {Key::FAVORITES ,"Favorites"},
+ {Key::SEARCH ,"Search"},
+ {Key::STANDBY ,"StandBy"},
+ {Key::LAUNCHMAIL ,"LaunchMail"},
+ {Key::LAUNCHMEDIA ,"LaunchMedia"},
+ {Key::LAUNCH0 ,"Launch0"},
+ {Key::LAUNCH1 ,"Launch1"},
+ {Key::LAUNCH2 ,"Launch2"},
+ {Key::LAUNCH3 ,"Launch3"},
+ {Key::LAUNCH4 ,"Launch4"},
+ {Key::LAUNCH5 ,"Launch5"},
+ {Key::LAUNCH6 ,"Launch6"},
+ {Key::LAUNCH7 ,"Launch7"},
+ {Key::LAUNCH8 ,"Launch8"},
+ {Key::LAUNCH9 ,"Launch9"},
+ {Key::LAUNCHA ,"LaunchA"},
+ {Key::LAUNCHB ,"LaunchB"},
+ {Key::LAUNCHC ,"LaunchC"},
+ {Key::LAUNCHD ,"LaunchD"},
+ {Key::LAUNCHE ,"LaunchE"},
+ {Key::LAUNCHF ,"LaunchF"},
+ {Key::UNKNOWN ,"Unknown"},
+ {Key::SPACE ,"Space"},
+ {Key::EXCLAM ,"Exclam"},
+ {Key::QUOTEDBL ,"QuoteDbl"},
+ {Key::NUMBERSIGN ,"NumberSign"},
+ {Key::DOLLAR ,"Dollar"},
+ {Key::PERCENT ,"Percent"},
+ {Key::AMPERSAND ,"Ampersand"},
+ {Key::APOSTROPHE ,"Apostrophe"},
+ {Key::PARENLEFT ,"ParenLeft"},
+ {Key::PARENRIGHT ,"ParenRight"},
+ {Key::ASTERISK ,"Asterisk"},
+ {Key::PLUS ,"Plus"},
+ {Key::COMMA ,"Comma"},
+ {Key::MINUS ,"Minus"},
+ {Key::PERIOD ,"Period"},
+ {Key::SLASH ,"Slash"},
+ {Key::KEY_0 ,"0"},
+ {Key::KEY_1 ,"1"},
+ {Key::KEY_2 ,"2"},
+ {Key::KEY_3 ,"3"},
+ {Key::KEY_4 ,"4"},
+ {Key::KEY_5 ,"5"},
+ {Key::KEY_6 ,"6"},
+ {Key::KEY_7 ,"7"},
+ {Key::KEY_8 ,"8"},
+ {Key::KEY_9 ,"9"},
+ {Key::COLON ,"Colon"},
+ {Key::SEMICOLON ,"Semicolon"},
+ {Key::LESS ,"Less"},
+ {Key::EQUAL ,"Equal"},
+ {Key::GREATER ,"Greater"},
+ {Key::QUESTION ,"Question"},
+ {Key::AT ,"At"},
+ {Key::A ,"A"},
+ {Key::B ,"B"},
+ {Key::C ,"C"},
+ {Key::D ,"D"},
+ {Key::E ,"E"},
+ {Key::F ,"F"},
+ {Key::G ,"G"},
+ {Key::H ,"H"},
+ {Key::I ,"I"},
+ {Key::J ,"J"},
+ {Key::K ,"K"},
+ {Key::L ,"L"},
+ {Key::M ,"M"},
+ {Key::N ,"N"},
+ {Key::O ,"O"},
+ {Key::P ,"P"},
+ {Key::Q ,"Q"},
+ {Key::R ,"R"},
+ {Key::S ,"S"},
+ {Key::T ,"T"},
+ {Key::U ,"U"},
+ {Key::V ,"V"},
+ {Key::W ,"W"},
+ {Key::X ,"X"},
+ {Key::Y ,"Y"},
+ {Key::Z ,"Z"},
+ {Key::BRACKETLEFT ,"BracketLeft"},
+ {Key::BACKSLASH ,"BackSlash"},
+ {Key::BRACKETRIGHT ,"BracketRight"},
+ {Key::ASCIICIRCUM ,"AsciiCircum"},
+ {Key::UNDERSCORE ,"UnderScore"},
+ {Key::QUOTELEFT ,"QuoteLeft"},
+ {Key::BRACELEFT ,"BraceLeft"},
+ {Key::BAR ,"Bar"},
+ {Key::BRACERIGHT ,"BraceRight"},
+ {Key::ASCIITILDE ,"AsciiTilde"},
+ {Key::NOBREAKSPACE ,"NoBreakSpace"},
+ {Key::EXCLAMDOWN ,"ExclamDown"},
+ {Key::CENT ,"Cent"},
+ {Key::STERLING ,"Sterling"},
+ {Key::CURRENCY ,"Currency"},
+ {Key::YEN ,"Yen"},
+ {Key::BROKENBAR ,"BrokenBar"},
+ {Key::SECTION ,"Section"},
+ {Key::DIAERESIS ,"Diaeresis"},
+ {Key::COPYRIGHT ,"Copyright"},
+ {Key::ORDFEMININE ,"Ordfeminine"},
+ {Key::GUILLEMOTLEFT ,"GuillemotLeft"},
+ {Key::NOTSIGN ,"NotSign"},
+ {Key::HYPHEN ,"Hyphen"},
+ {Key::KEY_REGISTERED ,"Registered"},
+ {Key::MACRON ,"Macron"},
+ {Key::DEGREE ,"Degree"},
+ {Key::PLUSMINUS ,"PlusMinus"},
+ {Key::TWOSUPERIOR ,"TwoSuperior"},
+ {Key::THREESUPERIOR ,"ThreeSuperior"},
+ {Key::ACUTE ,"Acute"},
+ {Key::MU ,"Mu"},
+ {Key::PARAGRAPH ,"Paragraph"},
+ {Key::PERIODCENTERED ,"PeriodCentered"},
+ {Key::CEDILLA ,"Cedilla"},
+ {Key::ONESUPERIOR ,"OneSuperior"},
+ {Key::MASCULINE ,"Masculine"},
+ {Key::GUILLEMOTRIGHT ,"GuillemotRight"},
+ {Key::ONEQUARTER ,"OneQuarter"},
+ {Key::ONEHALF ,"OneHalf"},
+ {Key::THREEQUARTERS ,"ThreeQuarters"},
+ {Key::QUESTIONDOWN ,"QuestionDown"},
+ {Key::AGRAVE ,"Agrave"},
+ {Key::AACUTE ,"Aacute"},
+ {Key::ACIRCUMFLEX ,"AcircumFlex"},
+ {Key::ATILDE ,"Atilde"},
+ {Key::ADIAERESIS ,"Adiaeresis"},
+ {Key::ARING ,"Aring"},
+ {Key::AE ,"Ae"},
+ {Key::CCEDILLA ,"Ccedilla"},
+ {Key::EGRAVE ,"Egrave"},
+ {Key::EACUTE ,"Eacute"},
+ {Key::ECIRCUMFLEX ,"Ecircumflex"},
+ {Key::EDIAERESIS ,"Ediaeresis"},
+ {Key::IGRAVE ,"Igrave"},
+ {Key::IACUTE ,"Iacute"},
+ {Key::ICIRCUMFLEX ,"Icircumflex"},
+ {Key::IDIAERESIS ,"Idiaeresis"},
+ {Key::ETH ,"Eth"},
+ {Key::NTILDE ,"Ntilde"},
+ {Key::OGRAVE ,"Ograve"},
+ {Key::OACUTE ,"Oacute"},
+ {Key::OCIRCUMFLEX ,"Ocircumflex"},
+ {Key::OTILDE ,"Otilde"},
+ {Key::ODIAERESIS ,"Odiaeresis"},
+ {Key::MULTIPLY ,"Multiply"},
+ {Key::OOBLIQUE ,"Ooblique"},
+ {Key::UGRAVE ,"Ugrave"},
+ {Key::UACUTE ,"Uacute"},
+ {Key::UCIRCUMFLEX ,"Ucircumflex"},
+ {Key::UDIAERESIS ,"Udiaeresis"},
+ {Key::YACUTE ,"Yacute"},
+ {Key::THORN ,"Thorn"},
+ {Key::SSHARP ,"Ssharp"},
+ {Key::DIVISION ,"Division"},
+ {Key::YDIAERESIS ,"Ydiaeresis"},
+ {Key::NONE ,nullptr}
/* clang-format on */
};
-bool keycode_has_unicode(uint32_t p_keycode) {
+bool keycode_has_unicode(Key p_keycode) {
switch (p_keycode) {
- case KEY_ESCAPE:
- case KEY_TAB:
- case KEY_BACKTAB:
- case KEY_BACKSPACE:
- case KEY_ENTER:
- case KEY_KP_ENTER:
- case KEY_INSERT:
- case KEY_DELETE:
- case KEY_PAUSE:
- case KEY_PRINT:
- case KEY_SYSREQ:
- case KEY_CLEAR:
- case KEY_HOME:
- case KEY_END:
- case KEY_LEFT:
- case KEY_UP:
- case KEY_RIGHT:
- case KEY_DOWN:
- case KEY_PAGEUP:
- case KEY_PAGEDOWN:
- case KEY_SHIFT:
- case KEY_CTRL:
- case KEY_META:
- case KEY_ALT:
- case KEY_CAPSLOCK:
- case KEY_NUMLOCK:
- case KEY_SCROLLLOCK:
- case KEY_F1:
- case KEY_F2:
- case KEY_F3:
- case KEY_F4:
- case KEY_F5:
- case KEY_F6:
- case KEY_F7:
- case KEY_F8:
- case KEY_F9:
- case KEY_F10:
- case KEY_F11:
- case KEY_F12:
- case KEY_F13:
- case KEY_F14:
- case KEY_F15:
- case KEY_F16:
- case KEY_SUPER_L:
- case KEY_SUPER_R:
- case KEY_MENU:
- case KEY_HYPER_L:
- case KEY_HYPER_R:
- case KEY_HELP:
- case KEY_DIRECTION_L:
- case KEY_DIRECTION_R:
- case KEY_BACK:
- case KEY_FORWARD:
- case KEY_STOP:
- case KEY_REFRESH:
- case KEY_VOLUMEDOWN:
- case KEY_VOLUMEMUTE:
- case KEY_VOLUMEUP:
- case KEY_BASSBOOST:
- case KEY_BASSUP:
- case KEY_BASSDOWN:
- case KEY_TREBLEUP:
- case KEY_TREBLEDOWN:
- case KEY_MEDIAPLAY:
- case KEY_MEDIASTOP:
- case KEY_MEDIAPREVIOUS:
- case KEY_MEDIANEXT:
- case KEY_MEDIARECORD:
- case KEY_HOMEPAGE:
- case KEY_FAVORITES:
- case KEY_SEARCH:
- case KEY_STANDBY:
- case KEY_OPENURL:
- case KEY_LAUNCHMAIL:
- case KEY_LAUNCHMEDIA:
- case KEY_LAUNCH0:
- case KEY_LAUNCH1:
- case KEY_LAUNCH2:
- case KEY_LAUNCH3:
- case KEY_LAUNCH4:
- case KEY_LAUNCH5:
- case KEY_LAUNCH6:
- case KEY_LAUNCH7:
- case KEY_LAUNCH8:
- case KEY_LAUNCH9:
- case KEY_LAUNCHA:
- case KEY_LAUNCHB:
- case KEY_LAUNCHC:
- case KEY_LAUNCHD:
- case KEY_LAUNCHE:
- case KEY_LAUNCHF:
+ case Key::ESCAPE:
+ case Key::TAB:
+ case Key::BACKTAB:
+ case Key::BACKSPACE:
+ case Key::ENTER:
+ case Key::KP_ENTER:
+ case Key::INSERT:
+ case Key::KEY_DELETE:
+ case Key::PAUSE:
+ case Key::PRINT:
+ case Key::SYSREQ:
+ case Key::CLEAR:
+ case Key::HOME:
+ case Key::END:
+ case Key::LEFT:
+ case Key::UP:
+ case Key::RIGHT:
+ case Key::DOWN:
+ case Key::PAGEUP:
+ case Key::PAGEDOWN:
+ case Key::SHIFT:
+ case Key::CTRL:
+ case Key::META:
+ case Key::ALT:
+ case Key::CAPSLOCK:
+ case Key::NUMLOCK:
+ case Key::SCROLLLOCK:
+ case Key::F1:
+ case Key::F2:
+ case Key::F3:
+ case Key::F4:
+ case Key::F5:
+ case Key::F6:
+ case Key::F7:
+ case Key::F8:
+ case Key::F9:
+ case Key::F10:
+ case Key::F11:
+ case Key::F12:
+ case Key::F13:
+ case Key::F14:
+ case Key::F15:
+ case Key::F16:
+ case Key::SUPER_L:
+ case Key::SUPER_R:
+ case Key::MENU:
+ case Key::HYPER_L:
+ case Key::HYPER_R:
+ case Key::HELP:
+ case Key::DIRECTION_L:
+ case Key::DIRECTION_R:
+ case Key::BACK:
+ case Key::FORWARD:
+ case Key::STOP:
+ case Key::REFRESH:
+ case Key::VOLUMEDOWN:
+ case Key::VOLUMEMUTE:
+ case Key::VOLUMEUP:
+ case Key::BASSBOOST:
+ case Key::BASSUP:
+ case Key::BASSDOWN:
+ case Key::TREBLEUP:
+ case Key::TREBLEDOWN:
+ case Key::MEDIAPLAY:
+ case Key::MEDIASTOP:
+ case Key::MEDIAPREVIOUS:
+ case Key::MEDIANEXT:
+ case Key::MEDIARECORD:
+ case Key::HOMEPAGE:
+ case Key::FAVORITES:
+ case Key::SEARCH:
+ case Key::STANDBY:
+ case Key::OPENURL:
+ case Key::LAUNCHMAIL:
+ case Key::LAUNCHMEDIA:
+ case Key::LAUNCH0:
+ case Key::LAUNCH1:
+ case Key::LAUNCH2:
+ case Key::LAUNCH3:
+ case Key::LAUNCH4:
+ case Key::LAUNCH5:
+ case Key::LAUNCH6:
+ case Key::LAUNCH7:
+ case Key::LAUNCH8:
+ case Key::LAUNCH9:
+ case Key::LAUNCHA:
+ case Key::LAUNCHB:
+ case Key::LAUNCHC:
+ case Key::LAUNCHD:
+ case Key::LAUNCHE:
+ case Key::LAUNCHF:
return false;
+ default: {
+ }
}
return true;
}
-String keycode_get_string(uint32_t p_code) {
+String keycode_get_string(Key p_code) {
String codestr;
- if (p_code & KEY_MASK_SHIFT) {
- codestr += find_keycode_name(KEY_SHIFT);
+ if ((p_code & KeyModifierMask::SHIFT) != Key::NONE) {
+ codestr += find_keycode_name(Key::SHIFT);
codestr += "+";
}
- if (p_code & KEY_MASK_ALT) {
- codestr += find_keycode_name(KEY_ALT);
+ if ((p_code & KeyModifierMask::ALT) != Key::NONE) {
+ codestr += find_keycode_name(Key::ALT);
codestr += "+";
}
- if (p_code & KEY_MASK_CTRL) {
- codestr += find_keycode_name(KEY_CTRL);
+ if ((p_code & KeyModifierMask::CTRL) != Key::NONE) {
+ codestr += find_keycode_name(Key::CTRL);
codestr += "+";
}
- if (p_code & KEY_MASK_META) {
- codestr += find_keycode_name(KEY_META);
+ if ((p_code & KeyModifierMask::META) != Key::NONE) {
+ codestr += find_keycode_name(Key::META);
codestr += "+";
}
- p_code &= KEY_CODE_MASK;
+ p_code &= KeyModifierMask::CODE_MASK;
const _KeyCodeText *kct = &_keycodes[0];
while (kct->text) {
- if (kct->code == (int)p_code) {
+ if (kct->code == p_code) {
codestr += kct->text;
return codestr;
}
kct++;
}
- codestr += String::chr(p_code);
+ codestr += String::chr((char32_t)p_code);
return codestr;
}
-int find_keycode(const String &p_code) {
+Key find_keycode(const String &p_code) {
const _KeyCodeText *kct = &_keycodes[0];
while (kct->text) {
@@ -436,10 +435,10 @@ int find_keycode(const String &p_code) {
kct++;
}
- return 0;
+ return Key::NONE;
}
-const char *find_keycode_name(int p_keycode) {
+const char *find_keycode_name(Key p_keycode) {
const _KeyCodeText *kct = &_keycodes[0];
while (kct->text) {
@@ -464,7 +463,7 @@ int keycode_get_count() {
}
int keycode_get_value_by_index(int p_index) {
- return _keycodes[p_index].code;
+ return (int)_keycodes[p_index].code;
}
const char *keycode_get_name_by_index(int p_index) {
diff --git a/core/os/keyboard.h b/core/os/keyboard.h
index 52174432d9..c780099553 100644
--- a/core/os/keyboard.h
+++ b/core/os/keyboard.h
@@ -33,148 +33,142 @@
#include "core/string/ustring.h"
-/*
- Special Key:
-
- The strategy here is similar to the one used by toolkits,
- which consists in leaving the 24 bits unicode range for printable
- characters, and use the upper 8 bits for special keys and
- modifiers. This way everything (char/keycode) can fit nicely in one 32 bits unsigned integer.
-*/
-enum {
- SPKEY = (1 << 24)
-};
-
-enum Key {
- KEY_NONE = 0,
+enum class Key {
+ NONE = 0,
+ // Special key: The strategy here is similar to the one used by toolkits,
+ // which consists in leaving the 24 bits unicode range for printable
+ // characters, and use the upper 8 bits for special keys and modifiers.
+ // This way everything (char/keycode) can fit nicely in one 32-bit
+ // integer (the enum's underlying type is `int` by default).
+ SPECIAL = (1 << 24),
/* CURSOR/FUNCTION/BROWSER/MULTIMEDIA/MISC KEYS */
- KEY_ESCAPE = SPKEY | 0x01,
- KEY_TAB = SPKEY | 0x02,
- KEY_BACKTAB = SPKEY | 0x03,
- KEY_BACKSPACE = SPKEY | 0x04,
- KEY_ENTER = SPKEY | 0x05,
- KEY_KP_ENTER = SPKEY | 0x06,
- KEY_INSERT = SPKEY | 0x07,
- KEY_DELETE = SPKEY | 0x08,
- KEY_PAUSE = SPKEY | 0x09,
- KEY_PRINT = SPKEY | 0x0A,
- KEY_SYSREQ = SPKEY | 0x0B,
- KEY_CLEAR = SPKEY | 0x0C,
- KEY_HOME = SPKEY | 0x0D,
- KEY_END = SPKEY | 0x0E,
- KEY_LEFT = SPKEY | 0x0F,
- KEY_UP = SPKEY | 0x10,
- KEY_RIGHT = SPKEY | 0x11,
- KEY_DOWN = SPKEY | 0x12,
- KEY_PAGEUP = SPKEY | 0x13,
- KEY_PAGEDOWN = SPKEY | 0x14,
- KEY_SHIFT = SPKEY | 0x15,
- KEY_CTRL = SPKEY | 0x16,
- KEY_META = SPKEY | 0x17,
- KEY_ALT = SPKEY | 0x18,
- KEY_CAPSLOCK = SPKEY | 0x19,
- KEY_NUMLOCK = SPKEY | 0x1A,
- KEY_SCROLLLOCK = SPKEY | 0x1B,
- KEY_F1 = SPKEY | 0x1C,
- KEY_F2 = SPKEY | 0x1D,
- KEY_F3 = SPKEY | 0x1E,
- KEY_F4 = SPKEY | 0x1F,
- KEY_F5 = SPKEY | 0x20,
- KEY_F6 = SPKEY | 0x21,
- KEY_F7 = SPKEY | 0x22,
- KEY_F8 = SPKEY | 0x23,
- KEY_F9 = SPKEY | 0x24,
- KEY_F10 = SPKEY | 0x25,
- KEY_F11 = SPKEY | 0x26,
- KEY_F12 = SPKEY | 0x27,
- KEY_F13 = SPKEY | 0x28,
- KEY_F14 = SPKEY | 0x29,
- KEY_F15 = SPKEY | 0x2A,
- KEY_F16 = SPKEY | 0x2B,
- KEY_KP_MULTIPLY = SPKEY | 0x81,
- KEY_KP_DIVIDE = SPKEY | 0x82,
- KEY_KP_SUBTRACT = SPKEY | 0x83,
- KEY_KP_PERIOD = SPKEY | 0x84,
- KEY_KP_ADD = SPKEY | 0x85,
- KEY_KP_0 = SPKEY | 0x86,
- KEY_KP_1 = SPKEY | 0x87,
- KEY_KP_2 = SPKEY | 0x88,
- KEY_KP_3 = SPKEY | 0x89,
- KEY_KP_4 = SPKEY | 0x8A,
- KEY_KP_5 = SPKEY | 0x8B,
- KEY_KP_6 = SPKEY | 0x8C,
- KEY_KP_7 = SPKEY | 0x8D,
- KEY_KP_8 = SPKEY | 0x8E,
- KEY_KP_9 = SPKEY | 0x8F,
- KEY_SUPER_L = SPKEY | 0x2C,
- KEY_SUPER_R = SPKEY | 0x2D,
- KEY_MENU = SPKEY | 0x2E,
- KEY_HYPER_L = SPKEY | 0x2F,
- KEY_HYPER_R = SPKEY | 0x30,
- KEY_HELP = SPKEY | 0x31,
- KEY_DIRECTION_L = SPKEY | 0x32,
- KEY_DIRECTION_R = SPKEY | 0x33,
- KEY_BACK = SPKEY | 0x40,
- KEY_FORWARD = SPKEY | 0x41,
- KEY_STOP = SPKEY | 0x42,
- KEY_REFRESH = SPKEY | 0x43,
- KEY_VOLUMEDOWN = SPKEY | 0x44,
- KEY_VOLUMEMUTE = SPKEY | 0x45,
- KEY_VOLUMEUP = SPKEY | 0x46,
- KEY_BASSBOOST = SPKEY | 0x47,
- KEY_BASSUP = SPKEY | 0x48,
- KEY_BASSDOWN = SPKEY | 0x49,
- KEY_TREBLEUP = SPKEY | 0x4A,
- KEY_TREBLEDOWN = SPKEY | 0x4B,
- KEY_MEDIAPLAY = SPKEY | 0x4C,
- KEY_MEDIASTOP = SPKEY | 0x4D,
- KEY_MEDIAPREVIOUS = SPKEY | 0x4E,
- KEY_MEDIANEXT = SPKEY | 0x4F,
- KEY_MEDIARECORD = SPKEY | 0x50,
- KEY_HOMEPAGE = SPKEY | 0x51,
- KEY_FAVORITES = SPKEY | 0x52,
- KEY_SEARCH = SPKEY | 0x53,
- KEY_STANDBY = SPKEY | 0x54,
- KEY_OPENURL = SPKEY | 0x55,
- KEY_LAUNCHMAIL = SPKEY | 0x56,
- KEY_LAUNCHMEDIA = SPKEY | 0x57,
- KEY_LAUNCH0 = SPKEY | 0x58,
- KEY_LAUNCH1 = SPKEY | 0x59,
- KEY_LAUNCH2 = SPKEY | 0x5A,
- KEY_LAUNCH3 = SPKEY | 0x5B,
- KEY_LAUNCH4 = SPKEY | 0x5C,
- KEY_LAUNCH5 = SPKEY | 0x5D,
- KEY_LAUNCH6 = SPKEY | 0x5E,
- KEY_LAUNCH7 = SPKEY | 0x5F,
- KEY_LAUNCH8 = SPKEY | 0x60,
- KEY_LAUNCH9 = SPKEY | 0x61,
- KEY_LAUNCHA = SPKEY | 0x62,
- KEY_LAUNCHB = SPKEY | 0x63,
- KEY_LAUNCHC = SPKEY | 0x64,
- KEY_LAUNCHD = SPKEY | 0x65,
- KEY_LAUNCHE = SPKEY | 0x66,
- KEY_LAUNCHF = SPKEY | 0x67,
+ ESCAPE = SPECIAL | 0x01,
+ TAB = SPECIAL | 0x02,
+ BACKTAB = SPECIAL | 0x03,
+ BACKSPACE = SPECIAL | 0x04,
+ ENTER = SPECIAL | 0x05,
+ KP_ENTER = SPECIAL | 0x06,
+ INSERT = SPECIAL | 0x07,
+ KEY_DELETE = SPECIAL | 0x08, // "DELETE" is a reserved word on Windows.
+ PAUSE = SPECIAL | 0x09,
+ PRINT = SPECIAL | 0x0A,
+ SYSREQ = SPECIAL | 0x0B,
+ CLEAR = SPECIAL | 0x0C,
+ HOME = SPECIAL | 0x0D,
+ END = SPECIAL | 0x0E,
+ LEFT = SPECIAL | 0x0F,
+ UP = SPECIAL | 0x10,
+ RIGHT = SPECIAL | 0x11,
+ DOWN = SPECIAL | 0x12,
+ PAGEUP = SPECIAL | 0x13,
+ PAGEDOWN = SPECIAL | 0x14,
+ SHIFT = SPECIAL | 0x15,
+ CTRL = SPECIAL | 0x16,
+ META = SPECIAL | 0x17,
+ ALT = SPECIAL | 0x18,
+ CAPSLOCK = SPECIAL | 0x19,
+ NUMLOCK = SPECIAL | 0x1A,
+ SCROLLLOCK = SPECIAL | 0x1B,
+ F1 = SPECIAL | 0x1C,
+ F2 = SPECIAL | 0x1D,
+ F3 = SPECIAL | 0x1E,
+ F4 = SPECIAL | 0x1F,
+ F5 = SPECIAL | 0x20,
+ F6 = SPECIAL | 0x21,
+ F7 = SPECIAL | 0x22,
+ F8 = SPECIAL | 0x23,
+ F9 = SPECIAL | 0x24,
+ F10 = SPECIAL | 0x25,
+ F11 = SPECIAL | 0x26,
+ F12 = SPECIAL | 0x27,
+ F13 = SPECIAL | 0x28,
+ F14 = SPECIAL | 0x29,
+ F15 = SPECIAL | 0x2A,
+ F16 = SPECIAL | 0x2B,
+ KP_MULTIPLY = SPECIAL | 0x81,
+ KP_DIVIDE = SPECIAL | 0x82,
+ KP_SUBTRACT = SPECIAL | 0x83,
+ KP_PERIOD = SPECIAL | 0x84,
+ KP_ADD = SPECIAL | 0x85,
+ KP_0 = SPECIAL | 0x86,
+ KP_1 = SPECIAL | 0x87,
+ KP_2 = SPECIAL | 0x88,
+ KP_3 = SPECIAL | 0x89,
+ KP_4 = SPECIAL | 0x8A,
+ KP_5 = SPECIAL | 0x8B,
+ KP_6 = SPECIAL | 0x8C,
+ KP_7 = SPECIAL | 0x8D,
+ KP_8 = SPECIAL | 0x8E,
+ KP_9 = SPECIAL | 0x8F,
+ SUPER_L = SPECIAL | 0x2C,
+ SUPER_R = SPECIAL | 0x2D,
+ MENU = SPECIAL | 0x2E,
+ HYPER_L = SPECIAL | 0x2F,
+ HYPER_R = SPECIAL | 0x30,
+ HELP = SPECIAL | 0x31,
+ DIRECTION_L = SPECIAL | 0x32,
+ DIRECTION_R = SPECIAL | 0x33,
+ BACK = SPECIAL | 0x40,
+ FORWARD = SPECIAL | 0x41,
+ STOP = SPECIAL | 0x42,
+ REFRESH = SPECIAL | 0x43,
+ VOLUMEDOWN = SPECIAL | 0x44,
+ VOLUMEMUTE = SPECIAL | 0x45,
+ VOLUMEUP = SPECIAL | 0x46,
+ BASSBOOST = SPECIAL | 0x47,
+ BASSUP = SPECIAL | 0x48,
+ BASSDOWN = SPECIAL | 0x49,
+ TREBLEUP = SPECIAL | 0x4A,
+ TREBLEDOWN = SPECIAL | 0x4B,
+ MEDIAPLAY = SPECIAL | 0x4C,
+ MEDIASTOP = SPECIAL | 0x4D,
+ MEDIAPREVIOUS = SPECIAL | 0x4E,
+ MEDIANEXT = SPECIAL | 0x4F,
+ MEDIARECORD = SPECIAL | 0x50,
+ HOMEPAGE = SPECIAL | 0x51,
+ FAVORITES = SPECIAL | 0x52,
+ SEARCH = SPECIAL | 0x53,
+ STANDBY = SPECIAL | 0x54,
+ OPENURL = SPECIAL | 0x55,
+ LAUNCHMAIL = SPECIAL | 0x56,
+ LAUNCHMEDIA = SPECIAL | 0x57,
+ LAUNCH0 = SPECIAL | 0x58,
+ LAUNCH1 = SPECIAL | 0x59,
+ LAUNCH2 = SPECIAL | 0x5A,
+ LAUNCH3 = SPECIAL | 0x5B,
+ LAUNCH4 = SPECIAL | 0x5C,
+ LAUNCH5 = SPECIAL | 0x5D,
+ LAUNCH6 = SPECIAL | 0x5E,
+ LAUNCH7 = SPECIAL | 0x5F,
+ LAUNCH8 = SPECIAL | 0x60,
+ LAUNCH9 = SPECIAL | 0x61,
+ LAUNCHA = SPECIAL | 0x62,
+ LAUNCHB = SPECIAL | 0x63,
+ LAUNCHC = SPECIAL | 0x64,
+ LAUNCHD = SPECIAL | 0x65,
+ LAUNCHE = SPECIAL | 0x66,
+ LAUNCHF = SPECIAL | 0x67,
- KEY_UNKNOWN = SPKEY | 0xFFFFFF,
+ UNKNOWN = SPECIAL | 0xFFFFFF,
/* PRINTABLE LATIN 1 CODES */
- KEY_SPACE = 0x0020,
- KEY_EXCLAM = 0x0021,
- KEY_QUOTEDBL = 0x0022,
- KEY_NUMBERSIGN = 0x0023,
- KEY_DOLLAR = 0x0024,
- KEY_PERCENT = 0x0025,
- KEY_AMPERSAND = 0x0026,
- KEY_APOSTROPHE = 0x0027,
- KEY_PARENLEFT = 0x0028,
- KEY_PARENRIGHT = 0x0029,
- KEY_ASTERISK = 0x002A,
- KEY_PLUS = 0x002B,
- KEY_COMMA = 0x002C,
- KEY_MINUS = 0x002D,
- KEY_PERIOD = 0x002E,
- KEY_SLASH = 0x002F,
+ SPACE = 0x0020,
+ EXCLAM = 0x0021,
+ QUOTEDBL = 0x0022,
+ NUMBERSIGN = 0x0023,
+ DOLLAR = 0x0024,
+ PERCENT = 0x0025,
+ AMPERSAND = 0x0026,
+ APOSTROPHE = 0x0027,
+ PARENLEFT = 0x0028,
+ PARENRIGHT = 0x0029,
+ ASTERISK = 0x002A,
+ PLUS = 0x002B,
+ COMMA = 0x002C,
+ MINUS = 0x002D,
+ PERIOD = 0x002E,
+ SLASH = 0x002F,
KEY_0 = 0x0030,
KEY_1 = 0x0031,
KEY_2 = 0x0032,
@@ -185,134 +179,133 @@ enum Key {
KEY_7 = 0x0037,
KEY_8 = 0x0038,
KEY_9 = 0x0039,
- KEY_COLON = 0x003A,
- KEY_SEMICOLON = 0x003B,
- KEY_LESS = 0x003C,
- KEY_EQUAL = 0x003D,
- KEY_GREATER = 0x003E,
- KEY_QUESTION = 0x003F,
- KEY_AT = 0x0040,
- KEY_A = 0x0041,
- KEY_B = 0x0042,
- KEY_C = 0x0043,
- KEY_D = 0x0044,
- KEY_E = 0x0045,
- KEY_F = 0x0046,
- KEY_G = 0x0047,
- KEY_H = 0x0048,
- KEY_I = 0x0049,
- KEY_J = 0x004A,
- KEY_K = 0x004B,
- KEY_L = 0x004C,
- KEY_M = 0x004D,
- KEY_N = 0x004E,
- KEY_O = 0x004F,
- KEY_P = 0x0050,
- KEY_Q = 0x0051,
- KEY_R = 0x0052,
- KEY_S = 0x0053,
- KEY_T = 0x0054,
- KEY_U = 0x0055,
- KEY_V = 0x0056,
- KEY_W = 0x0057,
- KEY_X = 0x0058,
- KEY_Y = 0x0059,
- KEY_Z = 0x005A,
- KEY_BRACKETLEFT = 0x005B,
- KEY_BACKSLASH = 0x005C,
- KEY_BRACKETRIGHT = 0x005D,
- KEY_ASCIICIRCUM = 0x005E,
- KEY_UNDERSCORE = 0x005F,
- KEY_QUOTELEFT = 0x0060,
- KEY_BRACELEFT = 0x007B,
- KEY_BAR = 0x007C,
- KEY_BRACERIGHT = 0x007D,
- KEY_ASCIITILDE = 0x007E,
- KEY_NOBREAKSPACE = 0x00A0,
- KEY_EXCLAMDOWN = 0x00A1,
- KEY_CENT = 0x00A2,
- KEY_STERLING = 0x00A3,
- KEY_CURRENCY = 0x00A4,
- KEY_YEN = 0x00A5,
- KEY_BROKENBAR = 0x00A6,
- KEY_SECTION = 0x00A7,
- KEY_DIAERESIS = 0x00A8,
- KEY_COPYRIGHT = 0x00A9,
- KEY_ORDFEMININE = 0x00AA,
- KEY_GUILLEMOTLEFT = 0x00AB,
- KEY_NOTSIGN = 0x00AC,
- KEY_HYPHEN = 0x00AD,
- KEY_REGISTERED = 0x00AE,
- KEY_MACRON = 0x00AF,
- KEY_DEGREE = 0x00B0,
- KEY_PLUSMINUS = 0x00B1,
- KEY_TWOSUPERIOR = 0x00B2,
- KEY_THREESUPERIOR = 0x00B3,
- KEY_ACUTE = 0x00B4,
- KEY_MU = 0x00B5,
- KEY_PARAGRAPH = 0x00B6,
- KEY_PERIODCENTERED = 0x00B7,
- KEY_CEDILLA = 0x00B8,
- KEY_ONESUPERIOR = 0x00B9,
- KEY_MASCULINE = 0x00BA,
- KEY_GUILLEMOTRIGHT = 0x00BB,
- KEY_ONEQUARTER = 0x00BC,
- KEY_ONEHALF = 0x00BD,
- KEY_THREEQUARTERS = 0x00BE,
- KEY_QUESTIONDOWN = 0x00BF,
- KEY_AGRAVE = 0x00C0,
- KEY_AACUTE = 0x00C1,
- KEY_ACIRCUMFLEX = 0x00C2,
- KEY_ATILDE = 0x00C3,
- KEY_ADIAERESIS = 0x00C4,
- KEY_ARING = 0x00C5,
- KEY_AE = 0x00C6,
- KEY_CCEDILLA = 0x00C7,
- KEY_EGRAVE = 0x00C8,
- KEY_EACUTE = 0x00C9,
- KEY_ECIRCUMFLEX = 0x00CA,
- KEY_EDIAERESIS = 0x00CB,
- KEY_IGRAVE = 0x00CC,
- KEY_IACUTE = 0x00CD,
- KEY_ICIRCUMFLEX = 0x00CE,
- KEY_IDIAERESIS = 0x00CF,
- KEY_ETH = 0x00D0,
- KEY_NTILDE = 0x00D1,
- KEY_OGRAVE = 0x00D2,
- KEY_OACUTE = 0x00D3,
- KEY_OCIRCUMFLEX = 0x00D4,
- KEY_OTILDE = 0x00D5,
- KEY_ODIAERESIS = 0x00D6,
- KEY_MULTIPLY = 0x00D7,
- KEY_OOBLIQUE = 0x00D8,
- KEY_UGRAVE = 0x00D9,
- KEY_UACUTE = 0x00DA,
- KEY_UCIRCUMFLEX = 0x00DB,
- KEY_UDIAERESIS = 0x00DC,
- KEY_YACUTE = 0x00DD,
- KEY_THORN = 0x00DE,
- KEY_SSHARP = 0x00DF,
+ COLON = 0x003A,
+ SEMICOLON = 0x003B,
+ LESS = 0x003C,
+ EQUAL = 0x003D,
+ GREATER = 0x003E,
+ QUESTION = 0x003F,
+ AT = 0x0040,
+ A = 0x0041,
+ B = 0x0042,
+ C = 0x0043,
+ D = 0x0044,
+ E = 0x0045,
+ F = 0x0046,
+ G = 0x0047,
+ H = 0x0048,
+ I = 0x0049,
+ J = 0x004A,
+ K = 0x004B,
+ L = 0x004C,
+ M = 0x004D,
+ N = 0x004E,
+ O = 0x004F,
+ P = 0x0050,
+ Q = 0x0051,
+ R = 0x0052,
+ S = 0x0053,
+ T = 0x0054,
+ U = 0x0055,
+ V = 0x0056,
+ W = 0x0057,
+ X = 0x0058,
+ Y = 0x0059,
+ Z = 0x005A,
+ BRACKETLEFT = 0x005B,
+ BACKSLASH = 0x005C,
+ BRACKETRIGHT = 0x005D,
+ ASCIICIRCUM = 0x005E,
+ UNDERSCORE = 0x005F,
+ QUOTELEFT = 0x0060,
+ BRACELEFT = 0x007B,
+ BAR = 0x007C,
+ BRACERIGHT = 0x007D,
+ ASCIITILDE = 0x007E,
+ NOBREAKSPACE = 0x00A0,
+ EXCLAMDOWN = 0x00A1,
+ CENT = 0x00A2,
+ STERLING = 0x00A3,
+ CURRENCY = 0x00A4,
+ YEN = 0x00A5,
+ BROKENBAR = 0x00A6,
+ SECTION = 0x00A7,
+ DIAERESIS = 0x00A8,
+ COPYRIGHT = 0x00A9,
+ ORDFEMININE = 0x00AA,
+ GUILLEMOTLEFT = 0x00AB,
+ NOTSIGN = 0x00AC,
+ HYPHEN = 0x00AD,
+ KEY_REGISTERED = 0x00AE, // "REGISTERED" is a reserved word on Windows.
+ MACRON = 0x00AF,
+ DEGREE = 0x00B0,
+ PLUSMINUS = 0x00B1,
+ TWOSUPERIOR = 0x00B2,
+ THREESUPERIOR = 0x00B3,
+ ACUTE = 0x00B4,
+ MU = 0x00B5,
+ PARAGRAPH = 0x00B6,
+ PERIODCENTERED = 0x00B7,
+ CEDILLA = 0x00B8,
+ ONESUPERIOR = 0x00B9,
+ MASCULINE = 0x00BA,
+ GUILLEMOTRIGHT = 0x00BB,
+ ONEQUARTER = 0x00BC,
+ ONEHALF = 0x00BD,
+ THREEQUARTERS = 0x00BE,
+ QUESTIONDOWN = 0x00BF,
+ AGRAVE = 0x00C0,
+ AACUTE = 0x00C1,
+ ACIRCUMFLEX = 0x00C2,
+ ATILDE = 0x00C3,
+ ADIAERESIS = 0x00C4,
+ ARING = 0x00C5,
+ AE = 0x00C6,
+ CCEDILLA = 0x00C7,
+ EGRAVE = 0x00C8,
+ EACUTE = 0x00C9,
+ ECIRCUMFLEX = 0x00CA,
+ EDIAERESIS = 0x00CB,
+ IGRAVE = 0x00CC,
+ IACUTE = 0x00CD,
+ ICIRCUMFLEX = 0x00CE,
+ IDIAERESIS = 0x00CF,
+ ETH = 0x00D0,
+ NTILDE = 0x00D1,
+ OGRAVE = 0x00D2,
+ OACUTE = 0x00D3,
+ OCIRCUMFLEX = 0x00D4,
+ OTILDE = 0x00D5,
+ ODIAERESIS = 0x00D6,
+ MULTIPLY = 0x00D7,
+ OOBLIQUE = 0x00D8,
+ UGRAVE = 0x00D9,
+ UACUTE = 0x00DA,
+ UCIRCUMFLEX = 0x00DB,
+ UDIAERESIS = 0x00DC,
+ YACUTE = 0x00DD,
+ THORN = 0x00DE,
+ SSHARP = 0x00DF,
- KEY_DIVISION = 0x00F7,
- KEY_YDIAERESIS = 0x00FF,
+ DIVISION = 0x00F7,
+ YDIAERESIS = 0x00FF,
+ END_LATIN1 = 0x0100,
};
-enum KeyModifierMask {
- KEY_CODE_MASK = ((1 << 25) - 1), ///< Apply this mask to any keycode to remove modifiers.
- KEY_MODIFIER_MASK = (0xFF << 24), ///< Apply this mask to isolate modifiers.
- KEY_MASK_SHIFT = (1 << 25),
- KEY_MASK_ALT = (1 << 26),
- KEY_MASK_META = (1 << 27),
- KEY_MASK_CTRL = (1 << 28),
+enum class KeyModifierMask {
+ CODE_MASK = ((1 << 25) - 1), ///< Apply this mask to any keycode to remove modifiers.
+ MODIFIER_MASK = (0xFF << 24), ///< Apply this mask to isolate modifiers.
+ SHIFT = (1 << 25),
+ ALT = (1 << 26),
+ META = (1 << 27),
+ CTRL = (1 << 28),
#ifdef APPLE_STYLE_KEYS
- KEY_MASK_CMD = KEY_MASK_META,
+ CMD = META,
#else
- KEY_MASK_CMD = KEY_MASK_CTRL,
+ CMD = CTRL,
#endif
-
- KEY_MASK_KPAD = (1 << 29),
- KEY_MASK_GROUP_SWITCH = (1 << 30)
- // bit 31 can't be used because variant uses regular 32 bits int as datatype
+ KPAD = (1 << 29),
+ GROUP_SWITCH = (1 << 30)
};
// To avoid having unnecessary operators, only define the ones that are needed.
@@ -325,10 +318,26 @@ inline Key &operator-=(Key &a, int b) {
return (Key &)((int &)a -= b);
}
+inline Key operator+(Key a, int b) {
+ return (Key)((int)a + (int)b);
+}
+
inline Key operator+(Key a, Key b) {
+ return (Key)((int)a + (int)b);
+}
+
+inline Key operator-(Key a, Key b) {
return (Key)((int)a - (int)b);
}
+inline Key operator&(Key a, Key b) {
+ return (Key)((int)a & (int)b);
+}
+
+inline Key operator|(Key a, Key b) {
+ return (Key)((int)a | (int)b);
+}
+
inline Key &operator|=(Key &a, Key b) {
return (Key &)((int &)a |= (int)b);
}
@@ -337,6 +346,10 @@ inline Key &operator|=(Key &a, KeyModifierMask b) {
return (Key &)((int &)a |= (int)b);
}
+inline Key &operator&=(Key &a, KeyModifierMask b) {
+ return (Key &)((int &)a &= (int)b);
+}
+
inline Key operator|(Key a, KeyModifierMask b) {
return (Key)((int)a | (int)b);
}
@@ -361,10 +374,10 @@ inline KeyModifierMask operator|(KeyModifierMask a, KeyModifierMask b) {
return (KeyModifierMask)((int)a | (int)b);
}
-String keycode_get_string(uint32_t p_code);
-bool keycode_has_unicode(uint32_t p_keycode);
-int find_keycode(const String &p_code);
-const char *find_keycode_name(int p_keycode);
+String keycode_get_string(Key p_code);
+bool keycode_has_unicode(Key p_keycode);
+Key find_keycode(const String &p_code);
+const char *find_keycode_name(Key p_keycode);
int keycode_get_count();
int keycode_get_value_by_index(int p_index);
const char *keycode_get_name_by_index(int p_index);
diff --git a/core/os/memory.h b/core/os/memory.h
index f67384a17e..ac56a12330 100644
--- a/core/os/memory.h
+++ b/core/os/memory.h
@@ -42,7 +42,6 @@
#endif
class Memory {
- Memory();
#ifdef DEBUG_ENABLED
static SafeNumeric<uint64_t> mem_usage;
static SafeNumeric<uint64_t> max_usage;
diff --git a/core/os/midi_driver.cpp b/core/os/midi_driver.cpp
index ee87346dfc..ee33eef83f 100644
--- a/core/os/midi_driver.cpp
+++ b/core/os/midi_driver.cpp
@@ -68,46 +68,46 @@ void MIDIDriver::receive_input_packet(uint64_t timestamp, uint8_t *data, uint32_
}
switch (event->get_message()) {
- case MIDI_MESSAGE_AFTERTOUCH:
+ case MIDIMessage::AFTERTOUCH:
if (length >= 2 + param_position) {
event->set_pitch(data[param_position]);
event->set_pressure(data[param_position + 1]);
}
break;
- case MIDI_MESSAGE_CONTROL_CHANGE:
+ case MIDIMessage::CONTROL_CHANGE:
if (length >= 2 + param_position) {
event->set_controller_number(data[param_position]);
event->set_controller_value(data[param_position + 1]);
}
break;
- case MIDI_MESSAGE_NOTE_ON:
- case MIDI_MESSAGE_NOTE_OFF:
+ case MIDIMessage::NOTE_ON:
+ case MIDIMessage::NOTE_OFF:
if (length >= 2 + param_position) {
event->set_pitch(data[param_position]);
event->set_velocity(data[param_position + 1]);
- if (event->get_message() == MIDI_MESSAGE_NOTE_ON && event->get_velocity() == 0) {
+ if (event->get_message() == MIDIMessage::NOTE_ON && event->get_velocity() == 0) {
// https://www.midi.org/forum/228-writing-midi-software-send-note-off,-or-zero-velocity-note-on
- event->set_message(MIDI_MESSAGE_NOTE_OFF);
+ event->set_message(MIDIMessage::NOTE_OFF);
}
}
break;
- case MIDI_MESSAGE_PITCH_BEND:
+ case MIDIMessage::PITCH_BEND:
if (length >= 2 + param_position) {
event->set_pitch((data[param_position + 1] << 7) | data[param_position]);
}
break;
- case MIDI_MESSAGE_PROGRAM_CHANGE:
+ case MIDIMessage::PROGRAM_CHANGE:
if (length >= 1 + param_position) {
event->set_instrument(data[param_position]);
}
break;
- case MIDI_MESSAGE_CHANNEL_PRESSURE:
+ case MIDIMessage::CHANNEL_PRESSURE:
if (length >= 1 + param_position) {
event->set_pressure(data[param_position]);
}
diff --git a/core/os/os.cpp b/core/os/os.cpp
index 12f85858c3..c8b8931919 100644
--- a/core/os/os.cpp
+++ b/core/os/os.cpp
@@ -75,12 +75,12 @@ void OS::add_logger(Logger *p_logger) {
}
}
-void OS::print_error(const char *p_function, const char *p_file, int p_line, const char *p_code, const char *p_rationale, Logger::ErrorType p_type) {
+void OS::print_error(const char *p_function, const char *p_file, int p_line, const char *p_code, const char *p_rationale, bool p_editor_notify, Logger::ErrorType p_type) {
if (!_stderr_enabled) {
return;
}
- _logger->log_error(p_function, p_file, p_line, p_code, p_rationale, p_type);
+ _logger->log_error(p_function, p_file, p_line, p_code, p_rationale, p_editor_notify, p_type);
}
void OS::print(const char *p_format, ...) {
@@ -190,8 +190,8 @@ static void _OS_printres(Object *p_obj) {
}
void OS::print_all_resources(String p_to_file) {
- ERR_FAIL_COND(p_to_file != "" && _OSPRF);
- if (p_to_file != "") {
+ ERR_FAIL_COND(!p_to_file.is_empty() && _OSPRF);
+ if (!p_to_file.is_empty()) {
Error err;
_OSPRF = FileAccess::open(p_to_file, FileAccess::WRITE, &err);
if (err != OK) {
@@ -202,7 +202,7 @@ void OS::print_all_resources(String p_to_file) {
ObjectDB::debug_objects(_OS_printres);
- if (p_to_file != "") {
+ if (!p_to_file.is_empty()) {
if (_OSPRF) {
memdelete(_OSPRF);
}
@@ -431,6 +431,24 @@ bool OS::has_feature(const String &p_feature) {
if (p_feature == "arm") {
return true;
}
+#elif defined(__riscv)
+#if __riscv_xlen == 8
+ if (p_feature == "rv64") {
+ return true;
+ }
+#endif
+ if (p_feature == "riscv") {
+ return true;
+ }
+#elif defined(__powerpc__)
+#if defined(__powerpc64__)
+ if (p_feature == "ppc64") {
+ return true;
+ }
+#endif
+ if (p_feature == "ppc") {
+ return true;
+ }
#endif
if (_check_internal_feature_support(p_feature)) {
diff --git a/core/os/os.h b/core/os/os.h
index 29d33ce4f0..3042696cce 100644
--- a/core/os/os.h
+++ b/core/os/os.h
@@ -68,6 +68,11 @@ class OS {
bool restart_on_exit = false;
List<String> restart_commandline;
+ // for the user interface we keep a record of the current display driver
+ // so we can retrieve the rendering drivers available
+ int _display_driver_id = -1;
+ String _current_rendering_driver_name = "";
+
protected:
void _set_logger(CompositeLogger *p_logger);
@@ -81,6 +86,11 @@ public:
RENDER_SEPARATE_THREAD
};
+ enum RenderMainThreadMode {
+ RENDER_MAIN_THREAD_ONLY,
+ RENDER_ANY_THREAD,
+ };
+
protected:
friend class Main;
// Needed by tests to setup command-line args.
@@ -88,6 +98,7 @@ protected:
HasServerFeatureCallback has_server_feature_callback = nullptr;
RenderThreadMode _render_thread_mode = RENDER_THREAD_SAFE;
+ RenderMainThreadMode _render_main_thread_mode = RENDER_ANY_THREAD;
// Functions used by Main to initialize/deinitialize the OS.
void add_logger(Logger *p_logger);
@@ -95,6 +106,9 @@ protected:
virtual void initialize() = 0;
virtual void initialize_joypads() = 0;
+ void set_current_rendering_driver_name(String p_driver_name) { _current_rendering_driver_name = p_driver_name; }
+ void set_display_driver_id(int p_display_driver_id) { _display_driver_id = p_display_driver_id; }
+
virtual void set_main_loop(MainLoop *p_main_loop) = 0;
virtual void delete_main_loop() = 0;
@@ -110,7 +124,10 @@ public:
static OS *get_singleton();
- void print_error(const char *p_function, const char *p_file, int p_line, const char *p_code, const char *p_rationale, Logger::ErrorType p_type = Logger::ERR_ERROR);
+ String get_current_rendering_driver_name() const { return _current_rendering_driver_name; }
+ int get_display_driver_id() const { return _display_driver_id; }
+
+ void print_error(const char *p_function, const char *p_file, int p_line, const char *p_code, const char *p_rationale, bool p_editor_notify = false, Logger::ErrorType p_type = Logger::ERR_ERROR);
void print(const char *p_format, ...) _PRINTF_FORMAT_ATTRIBUTE_2_3;
void printerr(const char *p_format, ...) _PRINTF_FORMAT_ATTRIBUTE_2_3;
@@ -134,6 +151,7 @@ public:
virtual String get_executable_path() const;
virtual Error execute(const String &p_path, const List<String> &p_arguments, String *r_pipe = nullptr, int *r_exitcode = nullptr, bool read_stderr = false, Mutex *p_pipe_mutex = nullptr) = 0;
virtual Error create_process(const String &p_path, const List<String> &p_arguments, ProcessID *r_child_id = nullptr) = 0;
+ virtual Error create_instance(const List<String> &p_arguments, ProcessID *r_child_id = nullptr) { return create_process(get_executable_path(), p_arguments, r_child_id); };
virtual Error kill(const ProcessID &p_pid) = 0;
virtual int get_process_id() const;
virtual void vibrate_handheld(int p_duration_ms = 500);
@@ -204,8 +222,8 @@ public:
String name;
};
- virtual Date get_date(bool local = false) const = 0;
- virtual Time get_time(bool local = false) const = 0;
+ virtual Date get_date(bool p_utc = false) const = 0;
+ virtual Time get_time(bool p_utc = false) const = 0;
virtual TimeZoneInfo get_time_zone_info() const = 0;
virtual double get_unix_time() const;
@@ -225,7 +243,7 @@ public:
void set_stdout_enabled(bool p_enabled);
void set_stderr_enabled(bool p_enabled);
- bool is_single_window() const;
+ virtual bool is_single_window() const;
virtual void disable_crash_handler() {}
virtual bool is_disable_crash_handler() const { return false; }
@@ -241,6 +259,8 @@ public:
virtual uint64_t get_free_static_memory() const;
RenderThreadMode get_render_thread_mode() const { return _render_thread_mode; }
+ RenderMainThreadMode get_render_main_thread_mode() const { return _render_main_thread_mode; }
+ void set_render_main_thread_mode(RenderMainThreadMode p_thread_mode) { _render_main_thread_mode = p_thread_mode; }
virtual String get_locale() const;
String get_locale_language() const;
@@ -278,6 +298,7 @@ public:
virtual void set_exit_code(int p_code);
virtual int get_processor_count() const;
+ virtual int get_default_thread_pool_size() const { return get_processor_count(); }
virtual String get_unique_id() const;
diff --git a/core/string/node_path.cpp b/core/string/node_path.cpp
index 5fae13779e..bb9a44ccaf 100644
--- a/core/string/node_path.cpp
+++ b/core/string/node_path.cpp
@@ -293,12 +293,12 @@ void NodePath::simplify() {
break;
}
if (data->path[i].operator String() == ".") {
- data->path.remove(i);
+ data->path.remove_at(i);
i--;
} else if (i > 0 && data->path[i].operator String() == ".." && data->path[i - 1].operator String() != "." && data->path[i - 1].operator String() != "..") {
//remove both
- data->path.remove(i - 1);
- data->path.remove(i - 1);
+ data->path.remove_at(i - 1);
+ data->path.remove_at(i - 1);
i -= 2;
if (data->path.size() == 0) {
data->path.push_back(".");
@@ -368,7 +368,7 @@ NodePath::NodePath(const String &p_path) {
for (int i = from; i <= path.length(); i++) {
if (path[i] == ':' || path[i] == 0) {
String str = path.substr(from, i - from);
- if (str == "") {
+ if (str.is_empty()) {
if (path[i] == 0) {
continue; // Allow end-of-path :
}
diff --git a/core/string/print_string.cpp b/core/string/print_string.cpp
index 345371d733..adc218f597 100644
--- a/core/string/print_string.cpp
+++ b/core/string/print_string.cpp
@@ -69,7 +69,7 @@ void remove_print_handler(PrintHandlerList *p_handler) {
ERR_FAIL_COND(l == nullptr);
}
-void print_line(String p_string) {
+void __print_line(String p_string) {
if (!_print_line_enabled) {
return;
}
@@ -108,3 +108,7 @@ void print_verbose(String p_string) {
print_line(p_string);
}
}
+
+String stringify_variants(Variant p_var) {
+ return p_var.operator String();
+}
diff --git a/core/string/print_string.h b/core/string/print_string.h
index 1a9ff1efd6..3cd170b68e 100644
--- a/core/string/print_string.h
+++ b/core/string/print_string.h
@@ -31,7 +31,7 @@
#ifndef PRINT_STRING_H
#define PRINT_STRING_H
-#include "core/string/ustring.h"
+#include "core/variant/variant.h"
extern void (*_print_func)(String);
@@ -46,13 +46,21 @@ struct PrintHandlerList {
PrintHandlerList() {}
};
+String stringify_variants(Variant p_var);
+
+template <typename... Args>
+String stringify_variants(Variant p_var, Args... p_args) {
+ return p_var.operator String() + " " + stringify_variants(p_args...);
+}
+
void add_print_handler(PrintHandlerList *p_handler);
void remove_print_handler(PrintHandlerList *p_handler);
extern bool _print_line_enabled;
extern bool _print_error_enabled;
-extern void print_line(String p_string);
+extern void __print_line(String p_string);
extern void print_error(String p_string);
extern void print_verbose(String p_string);
+#define print_line(...) __print_line(stringify_variants(__VA_ARGS__))
#endif // PRINT_STRING_H
diff --git a/core/string/string_builder.cpp b/core/string/string_builder.cpp
index 834c87c845..45cc2f3280 100644
--- a/core/string/string_builder.cpp
+++ b/core/string/string_builder.cpp
@@ -33,7 +33,7 @@
#include <string.h>
StringBuilder &StringBuilder::append(const String &p_string) {
- if (p_string == String()) {
+ if (p_string.is_empty()) {
return *this;
}
diff --git a/core/string/string_name.cpp b/core/string/string_name.cpp
index 9024f60dae..0e3482e873 100644
--- a/core/string/string_name.cpp
+++ b/core/string/string_name.cpp
@@ -310,7 +310,7 @@ StringName::StringName(const String &p_name, bool p_static) {
ERR_FAIL_COND(!configured);
- if (p_name == String()) {
+ if (p_name.is_empty()) {
return;
}
@@ -434,7 +434,7 @@ StringName StringName::search(const char32_t *p_name) {
}
StringName StringName::search(const String &p_name) {
- ERR_FAIL_COND_V(p_name == "", StringName());
+ ERR_FAIL_COND_V(p_name.is_empty(), StringName());
MutexLock lock(mutex);
diff --git a/core/string/translation.cpp b/core/string/translation.cpp
index cf61467d08..73f789b041 100644
--- a/core/string/translation.cpp
+++ b/core/string/translation.cpp
@@ -938,7 +938,7 @@ void Translation::_bind_methods() {
GDVIRTUAL_BIND(_get_plural_message, "src_message", "src_plural_message", "n", "context");
GDVIRTUAL_BIND(_get_message, "src_message", "context");
- ADD_PROPERTY(PropertyInfo(Variant::DICTIONARY, "messages", PROPERTY_HINT_NONE, "", PROPERTY_USAGE_NOEDITOR | PROPERTY_USAGE_INTERNAL), "_set_messages", "_get_messages");
+ ADD_PROPERTY(PropertyInfo(Variant::DICTIONARY, "messages", PROPERTY_HINT_NONE, "", PROPERTY_USAGE_NO_EDITOR | PROPERTY_USAGE_INTERNAL), "_set_messages", "_get_messages");
ADD_PROPERTY(PropertyInfo(Variant::STRING, "locale"), "set_locale", "get_locale");
}
@@ -1287,7 +1287,7 @@ bool TranslationServer::_load_translations(const String &p_from) {
void TranslationServer::setup() {
String test = GLOBAL_DEF("internationalization/locale/test", "");
test = test.strip_edges();
- if (test != "") {
+ if (!test.is_empty()) {
set_locale(test);
} else {
set_locale(OS::get_singleton()->get_locale());
@@ -1563,8 +1563,8 @@ const char32_t *TranslationServer::get_accented_version(char32_t p_character) co
bool TranslationServer::is_placeholder(String &p_message, int p_index) const {
return p_message[p_index] == '%' && p_index < p_message.size() - 1 &&
- (p_message[p_index + 1] == 's' || p_message[p_index + 1] == 'c' || p_message[p_index + 1] == 'd' ||
- p_message[p_index + 1] == 'o' || p_message[p_index + 1] == 'x' || p_message[p_index + 1] == 'X' || p_message[p_index + 1] == 'f');
+ (p_message[p_index + 1] == 's' || p_message[p_index + 1] == 'c' || p_message[p_index + 1] == 'd' ||
+ p_message[p_index + 1] == 'o' || p_message[p_index + 1] == 'x' || p_message[p_index + 1] == 'X' || p_message[p_index + 1] == 'f');
}
void TranslationServer::_bind_methods() {
diff --git a/core/string/ustring.cpp b/core/string/ustring.cpp
index daeb7fbd17..ac8e2ece12 100644
--- a/core/string/ustring.cpp
+++ b/core/string/ustring.cpp
@@ -38,6 +38,7 @@
#include "core/string/translation.h"
#include "core/string/ucaps.h"
#include "core/variant/variant.h"
+#include "core/version_generated.gen.h"
#include <stdio.h>
#include <stdlib.h>
@@ -129,9 +130,8 @@ Char16String &Char16String::operator+=(char16_t p_char) {
return *this;
}
-Char16String &Char16String::operator=(const char16_t *p_cstr) {
+void Char16String::operator=(const char16_t *p_cstr) {
copy_from(p_cstr);
- return *this;
}
const char16_t *Char16String::get_data() const {
@@ -185,9 +185,8 @@ CharString &CharString::operator+=(char p_char) {
return *this;
}
-CharString &CharString::operator=(const char *p_cstr) {
+void CharString::operator=(const char *p_cstr) {
copy_from(p_cstr);
- return *this;
}
const char *CharString::get_data() const {
@@ -952,10 +951,6 @@ const char32_t *String::get_data() const {
return size() ? &operator[](0) : &zero;
}
-void String::erase(int p_pos, int p_chars) {
- *this = left(MAX(p_pos, 0)) + substr(p_pos + p_chars, length() - ((p_pos + p_chars)));
-}
-
String String::capitalize() const {
String aux = this->camelcase_to_underscore(true).replace("_", " ").strip_edges();
String cap;
@@ -2137,7 +2132,7 @@ int64_t String::hex_to_int() const {
s++;
}
- if (len > 2 && s[0] == '0' && s[1] == 'x') {
+ if (len > 2 && s[0] == '0' && lower_case(s[1]) == 'x') {
s += 2;
}
@@ -2151,7 +2146,7 @@ int64_t String::hex_to_int() const {
} else if (c >= 'a' && c <= 'f') {
n = (c - 'a') + 10;
} else {
- return 0;
+ ERR_FAIL_COND_V_MSG(true, 0, "Invalid hexadecimal notation character \"" + chr(*s) + "\" in string \"" + *this + "\".");
}
// Check for overflow/underflow, with special case to ensure INT64_MIN does not result in error
bool overflow = ((hex > INT64_MAX / 16) && (sign == 1 || (sign == -1 && hex != (INT64_MAX >> 4) + 1))) || (sign == -1 && hex == (INT64_MAX >> 4) + 1 && c > '0');
@@ -2178,7 +2173,7 @@ int64_t String::bin_to_int() const {
s++;
}
- if (len > 2 && s[0] == '0' && s[1] == 'b') {
+ if (len > 2 && s[0] == '0' && lower_case(s[1]) == 'b') {
s += 2;
}
@@ -2317,28 +2312,33 @@ bool String::is_numeric() const {
}
template <class C>
-static double built_in_strtod(const C *string, /* A decimal ASCII floating-point number,
- * optionally preceded by white space. Must
- * have form "-I.FE-X", where I is the integer
- * part of the mantissa, F is the fractional
- * part of the mantissa, and X is the
- * exponent. Either of the signs may be "+",
- * "-", or omitted. Either I or F may be
- * omitted, or both. The decimal point isn't
- * necessary unless F is present. The "E" may
- * actually be an "e". E and X may both be
- * omitted (but not just one). */
- C **endPtr = nullptr) /* If non-nullptr, store terminating Cacter's
- * address here. */
-{
- static const int maxExponent = 511; /* Largest possible base 10 exponent. Any
- * exponent larger than this will already
- * produce underflow or overflow, so there's
- * no need to worry about additional digits.
- */
- static const double powersOf10[] = { /* Table giving binary powers of 10. Entry */
- 10., /* is 10^2^i. Used to convert decimal */
- 100., /* exponents into floating-point numbers. */
+static double built_in_strtod(
+ /* A decimal ASCII floating-point number,
+ * optionally preceded by white space. Must
+ * have form "-I.FE-X", where I is the integer
+ * part of the mantissa, F is the fractional
+ * part of the mantissa, and X is the
+ * exponent. Either of the signs may be "+",
+ * "-", or omitted. Either I or F may be
+ * omitted, or both. The decimal point isn't
+ * necessary unless F is present. The "E" may
+ * actually be an "e". E and X may both be
+ * omitted (but not just one). */
+ const C *string,
+ /* If non-nullptr, store terminating Cacter's
+ * address here. */
+ C **endPtr = nullptr) {
+ /* Largest possible base 10 exponent. Any
+ * exponent larger than this will already
+ * produce underflow or overflow, so there's
+ * no need to worry about additional digits. */
+ static const int maxExponent = 511;
+ /* Table giving binary powers of 10. Entry
+ * is 10^2^i. Used to convert decimal
+ * exponents into floating-point numbers. */
+ static const double powersOf10[] = {
+ 10.,
+ 100.,
1.0e4,
1.0e8,
1.0e16,
@@ -2353,25 +2353,28 @@ static double built_in_strtod(const C *string, /* A decimal ASCII floating-point
const double *d;
const C *p;
int c;
- int exp = 0; /* Exponent read from "EX" field. */
- int fracExp = 0; /* Exponent that derives from the fractional
- * part. Under normal circumstances, it is
- * the negative of the number of digits in F.
- * However, if I is very long, the last digits
- * of I get dropped (otherwise a long I with a
- * large negative exponent could cause an
- * unnecessary overflow on I alone). In this
- * case, fracExp is incremented one for each
- * dropped digit. */
- int mantSize; /* Number of digits in mantissa. */
- int decPt; /* Number of mantissa digits BEFORE decimal
- * point. */
- const C *pExp; /* Temporarily holds location of exponent in
- * string. */
+ /* Exponent read from "EX" field. */
+ int exp = 0;
+ /* Exponent that derives from the fractional
+ * part. Under normal circumstances, it is
+ * the negative of the number of digits in F.
+ * However, if I is very long, the last digits
+ * of I get dropped (otherwise a long I with a
+ * large negative exponent could cause an
+ * unnecessary overflow on I alone). In this
+ * case, fracExp is incremented one for each
+ * dropped digit. */
+ int fracExp = 0;
+ /* Number of digits in mantissa. */
+ int mantSize;
+ /* Number of mantissa digits BEFORE decimal point. */
+ int decPt;
+ /* Temporarily holds location of exponent in string. */
+ const C *pExp;
/*
- * Strip off leading blanks and check for a sign.
- */
+ * Strip off leading blanks and check for a sign.
+ */
p = string;
while (*p == ' ' || *p == '\t' || *p == '\n') {
@@ -2388,9 +2391,9 @@ static double built_in_strtod(const C *string, /* A decimal ASCII floating-point
}
/*
- * Count the number of digits in the mantissa (including the decimal
- * point), and also locate the decimal point.
- */
+ * Count the number of digits in the mantissa (including the decimal
+ * point), and also locate the decimal point.
+ */
decPt = -1;
for (mantSize = 0;; mantSize += 1) {
@@ -2405,11 +2408,11 @@ static double built_in_strtod(const C *string, /* A decimal ASCII floating-point
}
/*
- * Now suck up the digits in the mantissa. Use two integers to collect 9
- * digits each (this is faster than using floating-point). If the mantissa
- * has more than 18 digits, ignore the extras, since they can't affect the
- * value anyway.
- */
+ * Now suck up the digits in the mantissa. Use two integers to collect 9
+ * digits each (this is faster than using floating-point). If the mantissa
+ * has more than 18 digits, ignore the extras, since they can't affect the
+ * value anyway.
+ */
pExp = p;
p -= mantSize;
@@ -2455,8 +2458,8 @@ static double built_in_strtod(const C *string, /* A decimal ASCII floating-point
}
/*
- * Skim off the exponent.
- */
+ * Skim off the exponent.
+ */
p = pExp;
if ((*p == 'E') || (*p == 'e')) {
@@ -2486,10 +2489,10 @@ static double built_in_strtod(const C *string, /* A decimal ASCII floating-point
}
/*
- * Generate a floating-point number that represents the exponent. Do this
- * by processing the exponent one bit at a time to combine many powers of
- * 2 of 10. Then combine the exponent with the fraction.
- */
+ * Generate a floating-point number that represents the exponent. Do this
+ * by processing the exponent one bit at a time to combine many powers of
+ * 2 of 10. Then combine the exponent with the fraction.
+ */
if (exp < 0) {
expSign = true;
@@ -3665,15 +3668,15 @@ String String::simplify_path() const {
for (int i = 0; i < dirs.size(); i++) {
String d = dirs[i];
if (d == ".") {
- dirs.remove(i);
+ dirs.remove_at(i);
i--;
} else if (d == "..") {
if (i == 0) {
- dirs.remove(i);
+ dirs.remove_at(i);
i--;
} else {
- dirs.remove(i);
- dirs.remove(i - 1);
+ dirs.remove_at(i);
+ dirs.remove_at(i - 1);
i -= 2;
}
}
@@ -4280,7 +4283,7 @@ bool String::is_valid_filename() const {
return false;
}
- if (stripped == String()) {
+ if (stripped.is_empty()) {
return false;
}
@@ -4412,7 +4415,7 @@ String String::property_name_encode() const {
// as well as '"', '=' or ' ' (32)
const char32_t *cstr = get_data();
for (int i = 0; cstr[i]; i++) {
- if (cstr[i] == '=' || cstr[i] == '"' || cstr[i] < 33 || cstr[i] > 126) {
+ if (cstr[i] == '=' || cstr[i] == '"' || cstr[i] == ';' || cstr[i] == '[' || cstr[i] == ']' || cstr[i] < 33 || cstr[i] > 126) {
return "\"" + c_escape_multiline() + "\"";
}
}
@@ -4864,15 +4867,20 @@ String TTRN(const String &p_text, const String &p_text_plural, int p_n, const St
return p_text_plural;
}
+/* DTR and DTRN are used for the documentation, handling descriptions extracted
+ * from the XML.
+ * They also replace `$DOCS_URL` with the actual URL to the documentation's branch,
+ * to allow dehardcoding it in the XML and doing proper substitutions everywhere.
+ */
String DTR(const String &p_text, const String &p_context) {
// Comes straight from the XML, so remove indentation and any trailing whitespace.
const String text = p_text.dedent().strip_edges();
if (TranslationServer::get_singleton()) {
- return TranslationServer::get_singleton()->doc_translate(text, p_context);
+ return String(TranslationServer::get_singleton()->doc_translate(text, p_context)).replace("$DOCS_URL", VERSION_DOCS_URL);
}
- return text;
+ return text.replace("$DOCS_URL", VERSION_DOCS_URL);
}
String DTRN(const String &p_text, const String &p_text_plural, int p_n, const String &p_context) {
@@ -4880,21 +4888,21 @@ String DTRN(const String &p_text, const String &p_text_plural, int p_n, const St
const String text_plural = p_text_plural.dedent().strip_edges();
if (TranslationServer::get_singleton()) {
- return TranslationServer::get_singleton()->doc_translate_plural(text, text_plural, p_n, p_context);
+ return String(TranslationServer::get_singleton()->doc_translate_plural(text, text_plural, p_n, p_context)).replace("$DOCS_URL", VERSION_DOCS_URL);
}
// Return message based on English plural rule if translation is not possible.
if (p_n == 1) {
- return text;
+ return text.replace("$DOCS_URL", VERSION_DOCS_URL);
}
- return text_plural;
+ return text_plural.replace("$DOCS_URL", VERSION_DOCS_URL);
}
#endif
String RTR(const String &p_text, const String &p_context) {
if (TranslationServer::get_singleton()) {
String rtr = TranslationServer::get_singleton()->tool_translate(p_text, p_context);
- if (rtr == String() || rtr == p_text) {
+ if (rtr.is_empty() || rtr == p_text) {
return TranslationServer::get_singleton()->translate(p_text, p_context);
} else {
return rtr;
@@ -4907,7 +4915,7 @@ String RTR(const String &p_text, const String &p_context) {
String RTRN(const String &p_text, const String &p_text_plural, int p_n, const String &p_context) {
if (TranslationServer::get_singleton()) {
String rtr = TranslationServer::get_singleton()->tool_translate_plural(p_text, p_text_plural, p_n, p_context);
- if (rtr == String() || rtr == p_text || rtr == p_text_plural) {
+ if (rtr.is_empty() || rtr == p_text || rtr == p_text_plural) {
return TranslationServer::get_singleton()->translate_plural(p_text, p_text_plural, p_n, p_context);
} else {
return rtr;
diff --git a/core/string/ustring.h b/core/string/ustring.h
index 1d80ccf58d..396c996050 100644
--- a/core/string/ustring.h
+++ b/core/string/ustring.h
@@ -108,13 +108,10 @@ public:
_FORCE_INLINE_ Char16String() {}
_FORCE_INLINE_ Char16String(const Char16String &p_str) { _cowdata._ref(p_str._cowdata); }
- _FORCE_INLINE_ Char16String &operator=(const Char16String &p_str) {
- _cowdata._ref(p_str._cowdata);
- return *this;
- }
+ _FORCE_INLINE_ void operator=(const Char16String &p_str) { _cowdata._ref(p_str._cowdata); }
_FORCE_INLINE_ Char16String(const char16_t *p_cstr) { copy_from(p_cstr); }
- Char16String &operator=(const char16_t *p_cstr);
+ void operator=(const char16_t *p_cstr);
bool operator<(const Char16String &p_right) const;
Char16String &operator+=(char16_t p_char);
int length() const { return size() ? size() - 1 : 0; }
@@ -152,13 +149,10 @@ public:
_FORCE_INLINE_ CharString() {}
_FORCE_INLINE_ CharString(const CharString &p_str) { _cowdata._ref(p_str._cowdata); }
- _FORCE_INLINE_ CharString &operator=(const CharString &p_str) {
- _cowdata._ref(p_str._cowdata);
- return *this;
- }
+ _FORCE_INLINE_ void operator=(const CharString &p_str) { _cowdata._ref(p_str._cowdata); }
_FORCE_INLINE_ CharString(const char *p_cstr) { copy_from(p_cstr); }
- CharString &operator=(const char *p_cstr);
+ void operator=(const char *p_cstr);
bool operator<(const CharString &p_right) const;
CharString &operator+=(char p_char);
int length() const { return size() ? size() - 1 : 0; }
@@ -209,7 +203,7 @@ public:
_FORCE_INLINE_ char32_t *ptrw() { return _cowdata.ptrw(); }
_FORCE_INLINE_ const char32_t *ptr() const { return _cowdata.ptr(); }
- void remove(int p_index) { _cowdata.remove(p_index); }
+ void remove_at(int p_index) { _cowdata.remove_at(p_index); }
_FORCE_INLINE_ void clear() { resize(0); }
@@ -442,11 +436,7 @@ public:
_FORCE_INLINE_ String() {}
_FORCE_INLINE_ String(const String &p_str) { _cowdata._ref(p_str._cowdata); }
-
- String &operator=(const String &p_str) {
- _cowdata._ref(p_str._cowdata);
- return *this;
- }
+ _FORCE_INLINE_ void operator=(const String &p_str) { _cowdata._ref(p_str._cowdata); }
Vector<uint8_t> to_ascii_buffer() const;
Vector<uint8_t> to_utf8_buffer() const;
diff --git a/core/templates/bin_sorted_array.h b/core/templates/bin_sorted_array.h
index be9d0b5475..8db3e7aeb8 100644
--- a/core/templates/bin_sorted_array.h
+++ b/core/templates/bin_sorted_array.h
@@ -112,7 +112,7 @@ public:
return current_idx;
}
- void remove(uint64_t p_idx) {
+ void remove_at(uint64_t p_idx) {
ERR_FAIL_COND(p_idx >= array.size());
uint64_t new_idx = move(p_idx, 0);
uint64_t swap_idx = array.size() - 1;
diff --git a/core/templates/cowdata.h b/core/templates/cowdata.h
index 9b8c0eb528..e79ca037db 100644
--- a/core/templates/cowdata.h
+++ b/core/templates/cowdata.h
@@ -167,7 +167,7 @@ public:
Error resize(int p_size);
- _FORCE_INLINE_ void remove(int p_index) {
+ _FORCE_INLINE_ void remove_at(int p_index) {
ERR_FAIL_INDEX(p_index, size());
T *p = ptrw();
int len = size();
diff --git a/core/templates/hash_map.h b/core/templates/hash_map.h
index 1634219c23..45e0cc2427 100644
--- a/core/templates/hash_map.h
+++ b/core/templates/hash_map.h
@@ -53,7 +53,7 @@
* @param RELATIONSHIP Relationship at which the hash table is resized. if amount of elements is RELATIONSHIP
* times bigger than the hash table, table is resized to solve this condition. if RELATIONSHIP is zero, table is always MIN_HASH_TABLE_POWER.
*
-*/
+ */
template <class TKey, class TData, class Hasher = HashMapHasherDefault, class Comparator = HashMapComparatorDefault<TKey>, uint8_t MIN_HASH_TABLE_POWER = 3, uint8_t RELATIONSHIP = 8>
class HashMap {
@@ -458,8 +458,8 @@ public:
*
* print( *k );
* }
- *
- */
+ *
+ */
const TKey *next(const TKey *p_key) const {
if (unlikely(!hash_table)) {
return nullptr;
diff --git a/core/templates/list.h b/core/templates/list.h
index c2e17a2f6f..afbed998c2 100644
--- a/core/templates/list.h
+++ b/core/templates/list.h
@@ -249,29 +249,29 @@ private:
public:
/**
- * return a const iterator to the beginning of the list.
- */
+ * return a const iterator to the beginning of the list.
+ */
_FORCE_INLINE_ const Element *front() const {
return _data ? _data->first : nullptr;
}
/**
- * return an iterator to the beginning of the list.
- */
+ * return an iterator to the beginning of the list.
+ */
_FORCE_INLINE_ Element *front() {
return _data ? _data->first : nullptr;
}
/**
- * return a const iterator to the last member of the list.
- */
+ * return a const iterator to the last member of the list.
+ */
_FORCE_INLINE_ const Element *back() const {
return _data ? _data->last : nullptr;
}
/**
- * return an iterator to the last member of the list.
- */
+ * return an iterator to the last member of the list.
+ */
_FORCE_INLINE_ Element *back() {
return _data ? _data->last : nullptr;
}
diff --git a/core/templates/local_vector.h b/core/templates/local_vector.h
index 5704b8f230..4ec08821f8 100644
--- a/core/templates/local_vector.h
+++ b/core/templates/local_vector.h
@@ -70,7 +70,7 @@ public:
}
}
- void remove(U p_index) {
+ void remove_at(U p_index) {
ERR_FAIL_UNSIGNED_INDEX(p_index, count);
count--;
for (U i = p_index; i < count; i++) {
@@ -83,7 +83,7 @@ public:
/// Removes the item copying the last value into the position of the one to
/// remove. It's generally faster than `remove`.
- void remove_unordered(U p_index) {
+ void remove_at_unordered(U p_index) {
ERR_FAIL_INDEX(p_index, count);
count--;
if (count > p_index) {
@@ -97,7 +97,7 @@ public:
void erase(const T &p_val) {
int64_t idx = find(p_val);
if (idx >= 0) {
- remove(idx);
+ remove_at(idx);
}
}
@@ -234,19 +234,17 @@ public:
data[i] = p_from.data[i];
}
}
- inline LocalVector &operator=(const LocalVector &p_from) {
+ inline void operator=(const LocalVector &p_from) {
resize(p_from.size());
for (U i = 0; i < p_from.count; i++) {
data[i] = p_from.data[i];
}
- return *this;
}
- inline LocalVector &operator=(const Vector<T> &p_from) {
+ inline void operator=(const Vector<T> &p_from) {
resize(p_from.size());
for (U i = 0; i < count; i++) {
data[i] = p_from[i];
}
- return *this;
}
_FORCE_INLINE_ ~LocalVector() {
diff --git a/core/templates/oa_hash_map.h b/core/templates/oa_hash_map.h
index 025cc30db4..9dab36e343 100644
--- a/core/templates/oa_hash_map.h
+++ b/core/templates/oa_hash_map.h
@@ -353,7 +353,7 @@ public:
(*this) = p_other;
}
- OAHashMap &operator=(const OAHashMap &p_other) {
+ void operator=(const OAHashMap &p_other) {
if (capacity != 0) {
clear();
}
@@ -363,7 +363,6 @@ public:
for (Iterator it = p_other.iter(); it.valid; it = p_other.next_iter(it)) {
set(*it.key, *it.value);
}
- return *this;
}
OAHashMap(uint32_t p_initial_capacity = 64) {
diff --git a/core/templates/ordered_hash_map.h b/core/templates/ordered_hash_map.h
index 7a17eeb644..928072bb18 100644
--- a/core/templates/ordered_hash_map.h
+++ b/core/templates/ordered_hash_map.h
@@ -85,11 +85,10 @@ public:
next_element(other.next_element) {
}
- Element &operator=(const Element &other) {
+ void operator=(const Element &other) {
list_element = other.list_element;
next_element = other.next_element;
prev_element = other.prev_element;
- return *this;
}
_FORCE_INLINE_ bool operator==(const Element &p_other) const {
@@ -145,9 +144,8 @@ public:
list_element(other.list_element) {
}
- ConstElement &operator=(const ConstElement &other) {
+ void operator=(const ConstElement &other) {
list_element = other.list_element;
- return *this;
}
ConstElement next() const {
@@ -207,8 +205,12 @@ public:
(*list_element)->get().second = p_value;
return Element(*list_element);
}
- typename InternalList::Element *new_element = list.push_back(Pair<const K *, V>(nullptr, p_value));
+ // Incorrectly set the first value of the pair with a value that will
+ // be invalid as soon as we leave this function...
+ typename InternalList::Element *new_element = list.push_back(Pair<const K *, V>(&p_key, p_value));
+ // ...this is needed here in case the hashmap recursively reference itself...
typename InternalMap::Element *e = map.set(p_key, new_element);
+ // ...now we can set the right value !
new_element->get().first = &e->key();
return Element(new_element);
diff --git a/core/templates/thread_work_pool.cpp b/core/templates/thread_work_pool.cpp
index 17969a2c90..710f043a4a 100644
--- a/core/templates/thread_work_pool.cpp
+++ b/core/templates/thread_work_pool.cpp
@@ -47,7 +47,7 @@ void ThreadWorkPool::_thread_function(void *p_user) {
void ThreadWorkPool::init(int p_thread_count) {
ERR_FAIL_COND(threads != nullptr);
if (p_thread_count < 0) {
- p_thread_count = OS::get_singleton()->get_processor_count();
+ p_thread_count = OS::get_singleton()->get_default_thread_pool_size();
}
thread_count = p_thread_count;
diff --git a/core/templates/thread_work_pool.h b/core/templates/thread_work_pool.h
index b242648bc8..19096c496a 100644
--- a/core/templates/thread_work_pool.h
+++ b/core/templates/thread_work_pool.h
@@ -73,6 +73,7 @@ class ThreadWorkPool {
ThreadData *threads = nullptr;
uint32_t thread_count = 0;
+ uint32_t threads_working = 0;
BaseWork *current_work = nullptr;
static void _thread_function(void *p_user);
@@ -94,7 +95,9 @@ public:
current_work = w;
- for (uint32_t i = 0; i < thread_count; i++) {
+ threads_working = MIN(p_elements, thread_count);
+
+ for (uint32_t i = 0; i < threads_working; i++) {
threads[i].work = w;
threads[i].start.post();
}
@@ -117,19 +120,32 @@ public:
void end_work() {
ERR_FAIL_COND(current_work == nullptr);
- for (uint32_t i = 0; i < thread_count; i++) {
+ for (uint32_t i = 0; i < threads_working; i++) {
threads[i].completed.wait();
threads[i].work = nullptr;
}
+ threads_working = 0;
memdelete(current_work);
current_work = nullptr;
}
template <class C, class M, class U>
void do_work(uint32_t p_elements, C *p_instance, M p_method, U p_userdata) {
- begin_work(p_elements, p_instance, p_method, p_userdata);
- end_work();
+ switch (p_elements) {
+ case 0:
+ // Nothing to do, so do nothing.
+ break;
+ case 1:
+ // No value in pushing the work to another thread if it's a single job
+ // and we're going to wait for it to finish. Just run it right here.
+ (p_instance->*p_method)(0, p_userdata);
+ break;
+ default:
+ // Multiple jobs to do; commence threaded business.
+ begin_work(p_elements, p_instance, p_method, p_userdata);
+ end_work();
+ }
}
_FORCE_INLINE_ int get_thread_count() const { return thread_count; }
diff --git a/core/templates/vector.h b/core/templates/vector.h
index 4b008a45a4..2f51a83848 100644
--- a/core/templates/vector.h
+++ b/core/templates/vector.h
@@ -35,7 +35,7 @@
* @class Vector
* @author Juan Linietsky
* Vector container. Regular Vector Container. Use with care and for smaller arrays when possible. Use Vector for large arrays.
-*/
+ */
#include "core/error/error_macros.h"
#include "core/os/memory.h"
@@ -68,11 +68,11 @@ public:
_FORCE_INLINE_ bool append(const T &p_elem) { return push_back(p_elem); } //alias
void fill(T p_elem);
- void remove(int p_index) { _cowdata.remove(p_index); }
+ void remove_at(int p_index) { _cowdata.remove_at(p_index); }
void erase(const T &p_val) {
int idx = find(p_val);
if (idx >= 0) {
- remove(idx);
+ remove_at(idx);
}
}
void reverse();
@@ -132,9 +132,8 @@ public:
insert(i, p_val);
}
- inline Vector &operator=(const Vector &p_from) {
+ inline void operator=(const Vector &p_from) {
_cowdata._ref(p_from._cowdata);
- return *this;
}
Vector<uint8_t> to_byte_array() const {
@@ -144,27 +143,28 @@ public:
return ret;
}
- Vector<T> subarray(int p_from, int p_to) const {
- if (p_from < 0) {
- p_from = size() + p_from;
- }
- if (p_to < 0) {
- p_to = size() + p_to;
+ Vector<T> slice(int p_begin, int p_end) const {
+ Vector<T> result;
+
+ if (p_end < 0) {
+ p_end += size() + 1;
}
- ERR_FAIL_INDEX_V(p_from, size(), Vector<T>());
- ERR_FAIL_INDEX_V(p_to, size(), Vector<T>());
+ ERR_FAIL_INDEX_V(p_begin, size(), result);
+ ERR_FAIL_INDEX_V(p_end, size() + 1, result);
+
+ ERR_FAIL_COND_V(p_begin > p_end, result);
+
+ int result_size = p_end - p_begin;
+ result.resize(result_size);
- Vector<T> slice;
- int span = 1 + p_to - p_from;
- slice.resize(span);
- const T *r = ptr();
- T *w = slice.ptrw();
- for (int i = 0; i < span; ++i) {
- w[i] = r[p_from + i];
+ const T *const r = ptr();
+ T *const w = result.ptrw();
+ for (int i = 0; i < result_size; ++i) {
+ w[i] = r[p_begin + i];
}
- return slice;
+ return result;
}
bool operator==(const Vector<T> &p_arr) const {
diff --git a/core/templates/vmap.h b/core/templates/vmap.h
index 520e0b3720..0ff105ccbf 100644
--- a/core/templates/vmap.h
+++ b/core/templates/vmap.h
@@ -134,7 +134,7 @@ public:
if (pos < 0) {
return;
}
- _cowdata.remove(pos);
+ _cowdata.remove_at(pos);
}
int find(const T &p_val) const {
@@ -193,9 +193,8 @@ public:
_FORCE_INLINE_ VMap() {}
_FORCE_INLINE_ VMap(const VMap &p_from) { _cowdata._ref(p_from._cowdata); }
- inline VMap &operator=(const VMap &p_from) {
+ inline void operator=(const VMap &p_from) {
_cowdata._ref(p_from._cowdata);
- return *this;
}
};
diff --git a/core/templates/vset.h b/core/templates/vset.h
index 6665651d42..94e7a17061 100644
--- a/core/templates/vset.h
+++ b/core/templates/vset.h
@@ -119,7 +119,7 @@ public:
if (pos < 0) {
return;
}
- _data.remove(pos);
+ _data.remove_at(pos);
}
int find(const T &p_val) const {
diff --git a/core/typedefs.h b/core/typedefs.h
index 8ca3d13e63..95bd423817 100644
--- a/core/typedefs.h
+++ b/core/typedefs.h
@@ -91,8 +91,8 @@
#define ABS(m_v) (((m_v) < 0) ? (-(m_v)) : (m_v))
#endif
-#ifndef SGN
-#define SGN(m_v) (((m_v) == 0) ? (0.0) : (((m_v) < 0) ? (-1.0) : (+1.0)))
+#ifndef SIGN
+#define SIGN(m_v) (((m_v) == 0) ? (0.0) : (((m_v) < 0) ? (-1.0) : (+1.0)))
#endif
#ifndef MIN
@@ -277,6 +277,9 @@ struct BuildIndexSequence : BuildIndexSequence<N - 1, N - 1, Is...> {};
template <size_t... Is>
struct BuildIndexSequence<0, Is...> : IndexSequence<Is...> {};
+// Limit the depth of recursive algorithms when dealing with Array/Dictionary
+#define MAX_RECURSION 100
+
#ifdef DEBUG_ENABLED
#define DEBUG_METHODS_ENABLED
#endif
diff --git a/core/variant/array.cpp b/core/variant/array.cpp
index b4d6dffc6f..45f2e0c5ac 100644
--- a/core/variant/array.cpp
+++ b/core/variant/array.cpp
@@ -97,11 +97,38 @@ void Array::clear() {
}
bool Array::operator==(const Array &p_array) const {
- return _p == p_array._p;
+ return recursive_equal(p_array, 0);
}
bool Array::operator!=(const Array &p_array) const {
- return !operator==(p_array);
+ return !recursive_equal(p_array, 0);
+}
+
+bool Array::recursive_equal(const Array &p_array, int recursion_count) const {
+ // Cheap checks
+ if (_p == p_array._p) {
+ return true;
+ }
+ const Vector<Variant> &a1 = _p->array;
+ const Vector<Variant> &a2 = p_array._p->array;
+ const int size = a1.size();
+ if (size != a2.size()) {
+ return false;
+ }
+
+ // Heavy O(n) check
+ if (recursion_count > MAX_RECURSION) {
+ ERR_PRINT("Max recursion reached");
+ return true;
+ }
+ recursion_count++;
+ for (int i = 0; i < size; i++) {
+ if (!a1[i].hash_compare(a2[i], recursion_count)) {
+ return false;
+ }
+ }
+
+ return true;
}
bool Array::operator<(const Array &p_array) const {
@@ -132,10 +159,20 @@ bool Array::operator>=(const Array &p_array) const {
}
uint32_t Array::hash() const {
- uint32_t h = hash_djb2_one_32(0);
+ return recursive_hash(0);
+}
+
+uint32_t Array::recursive_hash(int recursion_count) const {
+ if (recursion_count > MAX_RECURSION) {
+ ERR_PRINT("Max recursion reached");
+ return 0;
+ }
+ uint32_t h = hash_djb2_one_32(Variant::ARRAY);
+
+ recursion_count++;
for (int i = 0; i < _p->array.size(); i++) {
- h = hash_djb2_one_32(_p->array[i].hash(), h);
+ h = hash_djb2_one_32(_p->array[i].recursive_hash(recursion_count), h);
}
return h;
}
@@ -285,8 +322,8 @@ bool Array::has(const Variant &p_value) const {
return _p->array.find(p_value, 0) != -1;
}
-void Array::remove(int p_pos) {
- _p->array.remove(p_pos);
+void Array::remove_at(int p_pos) {
+ _p->array.remove_at(p_pos);
}
void Array::set(int p_idx, const Variant &p_value) {
@@ -300,66 +337,58 @@ const Variant &Array::get(int p_idx) const {
}
Array Array::duplicate(bool p_deep) const {
+ return recursive_duplicate(p_deep, 0);
+}
+
+Array Array::recursive_duplicate(bool p_deep, int recursion_count) const {
Array new_arr;
+
+ if (recursion_count > MAX_RECURSION) {
+ ERR_PRINT("Max recursion reached");
+ return new_arr;
+ }
+
int element_count = size();
new_arr.resize(element_count);
new_arr._p->typed = _p->typed;
- for (int i = 0; i < element_count; i++) {
- new_arr[i] = p_deep ? get(i).duplicate(p_deep) : get(i);
+ if (p_deep) {
+ recursion_count++;
+ for (int i = 0; i < element_count; i++) {
+ new_arr[i] = get(i).recursive_duplicate(true, recursion_count);
+ }
+ } else {
+ for (int i = 0; i < element_count; i++) {
+ new_arr[i] = get(i);
+ }
}
return new_arr;
}
-int Array::_clamp_slice_index(int p_index) const {
- int arr_size = size();
- int fixed_index = CLAMP(p_index, -arr_size, arr_size - 1);
- if (fixed_index < 0) {
- fixed_index = arr_size + fixed_index;
- }
- return fixed_index;
-}
+Array Array::slice(int p_begin, int p_end, int p_step, bool p_deep) const {
+ Array result;
-Array Array::slice(int p_begin, int p_end, int p_step, bool p_deep) const { // like python, but inclusive on upper bound
-
- Array new_arr;
+ ERR_FAIL_COND_V_MSG(p_step == 0, result, "Slice step cannot be zero.");
- ERR_FAIL_COND_V_MSG(p_step == 0, new_arr, "Array slice step size cannot be zero.");
-
- if (is_empty()) { // Don't try to slice empty arrays.
- return new_arr;
- }
- if (p_step > 0) {
- if (p_begin >= size() || p_end < -size()) {
- return new_arr;
- }
- } else { // p_step < 0
- if (p_begin < -size() || p_end >= size()) {
- return new_arr;
- }
+ if (p_end < 0) {
+ p_end += size() + 1;
}
- int begin = _clamp_slice_index(p_begin);
- int end = _clamp_slice_index(p_end);
+ ERR_FAIL_INDEX_V(p_begin, size(), result);
+ ERR_FAIL_INDEX_V(p_end, size() + 1, result);
- int new_arr_size = MAX(((end - begin + p_step) / p_step), 0);
- new_arr.resize(new_arr_size);
+ ERR_FAIL_COND_V_MSG(p_step > 0 && p_begin > p_end, result, "Slice is positive, but bounds is decreasing");
+ ERR_FAIL_COND_V_MSG(p_step < 0 && p_begin < p_end, result, "Slice is negative, but bounds is increasing");
- if (p_step > 0) {
- int dest_idx = 0;
- for (int idx = begin; idx <= end; idx += p_step) {
- ERR_FAIL_COND_V_MSG(dest_idx < 0 || dest_idx >= new_arr_size, Array(), "Bug in Array slice()");
- new_arr[dest_idx++] = p_deep ? get(idx).duplicate(p_deep) : get(idx);
- }
- } else { // p_step < 0
- int dest_idx = 0;
- for (int idx = begin; idx >= end; idx += p_step) {
- ERR_FAIL_COND_V_MSG(dest_idx < 0 || dest_idx >= new_arr_size, Array(), "Bug in Array slice()");
- new_arr[dest_idx++] = p_deep ? get(idx).duplicate(p_deep) : get(idx);
- }
+ int result_size = (p_end - p_begin) / p_step;
+ result.resize(result_size);
+
+ for (int src_idx = p_begin, dest_idx = 0; dest_idx < result_size; ++dest_idx) {
+ result[dest_idx] = p_deep ? get(src_idx).duplicate(true) : get(src_idx);
+ src_idx += p_step;
}
- return new_arr;
+ return result;
}
Array Array::filter(const Callable &p_callable) const {
@@ -522,7 +551,7 @@ Variant Array::pop_back() {
Variant Array::pop_front() {
if (!_p->array.is_empty()) {
const Variant ret = _p->array.get(0);
- _p->array.remove(0);
+ _p->array.remove_at(0);
return ret;
}
return Variant();
@@ -549,7 +578,7 @@ Variant Array::pop_at(int p_pos) {
_p->array.size()));
const Variant ret = _p->array.get(p_pos);
- _p->array.remove(p_pos);
+ _p->array.remove_at(p_pos);
return ret;
}
diff --git a/core/variant/array.h b/core/variant/array.h
index 4a1b25c4a9..6a68a9b9ff 100644
--- a/core/variant/array.h
+++ b/core/variant/array.h
@@ -44,8 +44,6 @@ class Array {
void _ref(const Array &p_from) const;
void _unref() const;
- inline int _clamp_slice_index(int p_index) const;
-
protected:
Array(const Array &p_base, uint32_t p_type, const StringName &p_class_name, const Variant &p_script);
bool _assign(const Array &p_array);
@@ -63,8 +61,10 @@ public:
bool operator==(const Array &p_array) const;
bool operator!=(const Array &p_array) const;
+ bool recursive_equal(const Array &p_array, int recursion_count) const;
uint32_t hash() const;
+ uint32_t recursive_hash(int recursion_count) const;
void operator=(const Array &p_array);
void push_back(const Variant &p_value);
@@ -73,7 +73,7 @@ public:
Error resize(int p_new_size);
Error insert(int p_pos, const Variant &p_value);
- void remove(int p_pos);
+ void remove_at(int p_pos);
void fill(const Variant &p_value);
Variant front() const;
@@ -100,6 +100,7 @@ public:
Variant pop_at(int p_pos);
Array duplicate(bool p_deep = false) const;
+ Array recursive_duplicate(bool p_deep, int recursion_count) const;
Array slice(int p_begin, int p_end, int p_step = 1, bool p_deep = false) const;
Array filter(const Callable &p_callable) const;
diff --git a/core/variant/binder_common.h b/core/variant/binder_common.h
index 8592a1dc62..3fb4af4944 100644
--- a/core/variant/binder_common.h
+++ b/core/variant/binder_common.h
@@ -80,14 +80,18 @@ struct VariantCaster<const T &> {
} \
typedef int64_t EncodeT; \
_FORCE_INLINE_ static void encode(m_enum p_val, const void *p_ptr) { \
- *(int64_t *)p_ptr = p_val; \
+ *(int64_t *)p_ptr = (int64_t)p_val; \
} \
};
// Object enum casts must go here
VARIANT_ENUM_CAST(Object::ConnectFlags);
+VARIANT_ENUM_CAST(Vector2::Axis);
+VARIANT_ENUM_CAST(Vector2i::Axis);
VARIANT_ENUM_CAST(Vector3::Axis);
+VARIANT_ENUM_CAST(Vector3i::Axis);
+VARIANT_ENUM_CAST(Basis::EulerOrder);
VARIANT_ENUM_CAST(Error);
VARIANT_ENUM_CAST(Side);
@@ -102,9 +106,9 @@ VARIANT_ENUM_CAST(KeyModifierMask);
VARIANT_ENUM_CAST(MIDIMessage);
VARIANT_ENUM_CAST(MouseButton);
VARIANT_ENUM_CAST(Orientation);
-VARIANT_ENUM_CAST(HAlign);
-VARIANT_ENUM_CAST(VAlign);
-VARIANT_ENUM_CAST(InlineAlign);
+VARIANT_ENUM_CAST(HorizontalAlignment);
+VARIANT_ENUM_CAST(VerticalAlignment);
+VARIANT_ENUM_CAST(InlineAlignment);
VARIANT_ENUM_CAST(PropertyHint);
VARIANT_ENUM_CAST(PropertyUsageFlags);
VARIANT_ENUM_CAST(Variant::Type);
diff --git a/core/variant/dictionary.cpp b/core/variant/dictionary.cpp
index 07b3a9a675..24d21386a7 100644
--- a/core/variant/dictionary.cpp
+++ b/core/variant/dictionary.cpp
@@ -188,11 +188,35 @@ bool Dictionary::erase(const Variant &p_key) {
}
bool Dictionary::operator==(const Dictionary &p_dictionary) const {
- return _p == p_dictionary._p;
+ return recursive_equal(p_dictionary, 0);
}
bool Dictionary::operator!=(const Dictionary &p_dictionary) const {
- return _p != p_dictionary._p;
+ return !recursive_equal(p_dictionary, 0);
+}
+
+bool Dictionary::recursive_equal(const Dictionary &p_dictionary, int recursion_count) const {
+ // Cheap checks
+ if (_p == p_dictionary._p) {
+ return true;
+ }
+ if (_p->variant_map.size() != p_dictionary._p->variant_map.size()) {
+ return false;
+ }
+
+ // Heavy O(n) check
+ if (recursion_count > MAX_RECURSION) {
+ ERR_PRINT("Max recursion reached");
+ return true;
+ }
+ recursion_count++;
+ for (OrderedHashMap<Variant, Variant, VariantHasher, VariantComparator>::ConstElement this_E = ((const OrderedHashMap<Variant, Variant, VariantHasher, VariantComparator> *)&_p->variant_map)->front(); this_E; this_E = this_E.next()) {
+ OrderedHashMap<Variant, Variant, VariantHasher, VariantComparator>::ConstElement other_E = ((const OrderedHashMap<Variant, Variant, VariantHasher, VariantComparator> *)&p_dictionary._p->variant_map)->find(this_E.key());
+ if (!other_E || !this_E.value().hash_compare(other_E.value(), recursion_count)) {
+ return false;
+ }
+ }
+ return true;
}
void Dictionary::_ref(const Dictionary &p_from) const {
@@ -225,11 +249,21 @@ void Dictionary::_unref() const {
}
uint32_t Dictionary::hash() const {
+ return recursive_hash(0);
+}
+
+uint32_t Dictionary::recursive_hash(int recursion_count) const {
+ if (recursion_count > MAX_RECURSION) {
+ ERR_PRINT("Max recursion reached");
+ return 0;
+ }
+
uint32_t h = hash_djb2_one_32(Variant::DICTIONARY);
+ recursion_count++;
for (OrderedHashMap<Variant, Variant, VariantHasher, VariantComparator>::Element E = _p->variant_map.front(); E; E = E.next()) {
- h = hash_djb2_one_32(E.key().hash(), h);
- h = hash_djb2_one_32(E.value().hash(), h);
+ h = hash_djb2_one_32(E.key().recursive_hash(recursion_count), h);
+ h = hash_djb2_one_32(E.value().recursive_hash(recursion_count), h);
}
return h;
@@ -286,10 +320,26 @@ const Variant *Dictionary::next(const Variant *p_key) const {
}
Dictionary Dictionary::duplicate(bool p_deep) const {
+ return recursive_duplicate(p_deep, 0);
+}
+
+Dictionary Dictionary::recursive_duplicate(bool p_deep, int recursion_count) const {
Dictionary n;
- for (OrderedHashMap<Variant, Variant, VariantHasher, VariantComparator>::Element E = _p->variant_map.front(); E; E = E.next()) {
- n[E.key()] = p_deep ? E.value().duplicate(true) : E.value();
+ if (recursion_count > MAX_RECURSION) {
+ ERR_PRINT("Max recursion reached");
+ return n;
+ }
+
+ if (p_deep) {
+ recursion_count++;
+ for (OrderedHashMap<Variant, Variant, VariantHasher, VariantComparator>::Element E = _p->variant_map.front(); E; E = E.next()) {
+ n[E.key().recursive_duplicate(true, recursion_count)] = E.value().recursive_duplicate(true, recursion_count);
+ }
+ } else {
+ for (OrderedHashMap<Variant, Variant, VariantHasher, VariantComparator>::Element E = _p->variant_map.front(); E; E = E.next()) {
+ n[E.key()] = E.value();
+ }
}
return n;
diff --git a/core/variant/dictionary.h b/core/variant/dictionary.h
index 4067ff9fd9..f8a2a7573f 100644
--- a/core/variant/dictionary.h
+++ b/core/variant/dictionary.h
@@ -70,8 +70,10 @@ public:
bool operator==(const Dictionary &p_dictionary) const;
bool operator!=(const Dictionary &p_dictionary) const;
+ bool recursive_equal(const Dictionary &p_dictionary, int recursion_count) const;
uint32_t hash() const;
+ uint32_t recursive_hash(int recursion_count) const;
void operator=(const Dictionary &p_dictionary);
const Variant *next(const Variant *p_key = nullptr) const;
@@ -80,6 +82,7 @@ public:
Array values() const;
Dictionary duplicate(bool p_deep = false) const;
+ Dictionary recursive_duplicate(bool p_deep, int recursion_count) const;
const void *id() const;
diff --git a/core/variant/type_info.h b/core/variant/type_info.h
index b70d29bbac..2c6b82d25f 100644
--- a/core/variant/type_info.h
+++ b/core/variant/type_info.h
@@ -60,7 +60,7 @@ struct TypeInherits {
static char (&test(...))[2];
static bool const value = sizeof(test(get_d())) == sizeof(char) &&
- !TypesAreSame<B volatile const, void volatile const>::value;
+ !TypesAreSame<B volatile const, void volatile const>::value;
};
namespace GodotTypeInfo {
diff --git a/core/variant/variant.cpp b/core/variant/variant.cpp
index 3214fc125d..c43ff8626e 100644
--- a/core/variant/variant.cpp
+++ b/core/variant/variant.cpp
@@ -313,7 +313,6 @@ bool Variant::can_convert(Variant::Type p_type_from, Variant::Type p_type_to) {
case BASIS: {
static const Type valid[] = {
QUATERNION,
- VECTOR3,
NIL
};
@@ -620,7 +619,6 @@ bool Variant::can_convert_strict(Variant::Type p_type_from, Variant::Type p_type
case BASIS: {
static const Type valid[] = {
QUATERNION,
- VECTOR3,
NIL
};
@@ -786,16 +784,11 @@ bool Variant::can_convert_strict(Variant::Type p_type_from, Variant::Type p_type
}
bool Variant::operator==(const Variant &p_variant) const {
- if (type != p_variant.type) { //evaluation of operator== needs to be more strict
- return false;
- }
- bool v;
- Variant r;
- evaluate(OP_EQUAL, *this, p_variant, r, v);
- return r;
+ return hash_compare(p_variant);
}
bool Variant::operator!=(const Variant &p_variant) const {
+ // Don't use `!hash_compare(p_variant)` given it makes use of OP_EQUAL
if (type != p_variant.type) { //evaluation of operator== needs to be more strict
return true;
}
@@ -1619,25 +1612,23 @@ struct _VariantStrPair {
};
Variant::operator String() const {
- List<const void *> stack;
-
- return stringify(stack);
+ return stringify(0);
}
template <class T>
-String stringify_vector(const T &vec, List<const void *> &stack) {
+String stringify_vector(const T &vec, int recursion_count) {
String str("[");
for (int i = 0; i < vec.size(); i++) {
if (i > 0) {
str += ", ";
}
- str = str + Variant(vec[i]).stringify(stack);
+ str = str + Variant(vec[i]).stringify(recursion_count);
}
str += "]";
return str;
}
-String Variant::stringify(List<const void *> &stack) const {
+String Variant::stringify(int recursion_count) const {
switch (type) {
case NIL:
return "null";
@@ -1681,23 +1672,22 @@ String Variant::stringify(List<const void *> &stack) const {
return operator Color();
case DICTIONARY: {
const Dictionary &d = *reinterpret_cast<const Dictionary *>(_data._mem);
- if (stack.find(d.id())) {
+ if (recursion_count > MAX_RECURSION) {
+ ERR_PRINT("Max recursion reached");
return "{...}";
}
- stack.push_back(d.id());
-
- //const String *K=nullptr;
String str("{");
List<Variant> keys;
d.get_key_list(&keys);
Vector<_VariantStrPair> pairs;
- for (const Variant &E : keys) {
+ recursion_count++;
+ for (List<Variant>::Element *E = keys.front(); E; E = E->next()) {
_VariantStrPair sp;
- sp.key = E.stringify(stack);
- sp.value = d[E].stringify(stack);
+ sp.key = E->get().stringify(recursion_count);
+ sp.value = d[E->get()].stringify(recursion_count);
pairs.push_back(sp);
}
@@ -1712,46 +1702,43 @@ String Variant::stringify(List<const void *> &stack) const {
}
str += "}";
- stack.erase(d.id());
return str;
} break;
case PACKED_VECTOR2_ARRAY: {
- return stringify_vector(operator Vector<Vector2>(), stack);
+ return stringify_vector(operator Vector<Vector2>(), recursion_count);
} break;
case PACKED_VECTOR3_ARRAY: {
- return stringify_vector(operator Vector<Vector3>(), stack);
+ return stringify_vector(operator Vector<Vector3>(), recursion_count);
} break;
case PACKED_COLOR_ARRAY: {
- return stringify_vector(operator Vector<Color>(), stack);
+ return stringify_vector(operator Vector<Color>(), recursion_count);
} break;
case PACKED_STRING_ARRAY: {
- return stringify_vector(operator Vector<String>(), stack);
+ return stringify_vector(operator Vector<String>(), recursion_count);
} break;
case PACKED_BYTE_ARRAY: {
- return stringify_vector(operator Vector<uint8_t>(), stack);
+ return stringify_vector(operator Vector<uint8_t>(), recursion_count);
} break;
case PACKED_INT32_ARRAY: {
- return stringify_vector(operator Vector<int32_t>(), stack);
+ return stringify_vector(operator Vector<int32_t>(), recursion_count);
} break;
case PACKED_INT64_ARRAY: {
- return stringify_vector(operator Vector<int64_t>(), stack);
+ return stringify_vector(operator Vector<int64_t>(), recursion_count);
} break;
case PACKED_FLOAT32_ARRAY: {
- return stringify_vector(operator Vector<float>(), stack);
+ return stringify_vector(operator Vector<float>(), recursion_count);
} break;
case PACKED_FLOAT64_ARRAY: {
- return stringify_vector(operator Vector<double>(), stack);
+ return stringify_vector(operator Vector<double>(), recursion_count);
} break;
case ARRAY: {
Array arr = operator Array();
- if (stack.find(arr.id())) {
+ if (recursion_count > MAX_RECURSION) {
+ ERR_PRINT("Max recursion reached");
return "[...]";
}
- stack.push_back(arr.id());
-
- String str = stringify_vector(arr, stack);
- stack.erase(arr.id());
+ String str = stringify_vector(arr, recursion_count);
return str;
} break;
@@ -1889,8 +1876,6 @@ Variant::operator Basis() const {
return *_data._basis;
} else if (type == QUATERNION) {
return *reinterpret_cast<const Quaternion *>(_data._mem);
- } else if (type == VECTOR3) {
- return Basis(*reinterpret_cast<const Vector3 *>(_data._mem));
} else if (type == TRANSFORM3D) { // unexposed in Variant::can_convert?
return _data._transform3d->basis;
} else {
@@ -2772,6 +2757,10 @@ Variant::Variant(const Variant &p_variant) {
}
uint32_t Variant::hash() const {
+ return recursive_hash(0);
+}
+
+uint32_t Variant::recursive_hash(int recursion_count) const {
switch (type) {
case NIL: {
return 0;
@@ -2899,7 +2888,7 @@ uint32_t Variant::hash() const {
return reinterpret_cast<const NodePath *>(_data._mem)->hash();
} break;
case DICTIONARY: {
- return reinterpret_cast<const Dictionary *>(_data._mem)->hash();
+ return reinterpret_cast<const Dictionary *>(_data._mem)->recursive_hash(recursion_count);
} break;
case CALLABLE: {
@@ -2913,7 +2902,7 @@ uint32_t Variant::hash() const {
} break;
case ARRAY: {
const Array &arr = *reinterpret_cast<const Array *>(_data._mem);
- return arr.hash();
+ return arr.recursive_hash(recursion_count);
} break;
case PACKED_BYTE_ARRAY: {
@@ -3087,7 +3076,7 @@ uint32_t Variant::hash() const {
\
return true
-bool Variant::hash_compare(const Variant &p_variant) const {
+bool Variant::hash_compare(const Variant &p_variant, int recursion_count) const {
if (type != p_variant.type) {
return false;
}
@@ -3122,7 +3111,7 @@ bool Variant::hash_compare(const Variant &p_variant) const {
const Rect2 *r = reinterpret_cast<const Rect2 *>(p_variant._data._mem);
return (hash_compare_vector2(l->position, r->position)) &&
- (hash_compare_vector2(l->size, r->size));
+ (hash_compare_vector2(l->size, r->size));
} break;
case RECT2I: {
const Rect2i *l = reinterpret_cast<const Rect2i *>(_data._mem);
@@ -3162,7 +3151,7 @@ bool Variant::hash_compare(const Variant &p_variant) const {
const Plane *r = reinterpret_cast<const Plane *>(p_variant._data._mem);
return (hash_compare_vector3(l->normal, r->normal)) &&
- (hash_compare_scalar(l->d, r->d));
+ (hash_compare_scalar(l->d, r->d));
} break;
case AABB: {
@@ -3218,14 +3207,19 @@ bool Variant::hash_compare(const Variant &p_variant) const {
const Array &l = *(reinterpret_cast<const Array *>(_data._mem));
const Array &r = *(reinterpret_cast<const Array *>(p_variant._data._mem));
- if (l.size() != r.size()) {
+ if (!l.recursive_equal(r, recursion_count + 1)) {
return false;
}
- for (int i = 0; i < l.size(); ++i) {
- if (!l[i].hash_compare(r[i])) {
- return false;
- }
+ return true;
+ } break;
+
+ case DICTIONARY: {
+ const Dictionary &l = *(reinterpret_cast<const Dictionary *>(_data._mem));
+ const Dictionary &r = *(reinterpret_cast<const Dictionary *>(p_variant._data._mem));
+
+ if (!l.recursive_equal(r, recursion_count + 1)) {
+ return false;
}
return true;
diff --git a/core/variant/variant.h b/core/variant/variant.h
index d3f694e7ca..230ed33c0c 100644
--- a/core/variant/variant.h
+++ b/core/variant/variant.h
@@ -31,6 +31,7 @@
#ifndef VARIANT_H
#define VARIANT_H
+#include "core/input/input_enums.h"
#include "core/io/ip_address.h"
#include "core/math/aabb.h"
#include "core/math/basis.h"
@@ -43,6 +44,7 @@
#include "core/math/vector3.h"
#include "core/math/vector3i.h"
#include "core/object/object_id.h"
+#include "core/os/keyboard.h"
#include "core/string/node_path.h"
#include "core/string/ustring.h"
#include "core/templates/rid.h"
@@ -430,6 +432,21 @@ public:
Variant(const IPAddress &p_address);
+#define VARIANT_ENUM_CLASS_CONSTRUCTOR(m_enum) \
+ Variant(const m_enum &p_value) { \
+ type = INT; \
+ _data._int = (int64_t)p_value; \
+ }
+
+ // Only enum classes that need to be bound need this to be defined.
+ VARIANT_ENUM_CLASS_CONSTRUCTOR(JoyAxis)
+ VARIANT_ENUM_CLASS_CONSTRUCTOR(JoyButton)
+ VARIANT_ENUM_CLASS_CONSTRUCTOR(Key)
+ VARIANT_ENUM_CLASS_CONSTRUCTOR(MIDIMessage)
+ VARIANT_ENUM_CLASS_CONSTRUCTOR(MouseButton)
+
+#undef VARIANT_ENUM_CLASS_CONSTRUCTOR
+
// If this changes the table in variant_op must be updated
enum Operator {
//comparison
@@ -481,7 +498,8 @@ public:
static PTROperatorEvaluator get_ptr_operator_evaluator(Operator p_operator, Type p_type_a, Type p_type_b);
void zero();
- Variant duplicate(bool deep = false) const;
+ Variant duplicate(bool p_deep = false) const;
+ Variant recursive_duplicate(bool p_deep, int recursion_count) const;
static void blend(const Variant &a, const Variant &b, float c, Variant &r_dst);
static void interpolate(const Variant &a, const Variant &b, float c, Variant &r_dst);
@@ -659,10 +677,11 @@ public:
bool operator!=(const Variant &p_variant) const;
bool operator<(const Variant &p_variant) const;
uint32_t hash() const;
+ uint32_t recursive_hash(int recursion_count) const;
- bool hash_compare(const Variant &p_variant) const;
+ bool hash_compare(const Variant &p_variant, int recursion_count = 0) const;
bool booleanize() const;
- String stringify(List<const void *> &stack) const;
+ String stringify(int recursion_count = 0) const;
String to_json_string() const;
void static_assign(const Variant &p_variant);
diff --git a/core/variant/variant_call.cpp b/core/variant/variant_call.cpp
index 6284caae2d..82f547e78c 100644
--- a/core/variant/variant_call.cpp
+++ b/core/variant/variant_call.cpp
@@ -752,8 +752,9 @@ struct _VariantCall {
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;
+ ERR_FAIL_COND_V_MSG(size < sizeof(int32_t), dest, "Size didn't match array of size int32_t, maybe you are trying to convert to the wrong type?");
+ const uint8_t *r = p_instance->ptr();
dest.resize(size / sizeof(int32_t));
memcpy(dest.ptrw(), r, size);
return dest;
@@ -761,8 +762,9 @@ struct _VariantCall {
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;
+ ERR_FAIL_COND_V_MSG(size < sizeof(int64_t), dest, "Size didn't match array of size int64_t, maybe you are trying to convert to the wrong type?");
+ const uint8_t *r = p_instance->ptr();
dest.resize(size / sizeof(int64_t));
memcpy(dest.ptrw(), r, size);
return dest;
@@ -770,8 +772,9 @@ struct _VariantCall {
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;
+ ERR_FAIL_COND_V_MSG(size < sizeof(float), dest, "Size didn't match array of size float, maybe you are trying to convert to the wrong type?");
+ const uint8_t *r = p_instance->ptr();
dest.resize(size / sizeof(float));
memcpy(dest.ptrw(), r, size);
return dest;
@@ -779,8 +782,9 @@ struct _VariantCall {
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;
+ ERR_FAIL_COND_V_MSG(size < sizeof(double), dest, "Size didn't match array of size double, maybe you are trying to convert to the wrong type?");
+ const uint8_t *r = p_instance->ptr();
dest.resize(size / sizeof(double));
memcpy(dest.ptrw(), r, size);
return dest;
@@ -1366,6 +1370,7 @@ static void _register_variant_builtin_methods() {
bind_method(String, naturalnocasecmp_to, sarray("to"), varray());
bind_method(String, length, sarray(), varray());
bind_method(String, substr, sarray("from", "len"), varray(-1));
+ bind_method(String, get_slice, sarray("delimiter", "slice"), varray());
bind_methodv(String, find, static_cast<int (String::*)(const String &, int) const>(&String::find), sarray("what", "from"), varray(0));
bind_method(String, count, sarray("what", "from", "to"), varray(0, 0));
bind_method(String, countn, sarray("what", "from", "to"), varray(0, 0));
@@ -1407,8 +1412,6 @@ static void _register_variant_builtin_methods() {
bind_method(String, plus_file, sarray("file"), varray());
bind_method(String, unicode_at, sarray("at"), varray());
bind_method(String, dedent, sarray(), varray());
- // FIXME: String needs to be immutable when binding
- //bind_method(String, erase, sarray("position", "chars"), varray());
bind_method(String, hash, sarray(), varray());
bind_method(String, md5_text, sarray(), varray());
bind_method(String, sha1_text, sarray(), varray());
@@ -1417,8 +1420,6 @@ static void _register_variant_builtin_methods() {
bind_method(String, sha1_buffer, sarray(), varray());
bind_method(String, sha256_buffer, sarray(), varray());
bind_method(String, is_empty, sarray(), varray());
- // FIXME: Static function, not sure how to bind
- //bind_method(String, humanize_size, sarray("size"), varray());
bind_method(String, is_absolute_path, sarray(), varray());
bind_method(String, is_relative_path, sarray(), varray());
@@ -1470,7 +1471,7 @@ static void _register_variant_builtin_methods() {
bind_method(Vector2, angle, sarray(), varray());
bind_method(Vector2, angle_to, sarray("to"), varray());
bind_method(Vector2, angle_to_point, sarray("to"), varray());
- bind_method(Vector2, direction_to, sarray("b"), varray());
+ bind_method(Vector2, direction_to, sarray("to"), varray());
bind_method(Vector2, distance_to, sarray("to"), varray());
bind_method(Vector2, distance_squared_to, sarray("to"), varray());
bind_method(Vector2, length, sarray(), varray());
@@ -1485,6 +1486,8 @@ static void _register_variant_builtin_methods() {
bind_method(Vector2, lerp, sarray("to", "weight"), varray());
bind_method(Vector2, slerp, sarray("to", "weight"), varray());
bind_method(Vector2, cubic_interpolate, sarray("b", "pre_a", "post_b", "weight"), varray());
+ bind_method(Vector2, max_axis_index, sarray(), varray());
+ bind_method(Vector2, min_axis_index, sarray(), varray());
bind_method(Vector2, move_toward, sarray("to", "delta"), varray());
bind_method(Vector2, rotated, sarray("phi"), varray());
bind_method(Vector2, orthogonal, sarray(), varray());
@@ -1507,6 +1510,8 @@ static void _register_variant_builtin_methods() {
/* Vector2i */
bind_method(Vector2i, aspect, sarray(), varray());
+ bind_method(Vector2i, max_axis_index, sarray(), varray());
+ bind_method(Vector2i, min_axis_index, sarray(), varray());
bind_method(Vector2i, sign, sarray(), varray());
bind_method(Vector2i, abs, sarray(), varray());
bind_method(Vector2i, clamp, sarray("min", "max"), varray());
@@ -1546,13 +1551,13 @@ static void _register_variant_builtin_methods() {
/* Vector3 */
- bind_method(Vector3, min_axis, sarray(), varray());
- bind_method(Vector3, max_axis, sarray(), varray());
+ bind_method(Vector3, min_axis_index, sarray(), varray());
+ bind_method(Vector3, max_axis_index, sarray(), varray());
bind_method(Vector3, angle_to, sarray("to"), varray());
bind_method(Vector3, signed_angle_to, sarray("to", "axis"), varray());
- bind_method(Vector3, direction_to, sarray("b"), varray());
- bind_method(Vector3, distance_to, sarray("b"), varray());
- bind_method(Vector3, distance_squared_to, sarray("b"), varray());
+ bind_method(Vector3, direction_to, sarray("to"), varray());
+ bind_method(Vector3, distance_to, sarray("to"), varray());
+ bind_method(Vector3, distance_squared_to, sarray("to"), varray());
bind_method(Vector3, length, sarray(), varray());
bind_method(Vector3, length_squared, sarray(), varray());
bind_method(Vector3, limit_length, sarray("length"), varray(1.0));
@@ -1581,11 +1586,13 @@ static void _register_variant_builtin_methods() {
bind_method(Vector3, bounce, sarray("n"), varray());
bind_method(Vector3, reflect, sarray("n"), varray());
bind_method(Vector3, sign, sarray(), varray());
+ bind_method(Vector3, octahedron_encode, sarray(), varray());
+ bind_static_method(Vector3, octahedron_decode, sarray("uv"), varray());
/* Vector3i */
- bind_method(Vector3i, min_axis, sarray(), varray());
- bind_method(Vector3i, max_axis, sarray(), varray());
+ bind_method(Vector3i, min_axis_index, sarray(), varray());
+ bind_method(Vector3i, max_axis_index, sarray(), varray());
bind_method(Vector3i, sign, sarray(), varray());
bind_method(Vector3i, abs, sarray(), varray());
bind_method(Vector3i, clamp, sarray("min", "max"), varray());
@@ -1617,6 +1624,8 @@ static void _register_variant_builtin_methods() {
bind_method(Quaternion, slerpni, sarray("to", "weight"), varray());
bind_method(Quaternion, cubic_slerp, sarray("b", "pre_a", "post_b", "weight"), varray());
bind_method(Quaternion, get_euler, sarray(), varray());
+ bind_method(Quaternion, get_axis, sarray(), varray());
+ bind_method(Quaternion, get_angle, sarray(), varray());
/* Color */
@@ -1626,17 +1635,15 @@ static void _register_variant_builtin_methods() {
bind_method(Color, to_argb64, sarray(), varray());
bind_method(Color, to_abgr64, sarray(), varray());
bind_method(Color, to_rgba64, sarray(), varray());
+ bind_method(Color, to_html, sarray("with_alpha"), varray(true));
bind_method(Color, clamp, sarray("min", "max"), varray(Color(0, 0, 0, 0), Color(1, 1, 1, 1)));
bind_method(Color, inverted, sarray(), varray());
bind_method(Color, lerp, sarray("to", "weight"), varray());
bind_method(Color, lightened, sarray("amount"), varray());
bind_method(Color, darkened, sarray("amount"), varray());
- bind_method(Color, to_html, sarray("with_alpha"), varray(true));
bind_method(Color, blend, sarray("over"), varray());
- // FIXME: Color is immutable, need to probably find a way to do this via constructor
- //ADDFUNC4R(COLOR, COLOR, Color, from_hsv, FLOAT, "h", FLOAT, "s", FLOAT, "v", FLOAT, "a", varray(1.0));
bind_method(Color, is_equal_approx, sarray("to"), varray());
bind_static_method(Color, hex, sarray("hex"), varray());
@@ -1648,6 +1655,7 @@ static void _register_variant_builtin_methods() {
bind_static_method(Color, get_named_color_name, sarray("idx"), varray());
bind_static_method(Color, get_named_color, sarray("idx"), varray());
bind_static_method(Color, from_string, sarray("str", "default"), varray());
+ bind_static_method(Color, from_hsv, sarray("h", "s", "v", "alpha"), varray(1.0));
bind_static_method(Color, from_rgbe9995, sarray("rgbe"), varray());
/* RID */
@@ -1727,7 +1735,7 @@ static void _register_variant_builtin_methods() {
bind_methodv(Basis, rotated, static_cast<Basis (Basis::*)(const Vector3 &, real_t) const>(&Basis::rotated), sarray("axis", "phi"), varray());
bind_method(Basis, scaled, sarray("scale"), varray());
bind_method(Basis, get_scale, sarray(), varray());
- bind_method(Basis, get_euler, sarray(), varray());
+ bind_method(Basis, get_euler, sarray("order"), varray(Basis::EULER_ORDER_YXZ));
bind_method(Basis, tdotx, sarray("with"), varray());
bind_method(Basis, tdoty, sarray("with"), varray());
bind_method(Basis, tdotz, sarray("with"), varray());
@@ -1737,13 +1745,14 @@ static void _register_variant_builtin_methods() {
bind_method(Basis, get_rotation_quaternion, sarray(), varray());
bind_static_method(Basis, looking_at, sarray("target", "up"), varray(Vector3(0, 1, 0)));
bind_static_method(Basis, from_scale, sarray("scale"), varray());
+ bind_static_method(Basis, from_euler, sarray("euler", "order"), varray(Basis::EULER_ORDER_YXZ));
/* AABB */
bind_method(AABB, abs, sarray(), varray());
bind_method(AABB, get_center, sarray(), varray());
- bind_method(AABB, get_area, sarray(), varray());
- bind_method(AABB, has_no_area, sarray(), varray());
+ bind_method(AABB, get_volume, sarray(), varray());
+ bind_method(AABB, has_no_volume, sarray(), varray());
bind_method(AABB, has_no_surface, sarray(), varray());
bind_method(AABB, has_point, sarray("point"), varray());
bind_method(AABB, is_equal_approx, sarray("aabb"), varray());
@@ -1803,7 +1812,7 @@ static void _register_variant_builtin_methods() {
bind_method(Array, append_array, sarray("array"), varray());
bind_method(Array, resize, sarray("size"), varray());
bind_method(Array, insert, sarray("position", "value"), varray());
- bind_method(Array, remove, sarray("position"), varray());
+ bind_method(Array, remove_at, sarray("position"), varray());
bind_method(Array, fill, sarray("value"), varray());
bind_method(Array, erase, sarray("value"), varray());
bind_method(Array, front, sarray(), varray());
@@ -1837,13 +1846,13 @@ static void _register_variant_builtin_methods() {
bind_method(PackedByteArray, push_back, sarray("value"), varray());
bind_method(PackedByteArray, append, sarray("value"), varray());
bind_method(PackedByteArray, append_array, sarray("array"), varray());
- bind_method(PackedByteArray, remove, sarray("index"), varray());
+ bind_method(PackedByteArray, remove_at, sarray("index"), varray());
bind_method(PackedByteArray, insert, sarray("at_index", "value"), varray());
bind_method(PackedByteArray, fill, sarray("value"), varray());
bind_method(PackedByteArray, resize, sarray("new_size"), varray());
bind_method(PackedByteArray, has, sarray("value"), varray());
bind_method(PackedByteArray, reverse, sarray(), varray());
- bind_method(PackedByteArray, subarray, sarray("from", "to"), varray());
+ bind_method(PackedByteArray, slice, sarray("begin", "end"), varray());
bind_method(PackedByteArray, sort, sarray(), varray());
bind_method(PackedByteArray, bsearch, sarray("value", "before"), varray(true));
bind_method(PackedByteArray, duplicate, sarray(), varray());
@@ -1898,13 +1907,13 @@ static void _register_variant_builtin_methods() {
bind_method(PackedInt32Array, push_back, sarray("value"), varray());
bind_method(PackedInt32Array, append, sarray("value"), varray());
bind_method(PackedInt32Array, append_array, sarray("array"), varray());
- bind_method(PackedInt32Array, remove, sarray("index"), varray());
+ bind_method(PackedInt32Array, remove_at, sarray("index"), varray());
bind_method(PackedInt32Array, insert, sarray("at_index", "value"), varray());
bind_method(PackedInt32Array, fill, sarray("value"), varray());
bind_method(PackedInt32Array, resize, sarray("new_size"), varray());
bind_method(PackedInt32Array, has, sarray("value"), varray());
bind_method(PackedInt32Array, reverse, sarray(), varray());
- bind_method(PackedInt32Array, subarray, sarray("from", "to"), varray());
+ bind_method(PackedInt32Array, slice, sarray("begin", "end"), varray());
bind_method(PackedInt32Array, to_byte_array, sarray(), varray());
bind_method(PackedInt32Array, sort, sarray(), varray());
bind_method(PackedInt32Array, bsearch, sarray("value", "before"), varray(true));
@@ -1918,13 +1927,13 @@ static void _register_variant_builtin_methods() {
bind_method(PackedInt64Array, push_back, sarray("value"), varray());
bind_method(PackedInt64Array, append, sarray("value"), varray());
bind_method(PackedInt64Array, append_array, sarray("array"), varray());
- bind_method(PackedInt64Array, remove, sarray("index"), varray());
+ bind_method(PackedInt64Array, remove_at, sarray("index"), varray());
bind_method(PackedInt64Array, insert, sarray("at_index", "value"), varray());
bind_method(PackedInt64Array, fill, sarray("value"), varray());
bind_method(PackedInt64Array, resize, sarray("new_size"), varray());
bind_method(PackedInt64Array, has, sarray("value"), varray());
bind_method(PackedInt64Array, reverse, sarray(), varray());
- bind_method(PackedInt64Array, subarray, sarray("from", "to"), varray());
+ bind_method(PackedInt64Array, slice, sarray("begin", "end"), varray());
bind_method(PackedInt64Array, to_byte_array, sarray(), varray());
bind_method(PackedInt64Array, sort, sarray(), varray());
bind_method(PackedInt64Array, bsearch, sarray("value", "before"), varray(true));
@@ -1938,13 +1947,13 @@ static void _register_variant_builtin_methods() {
bind_method(PackedFloat32Array, push_back, sarray("value"), varray());
bind_method(PackedFloat32Array, append, sarray("value"), varray());
bind_method(PackedFloat32Array, append_array, sarray("array"), varray());
- bind_method(PackedFloat32Array, remove, sarray("index"), varray());
+ bind_method(PackedFloat32Array, remove_at, sarray("index"), varray());
bind_method(PackedFloat32Array, insert, sarray("at_index", "value"), varray());
bind_method(PackedFloat32Array, fill, sarray("value"), varray());
bind_method(PackedFloat32Array, resize, sarray("new_size"), varray());
bind_method(PackedFloat32Array, has, sarray("value"), varray());
bind_method(PackedFloat32Array, reverse, sarray(), varray());
- bind_method(PackedFloat32Array, subarray, sarray("from", "to"), varray());
+ bind_method(PackedFloat32Array, slice, sarray("begin", "end"), varray());
bind_method(PackedFloat32Array, to_byte_array, sarray(), varray());
bind_method(PackedFloat32Array, sort, sarray(), varray());
bind_method(PackedFloat32Array, bsearch, sarray("value", "before"), varray(true));
@@ -1958,13 +1967,13 @@ static void _register_variant_builtin_methods() {
bind_method(PackedFloat64Array, push_back, sarray("value"), varray());
bind_method(PackedFloat64Array, append, sarray("value"), varray());
bind_method(PackedFloat64Array, append_array, sarray("array"), varray());
- bind_method(PackedFloat64Array, remove, sarray("index"), varray());
+ bind_method(PackedFloat64Array, remove_at, sarray("index"), varray());
bind_method(PackedFloat64Array, insert, sarray("at_index", "value"), varray());
bind_method(PackedFloat64Array, fill, sarray("value"), varray());
bind_method(PackedFloat64Array, resize, sarray("new_size"), varray());
bind_method(PackedFloat64Array, has, sarray("value"), varray());
bind_method(PackedFloat64Array, reverse, sarray(), varray());
- bind_method(PackedFloat64Array, subarray, sarray("from", "to"), varray());
+ bind_method(PackedFloat64Array, slice, sarray("begin", "end"), varray());
bind_method(PackedFloat64Array, to_byte_array, sarray(), varray());
bind_method(PackedFloat64Array, sort, sarray(), varray());
bind_method(PackedFloat64Array, bsearch, sarray("value", "before"), varray(true));
@@ -1978,13 +1987,13 @@ static void _register_variant_builtin_methods() {
bind_method(PackedStringArray, push_back, sarray("value"), varray());
bind_method(PackedStringArray, append, sarray("value"), varray());
bind_method(PackedStringArray, append_array, sarray("array"), varray());
- bind_method(PackedStringArray, remove, sarray("index"), varray());
+ bind_method(PackedStringArray, remove_at, sarray("index"), varray());
bind_method(PackedStringArray, insert, sarray("at_index", "value"), varray());
bind_method(PackedStringArray, fill, sarray("value"), varray());
bind_method(PackedStringArray, resize, sarray("new_size"), varray());
bind_method(PackedStringArray, has, sarray("value"), varray());
bind_method(PackedStringArray, reverse, sarray(), varray());
- bind_method(PackedStringArray, subarray, sarray("from", "to"), varray());
+ bind_method(PackedStringArray, slice, sarray("begin", "end"), varray());
bind_method(PackedStringArray, to_byte_array, sarray(), varray());
bind_method(PackedStringArray, sort, sarray(), varray());
bind_method(PackedStringArray, bsearch, sarray("value", "before"), varray(true));
@@ -1998,13 +2007,13 @@ static void _register_variant_builtin_methods() {
bind_method(PackedVector2Array, push_back, sarray("value"), varray());
bind_method(PackedVector2Array, append, sarray("value"), varray());
bind_method(PackedVector2Array, append_array, sarray("array"), varray());
- bind_method(PackedVector2Array, remove, sarray("index"), varray());
+ bind_method(PackedVector2Array, remove_at, sarray("index"), varray());
bind_method(PackedVector2Array, insert, sarray("at_index", "value"), varray());
bind_method(PackedVector2Array, fill, sarray("value"), varray());
bind_method(PackedVector2Array, resize, sarray("new_size"), varray());
bind_method(PackedVector2Array, has, sarray("value"), varray());
bind_method(PackedVector2Array, reverse, sarray(), varray());
- bind_method(PackedVector2Array, subarray, sarray("from", "to"), varray());
+ bind_method(PackedVector2Array, slice, sarray("begin", "end"), varray());
bind_method(PackedVector2Array, to_byte_array, sarray(), varray());
bind_method(PackedVector2Array, sort, sarray(), varray());
bind_method(PackedVector2Array, bsearch, sarray("value", "before"), varray(true));
@@ -2018,13 +2027,13 @@ static void _register_variant_builtin_methods() {
bind_method(PackedVector3Array, push_back, sarray("value"), varray());
bind_method(PackedVector3Array, append, sarray("value"), varray());
bind_method(PackedVector3Array, append_array, sarray("array"), varray());
- bind_method(PackedVector3Array, remove, sarray("index"), varray());
+ bind_method(PackedVector3Array, remove_at, sarray("index"), varray());
bind_method(PackedVector3Array, insert, sarray("at_index", "value"), varray());
bind_method(PackedVector3Array, fill, sarray("value"), varray());
bind_method(PackedVector3Array, resize, sarray("new_size"), varray());
bind_method(PackedVector3Array, has, sarray("value"), varray());
bind_method(PackedVector3Array, reverse, sarray(), varray());
- bind_method(PackedVector3Array, subarray, sarray("from", "to"), varray());
+ bind_method(PackedVector3Array, slice, sarray("begin", "end"), varray());
bind_method(PackedVector3Array, to_byte_array, sarray(), varray());
bind_method(PackedVector3Array, sort, sarray(), varray());
bind_method(PackedVector3Array, bsearch, sarray("value", "before"), varray(true));
@@ -2038,13 +2047,13 @@ static void _register_variant_builtin_methods() {
bind_method(PackedColorArray, push_back, sarray("value"), varray());
bind_method(PackedColorArray, append, sarray("value"), varray());
bind_method(PackedColorArray, append_array, sarray("array"), varray());
- bind_method(PackedColorArray, remove, sarray("index"), varray());
+ bind_method(PackedColorArray, remove_at, sarray("index"), varray());
bind_method(PackedColorArray, insert, sarray("at_index", "value"), varray());
bind_method(PackedColorArray, fill, sarray("value"), varray());
bind_method(PackedColorArray, resize, sarray("new_size"), varray());
bind_method(PackedColorArray, has, sarray("value"), varray());
bind_method(PackedColorArray, reverse, sarray(), varray());
- bind_method(PackedColorArray, subarray, sarray("from", "to"), varray());
+ bind_method(PackedColorArray, slice, sarray("begin", "end"), varray());
bind_method(PackedColorArray, to_byte_array, sarray(), varray());
bind_method(PackedColorArray, sort, sarray(), varray());
bind_method(PackedColorArray, bsearch, sarray("value", "before"), varray(true));
@@ -2105,6 +2114,13 @@ static void _register_variant_builtin_methods() {
_VariantCall::add_variant_constant(Variant::VECTOR2I, "UP", Vector2i(0, -1));
_VariantCall::add_variant_constant(Variant::VECTOR2I, "DOWN", Vector2i(0, 1));
+ _VariantCall::add_constant(Variant::BASIS, "EULER_ORDER_XYZ", Basis::EULER_ORDER_XYZ);
+ _VariantCall::add_constant(Variant::BASIS, "EULER_ORDER_XZY", Basis::EULER_ORDER_XZY);
+ _VariantCall::add_constant(Variant::BASIS, "EULER_ORDER_YXZ", Basis::EULER_ORDER_YXZ);
+ _VariantCall::add_constant(Variant::BASIS, "EULER_ORDER_YZX", Basis::EULER_ORDER_YZX);
+ _VariantCall::add_constant(Variant::BASIS, "EULER_ORDER_ZXY", Basis::EULER_ORDER_ZXY);
+ _VariantCall::add_constant(Variant::BASIS, "EULER_ORDER_ZYX", Basis::EULER_ORDER_ZYX);
+
_VariantCall::add_variant_constant(Variant::TRANSFORM2D, "IDENTITY", Transform2D());
_VariantCall::add_variant_constant(Variant::TRANSFORM2D, "FLIP_X", Transform2D(-1, 0, 0, 1, 0, 0));
_VariantCall::add_variant_constant(Variant::TRANSFORM2D, "FLIP_Y", Transform2D(1, 0, 0, -1, 0, 0));
diff --git a/core/variant/variant_construct.cpp b/core/variant/variant_construct.cpp
index 6aba7d7d58..5c14f30180 100644
--- a/core/variant/variant_construct.cpp
+++ b/core/variant/variant_construct.cpp
@@ -128,10 +128,10 @@ void Variant::_register_variant_constructors() {
add_constructor<VariantConstructNoArgs<Quaternion>>(sarray());
add_constructor<VariantConstructor<Quaternion, Quaternion>>(sarray("from"));
add_constructor<VariantConstructor<Quaternion, Basis>>(sarray("from"));
- add_constructor<VariantConstructor<Quaternion, Vector3>>(sarray("euler"));
add_constructor<VariantConstructor<Quaternion, Vector3, double>>(sarray("axis", "angle"));
add_constructor<VariantConstructor<Quaternion, Vector3, Vector3>>(sarray("arc_from", "arc_to"));
add_constructor<VariantConstructor<Quaternion, double, double, double, double>>(sarray("x", "y", "z", "w"));
+ add_constructor<VariantConstructor<Quaternion, Vector3>>(sarray("euler_yxz"));
add_constructor<VariantConstructNoArgs<::AABB>>(sarray());
add_constructor<VariantConstructor<::AABB, ::AABB>>(sarray("from"));
@@ -140,7 +140,6 @@ void Variant::_register_variant_constructors() {
add_constructor<VariantConstructNoArgs<Basis>>(sarray());
add_constructor<VariantConstructor<Basis, Basis>>(sarray("from"));
add_constructor<VariantConstructor<Basis, Quaternion>>(sarray("from"));
- add_constructor<VariantConstructor<Basis, Vector3>>(sarray("euler"));
add_constructor<VariantConstructor<Basis, Vector3, double>>(sarray("axis", "phi"));
add_constructor<VariantConstructor<Basis, Vector3, Vector3, Vector3>>(sarray("x_axis", "y_axis", "z_axis"));
diff --git a/core/variant/variant_internal.h b/core/variant/variant_internal.h
index 37383ff2ec..d24f3e90f5 100644
--- a/core/variant/variant_internal.h
+++ b/core/variant/variant_internal.h
@@ -753,8 +753,20 @@ VARIANT_ACCESSOR_NUMBER(uint32_t)
VARIANT_ACCESSOR_NUMBER(int64_t)
VARIANT_ACCESSOR_NUMBER(uint64_t)
VARIANT_ACCESSOR_NUMBER(char32_t)
+
+// Bind enums to allow using them as return types.
VARIANT_ACCESSOR_NUMBER(Error)
VARIANT_ACCESSOR_NUMBER(Side)
+VARIANT_ACCESSOR_NUMBER(Vector2::Axis)
+VARIANT_ACCESSOR_NUMBER(Vector2i::Axis)
+VARIANT_ACCESSOR_NUMBER(Vector3::Axis)
+VARIANT_ACCESSOR_NUMBER(Vector3i::Axis)
+
+template <>
+struct VariantInternalAccessor<Basis::EulerOrder> {
+ static _FORCE_INLINE_ Basis::EulerOrder get(const Variant *v) { return Basis::EulerOrder(*VariantInternal::get_int(v)); }
+ static _FORCE_INLINE_ void set(Variant *v, Basis::EulerOrder p_value) { *VariantInternal::get_int(v) = p_value; }
+};
template <>
struct VariantInternalAccessor<ObjectID> {
@@ -1014,6 +1026,10 @@ INITIALIZER_INT(int64_t)
INITIALIZER_INT(char32_t)
INITIALIZER_INT(Error)
INITIALIZER_INT(ObjectID)
+INITIALIZER_INT(Vector2::Axis)
+INITIALIZER_INT(Vector2i::Axis)
+INITIALIZER_INT(Vector3::Axis)
+INITIALIZER_INT(Vector3i::Axis)
template <>
struct VariantInitializer<double> {
diff --git a/core/variant/variant_parser.cpp b/core/variant/variant_parser.cpp
index 221a8c4f98..47561f4621 100644
--- a/core/variant/variant_parser.cpp
+++ b/core/variant/variant_parser.cpp
@@ -1443,7 +1443,7 @@ static String rtos_fix(double p_value) {
}
}
-Error VariantWriter::write(const Variant &p_variant, StoreStringFunc p_store_string_func, void *p_store_string_ud, EncodeResourceFunc p_encode_res_func, void *p_encode_res_ud) {
+Error VariantWriter::write(const Variant &p_variant, StoreStringFunc p_store_string_func, void *p_store_string_ud, EncodeResourceFunc p_encode_res_func, void *p_encode_res_ud, int recursion_count) {
switch (p_variant.get_type()) {
case Variant::NIL: {
p_store_string_func(p_store_string_ud, "null");
@@ -1598,14 +1598,14 @@ Error VariantWriter::write(const Variant &p_variant, StoreStringFunc p_store_str
}
//try path because it's a file
- if (res_text == String() && res->get_path().is_resource_file()) {
+ if (res_text.is_empty() && res->get_path().is_resource_file()) {
//external resource
String path = res->get_path();
res_text = "Resource(\"" + path + "\")";
}
//could come up with some sort of text
- if (res_text != String()) {
+ if (!res_text.is_empty()) {
p_store_string_func(p_store_string_ud, res_text);
break;
}
@@ -1639,41 +1639,56 @@ Error VariantWriter::write(const Variant &p_variant, StoreStringFunc p_store_str
case Variant::DICTIONARY: {
Dictionary dict = p_variant;
-
- List<Variant> keys;
- dict.get_key_list(&keys);
- keys.sort();
-
- 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]))
- continue;
- */
- write(E->get(), p_store_string_func, p_store_string_ud, p_encode_res_func, p_encode_res_ud);
- p_store_string_func(p_store_string_ud, ": ");
- write(dict[E->get()], p_store_string_func, p_store_string_ud, p_encode_res_func, p_encode_res_ud);
- if (E->next()) {
- p_store_string_func(p_store_string_ud, ",\n");
- } else {
- p_store_string_func(p_store_string_ud, "\n");
+ if (recursion_count > MAX_RECURSION) {
+ ERR_PRINT("Max recursion reached");
+ p_store_string_func(p_store_string_ud, "{}");
+ } else {
+ recursion_count++;
+
+ List<Variant> keys;
+ dict.get_key_list(&keys);
+ keys.sort();
+
+ 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()]))
+ continue;
+ */
+ write(E->get(), p_store_string_func, p_store_string_ud, p_encode_res_func, p_encode_res_ud, recursion_count);
+ p_store_string_func(p_store_string_ud, ": ");
+ write(dict[E->get()], p_store_string_func, p_store_string_ud, p_encode_res_func, p_encode_res_ud, recursion_count);
+ if (E->next()) {
+ p_store_string_func(p_store_string_ud, ",\n");
+ } else {
+ p_store_string_func(p_store_string_ud, "\n");
+ }
}
- }
- p_store_string_func(p_store_string_ud, "}");
+ p_store_string_func(p_store_string_ud, "}");
+ }
} break;
+
case Variant::ARRAY: {
- p_store_string_func(p_store_string_ud, "[");
- Array array = p_variant;
- int len = array.size();
- for (int i = 0; i < len; i++) {
- if (i > 0) {
- p_store_string_func(p_store_string_ud, ", ");
+ if (recursion_count > MAX_RECURSION) {
+ ERR_PRINT("Max recursion reached");
+ p_store_string_func(p_store_string_ud, "[]");
+ } else {
+ recursion_count++;
+
+ p_store_string_func(p_store_string_ud, "[");
+ Array array = p_variant;
+ int len = array.size();
+ for (int i = 0; i < len; i++) {
+ if (i > 0) {
+ p_store_string_func(p_store_string_ud, ", ");
+ }
+ write(array[i], p_store_string_func, p_store_string_ud, p_encode_res_func, p_encode_res_ud, recursion_count);
}
- write(array[i], p_store_string_func, p_store_string_ud, p_encode_res_func, p_encode_res_ud);
+
+ p_store_string_func(p_store_string_ud, "]");
}
- p_store_string_func(p_store_string_ud, "]");
} break;
diff --git a/core/variant/variant_parser.h b/core/variant/variant_parser.h
index 1ba26db6ed..2e4baa6fff 100644
--- a/core/variant/variant_parser.h
+++ b/core/variant/variant_parser.h
@@ -140,7 +140,7 @@ public:
typedef Error (*StoreStringFunc)(void *ud, const String &p_string);
typedef String (*EncodeResourceFunc)(void *ud, const RES &p_resource);
- static Error write(const Variant &p_variant, StoreStringFunc p_store_string_func, void *p_store_string_ud, EncodeResourceFunc p_encode_res_func, void *p_encode_res_ud);
+ static Error write(const Variant &p_variant, StoreStringFunc p_store_string_func, void *p_store_string_ud, EncodeResourceFunc p_encode_res_func, void *p_encode_res_ud, int recursion_count = 0);
static Error write_to_string(const Variant &p_variant, String &r_string, EncodeResourceFunc p_encode_res_func = nullptr, void *p_encode_res_ud = nullptr);
};
diff --git a/core/variant/variant_setget.cpp b/core/variant/variant_setget.cpp
index 4abb51ca7c..b6ad2d870e 100644
--- a/core/variant/variant_setget.cpp
+++ b/core/variant/variant_setget.cpp
@@ -704,7 +704,7 @@ struct VariantIndexedSetGet_String {
String *b = VariantGetInternalPtr<String>::get_ptr(base);
const String *v = VariantInternal::get_string(value);
if (v->length() == 0) {
- b->remove(index);
+ b->remove_at(index);
} else {
b->set(index, v->get(0));
}
@@ -723,7 +723,7 @@ struct VariantIndexedSetGet_String {
String *b = VariantGetInternalPtr<String>::get_ptr(base);
const String *v = VariantInternal::get_string(value);
if (v->length() == 0) {
- b->remove(index);
+ b->remove_at(index);
} else {
b->set(index, v->get(0));
}
@@ -738,7 +738,7 @@ struct VariantIndexedSetGet_String {
OOB_TEST(index, v.length());
const String &m = *reinterpret_cast<const String *>(member);
if (unlikely(m.length() == 0)) {
- v.remove(index);
+ v.remove_at(index);
} else {
v.set(index, m.unicode_at(0));
}
@@ -1824,11 +1824,15 @@ Variant Variant::iter_get(const Variant &r_iter, bool &r_valid) const {
return Variant();
}
-Variant Variant::duplicate(bool deep) const {
+Variant Variant::duplicate(bool p_deep) const {
+ return recursive_duplicate(p_deep, 0);
+}
+
+Variant Variant::recursive_duplicate(bool p_deep, int recursion_count) const {
switch (type) {
case OBJECT: {
/* breaks stuff :(
- if (deep && !_get_obj().ref.is_null()) {
+ if (p_deep && !_get_obj().ref.is_null()) {
Ref<Resource> resource = _get_obj().ref;
if (resource.is_valid()) {
return resource->duplicate(true);
@@ -1838,9 +1842,9 @@ Variant Variant::duplicate(bool deep) const {
return *this;
} break;
case DICTIONARY:
- return operator Dictionary().duplicate(deep);
+ return operator Dictionary().recursive_duplicate(p_deep, recursion_count);
case ARRAY:
- return operator Array().duplicate(deep);
+ return operator Array().recursive_duplicate(p_deep, recursion_count);
case PACKED_BYTE_ARRAY:
return operator Vector<uint8_t>().duplicate();
case PACKED_INT32_ARRAY:
diff --git a/core/variant/variant_utility.cpp b/core/variant/variant_utility.cpp
index 666b582e39..554b2f1c25 100644
--- a/core/variant/variant_utility.cpp
+++ b/core/variant/variant_utility.cpp
@@ -151,10 +151,10 @@ struct VariantUtilityFunctions {
r_error.error = Callable::CallError::CALL_OK;
switch (x.get_type()) {
case Variant::INT: {
- return SGN(VariantInternalAccessor<int64_t>::get(&x));
+ return SIGN(VariantInternalAccessor<int64_t>::get(&x));
} break;
case Variant::FLOAT: {
- return SGN(VariantInternalAccessor<double>::get(&x));
+ return SIGN(VariantInternalAccessor<double>::get(&x));
} break;
case Variant::VECTOR2: {
return VariantInternalAccessor<Vector2>::get(&x).sign();
@@ -176,11 +176,11 @@ struct VariantUtilityFunctions {
}
static inline double signf(double x) {
- return SGN(x);
+ return SIGN(x);
}
static inline int64_t signi(int64_t x) {
- return SGN(x);
+ return SIGN(x);
}
static inline double pow(double x, double y) {
@@ -275,6 +275,10 @@ struct VariantUtilityFunctions {
return Math::wrapf(value, min, max);
}
+ static inline double pingpong(double value, double length) {
+ return Math::pingpong(value, length);
+ }
+
static inline Variant max(const Variant **p_args, int p_argcount, Callable::CallError &r_error) {
if (p_argcount < 2) {
r_error.error = Callable::CallError::CALL_ERROR_TOO_FEW_ARGUMENTS;
@@ -399,6 +403,10 @@ struct VariantUtilityFunctions {
return Math::randf();
}
+ static inline double randfn(double mean, double deviation) {
+ return Math::randfn(mean, deviation);
+ }
+
static inline int64_t randi_range(int64_t from, int64_t to) {
return Math::random((int32_t)from, (int32_t)to);
}
@@ -1226,6 +1234,7 @@ void Variant::_register_variant_utility_functions() {
FUNCBINDR(clampf, sarray("value", "min", "max"), Variant::UTILITY_FUNC_TYPE_MATH);
FUNCBINDR(nearest_po2, sarray("value"), Variant::UTILITY_FUNC_TYPE_MATH);
+ FUNCBINDR(pingpong, sarray("value", "length"), Variant::UTILITY_FUNC_TYPE_MATH);
// Random
@@ -1234,6 +1243,7 @@ void Variant::_register_variant_utility_functions() {
FUNCBINDR(randf, sarray(), Variant::UTILITY_FUNC_TYPE_RANDOM);
FUNCBINDR(randi_range, sarray("from", "to"), Variant::UTILITY_FUNC_TYPE_RANDOM);
FUNCBINDR(randf_range, sarray("from", "to"), Variant::UTILITY_FUNC_TYPE_RANDOM);
+ FUNCBINDR(randfn, sarray("mean", "deviation"), Variant::UTILITY_FUNC_TYPE_RANDOM);
FUNCBIND(seed, sarray("base"), Variant::UTILITY_FUNC_TYPE_RANDOM);
FUNCBINDR(rand_from_seed, sarray("seed"), Variant::UTILITY_FUNC_TYPE_RANDOM);