diff options
41 files changed, 469 insertions, 70 deletions
diff --git a/core/math/a_star.cpp b/core/math/a_star.cpp index 401a33da8..0ba82ff88 100644 --- a/core/math/a_star.cpp +++ b/core/math/a_star.cpp @@ -28,6 +28,8 @@ /*************************************************************************/ #include "a_star.h" #include "geometry.h" +#include "scene/scene_string_names.h" +#include "script_language.h" int AStar::get_available_point_id() const { @@ -187,7 +189,7 @@ bool AStar::_solve(Point *begin_point, Point *end_point) { Point *n = begin_point->neighbours[i]; n->prev_point = begin_point; - n->distance = n->pos.distance_to(begin_point->pos); + n->distance = _compute_cost(n->id, begin_point->id); n->distance *= n->weight_scale; n->last_pass = pass; open_list.add(&n->list); @@ -215,7 +217,7 @@ bool AStar::_solve(Point *begin_point, Point *end_point) { Point *p = E->self(); float cost = p->distance; - cost += p->pos.distance_to(end_point->pos); + cost += _estimate_cost(p->id, end_point->id); cost *= p->weight_scale; if (cost < least_cost) { @@ -233,7 +235,7 @@ bool AStar::_solve(Point *begin_point, Point *end_point) { Point *e = p->neighbours[i]; - float distance = p->pos.distance_to(e->pos) + p->distance; + float distance = _compute_cost(p->id, e->id) + p->distance; distance *= e->weight_scale; if (e->last_pass == pass) { @@ -274,6 +276,20 @@ bool AStar::_solve(Point *begin_point, Point *end_point) { return found_route; } +float AStar::_estimate_cost(int p_from_id, int p_to_id) { + if (get_script_instance() && get_script_instance()->has_method(SceneStringNames::get_singleton()->_estimate_cost)) + return get_script_instance()->call(SceneStringNames::get_singleton()->_estimate_cost, p_from_id, p_to_id); + + return points[p_from_id]->pos.distance_to(points[p_to_id]->pos); +} + +float AStar::_compute_cost(int p_from_id, int p_to_id) { + if (get_script_instance() && get_script_instance()->has_method(SceneStringNames::get_singleton()->_compute_cost)) + return get_script_instance()->call(SceneStringNames::get_singleton()->_compute_cost, p_from_id, p_to_id); + + return points[p_from_id]->pos.distance_to(points[p_to_id]->pos); +} + DVector<Vector3> AStar::get_point_path(int p_from_id, int p_to_id) { ERR_FAIL_COND_V(!points.has(p_from_id), DVector<Vector3>()); @@ -395,6 +411,9 @@ void AStar::_bind_methods() { ObjectTypeDB::bind_method(_MD("get_point_path", "from_id", "to_id"), &AStar::get_point_path); ObjectTypeDB::bind_method(_MD("get_id_path", "from_id", "to_id"), &AStar::get_id_path); + + BIND_VMETHOD(MethodInfo("_estimate_cost", PropertyInfo(Variant::INT, "from_id"), PropertyInfo(Variant::INT, "to_id"))); + BIND_VMETHOD(MethodInfo("_compute_cost", PropertyInfo(Variant::INT, "from_id"), PropertyInfo(Variant::INT, "to_id"))); } AStar::AStar() { diff --git a/core/math/a_star.h b/core/math/a_star.h index c88591cf9..a0e9fc2cc 100644 --- a/core/math/a_star.h +++ b/core/math/a_star.h @@ -93,6 +93,9 @@ class AStar : public Reference { protected: static void _bind_methods(); + virtual float _estimate_cost(int p_from_id, int p_to_id); + virtual float _compute_cost(int p_from_id, int p_to_id); + public: int get_available_point_id() const; diff --git a/doc/base/classes.xml b/doc/base/classes.xml index aad217b8e..0f3e1a3f0 100644 --- a/doc/base/classes.xml +++ b/doc/base/classes.xml @@ -33677,6 +33677,7 @@ </brief_description> <description> Library that contains a collection of [Sample], each identified by a text ID. This is used as a data container for the majority of the SamplePlayer classes and derivatives. + Sample players will never yield an active (currently playing) voice for a new playback request when there are no inactive voices available if the priority of the sample requested to be played is lower than that of every currently played samples. </description> <methods> <method name="add_sample"> @@ -33737,6 +33738,15 @@ Return the volume (in dB) for the given sample. </description> </method> + <method name="sample_get_priority" qualifiers="const"> + <return type="int"> + </return> + <argument index="0" name="name" type="String"> + </argument> + <description> + Return the priority for the given sample. + </description> + </method> <method name="sample_set_pitch_scale"> <argument index="0" name="name" type="String"> </argument> @@ -33755,6 +33765,15 @@ Set the volume (in dB) for the given sample. </description> </method> + <method name="sample_set_priority"> + <argument index="0" name="name" type="String"> + </argument> + <argument index="1" name="priority" type="int"> + </argument> + <description> + Set the priority for the given sample. + </description> + </method> </methods> <constants> </constants> diff --git a/editor/editor_run.cpp b/editor/editor_run.cpp index e571c1971..0e9c0b77b 100644 --- a/editor/editor_run.cpp +++ b/editor/editor_run.cpp @@ -47,7 +47,13 @@ Error EditorRun::run(const String &p_scene, const String p_custom_args, const Li if (true) { args.push_back("-rdebug"); - args.push_back("localhost:" + String::num(GLOBAL_DEF("debug/debug_port", 6007))); +#ifdef WINDOWS_ENABLED + // Avoid failing DNS lookup on disconnected Windows machines. + const char *debug_host = "127.0.0.1:"; +#else + const char *debug_host = "localhost:"; +#endif + args.push_back(debug_host + String::num(GLOBAL_DEF("debug/debug_port", 6007))); } args.push_back("-epid"); diff --git a/editor/plugins/sample_library_editor_plugin.cpp b/editor/plugins/sample_library_editor_plugin.cpp index 08231d6eb..f626b4d33 100644 --- a/editor/plugins/sample_library_editor_plugin.cpp +++ b/editor/plugins/sample_library_editor_plugin.cpp @@ -175,6 +175,11 @@ void SampleLibraryEditor::_item_edited() { StringName n = s->get_text(0); sample_library->sample_set_pitch_scale(n, s->get_range(4)); + + } else if (tree->get_selected_column() == 5) { // Priority + + StringName n = s->get_text(0); + sample_library->sample_set_priority(n, s->get_range(5)); } } @@ -248,9 +253,16 @@ void SampleLibraryEditor::_update_library() { ti->set_editable(4, true); ti->set_range(4, sample_library->sample_get_pitch_scale(E->get())); + // Priority + ti->set_cell_mode(5, TreeItem::CELL_MODE_RANGE); + ti->set_range_config(5, 0, 100, 1); + ti->set_selectable(5, true); + ti->set_editable(5, true); + ti->set_range(5, sample_library->sample_get_priority(E->get())); + // Delete - ti->set_cell_mode(5, TreeItem::CELL_MODE_STRING); - ti->add_button(5, get_icon("Remove", "EditorIcons")); + ti->set_cell_mode(6, TreeItem::CELL_MODE_STRING); + ti->add_button(6, get_icon("Remove", "EditorIcons")); } //player->add_sample("default",sample); @@ -411,7 +423,7 @@ SampleLibraryEditor::SampleLibraryEditor() { file->set_mode(EditorFileDialog::MODE_OPEN_FILES); tree = memnew(Tree); - tree->set_columns(6); + tree->set_columns(7); add_child(tree); tree->set_anchor_and_margin(MARGIN_LEFT, ANCHOR_BEGIN, 5); tree->set_anchor_and_margin(MARGIN_RIGHT, ANCHOR_END, 5); @@ -423,18 +435,21 @@ SampleLibraryEditor::SampleLibraryEditor() { tree->set_column_title(2, TTR("Format")); tree->set_column_title(3, "dB"); tree->set_column_title(4, TTR("Pitch")); - tree->set_column_title(5, ""); + tree->set_column_title(5, TTR("Priority")); + tree->set_column_title(6, ""); tree->set_column_min_width(1, 150); tree->set_column_min_width(2, 100); tree->set_column_min_width(3, 50); tree->set_column_min_width(4, 50); - tree->set_column_min_width(5, 32); + tree->set_column_min_width(5, 60); + tree->set_column_min_width(6, 32); tree->set_column_expand(1, false); tree->set_column_expand(2, false); tree->set_column_expand(3, false); tree->set_column_expand(4, false); tree->set_column_expand(5, false); + tree->set_column_expand(6, false); tree->set_drag_forwarding(this); diff --git a/editor/plugins/tile_map_editor_plugin.cpp b/editor/plugins/tile_map_editor_plugin.cpp index 6e52c41d1..6c32650a4 100644 --- a/editor/plugins/tile_map_editor_plugin.cpp +++ b/editor/plugins/tile_map_editor_plugin.cpp @@ -192,6 +192,19 @@ void TileMapEditor::_sbox_input(const InputEvent &p_ie) { } } +// Implementation detail of TileMapEditor::_update_palette(); +// in modern C++ this could have been inside its body +namespace { +struct _PaletteEntry { + int id; + String name; + + bool operator<(const _PaletteEntry &p_rhs) const { + return name < p_rhs.name; + } +}; +} + void TileMapEditor::_update_palette() { if (!node) @@ -214,6 +227,8 @@ void TileMapEditor::_update_palette() { min_size *= EDSCALE; int hseparation = EDITOR_DEF("tile_map/palette_item_hseparation", 8); bool show_tile_names = bool(EDITOR_DEF("tile_map/show_tile_names", true)); + bool show_tile_ids = bool(EDITOR_DEF("tile_map/show_tile_ids", true)); + bool sort_by_name = bool(EDITOR_DEF("tile_map/sort_tiles_by_name", false)); palette->add_constant_override("hseparation", hseparation * EDSCALE); palette->add_constant_override("vseparation", 8 * EDSCALE); @@ -223,12 +238,20 @@ void TileMapEditor::_update_palette() { String filter = search_box->get_text().strip_edges(); + Vector<_PaletteEntry> entries; + for (List<int>::Element *E = tiles.front(); E; E = E->next()) { - String name; + String name = tileset->tile_get_name(E->get()); - if (tileset->tile_get_name(E->get()) != "") { - name = itos(E->get()) + " - " + tileset->tile_get_name(E->get()); + if (name != "") { + if (show_tile_ids) { + if (sort_by_name) { + name = name + " - " + itos(E->get()); + } else { + name = itos(E->get()) + " - " + name; + } + } } else { name = "#" + itos(E->get()); } @@ -236,16 +259,26 @@ void TileMapEditor::_update_palette() { if (filter != "" && !filter.is_subsequence_ofi(name)) continue; + const _PaletteEntry entry = { E->get(), name }; + entries.push_back(entry); + } + + if (sort_by_name) { + entries.sort(); + } + + for (int i = 0; i < entries.size(); i++) { + if (show_tile_names) { - palette->add_item(name); + palette->add_item(entries[i].name); } else { palette->add_item(String()); } - Ref<Texture> tex = tileset->tile_get_texture(E->get()); + Ref<Texture> tex = tileset->tile_get_texture(entries[i].id); if (tex.is_valid()) { - Rect2 region = tileset->tile_get_region(E->get()); + Rect2 region = tileset->tile_get_region(entries[i].id); if (!region.has_no_area()) palette->set_item_icon_region(palette->get_item_count() - 1, region); @@ -253,7 +286,7 @@ void TileMapEditor::_update_palette() { palette->set_item_icon(palette->get_item_count() - 1, tex); } - palette->set_item_metadata(palette->get_item_count() - 1, E->get()); + palette->set_item_metadata(palette->get_item_count() - 1, entries[i].id); } palette->set_same_column_width(true); @@ -1565,6 +1598,8 @@ TileMapEditorPlugin::TileMapEditorPlugin(EditorNode *p_node) { EDITOR_DEF("tile_map/preview_size", 64); EDITOR_DEF("tile_map/palette_item_hseparation", 8); EDITOR_DEF("tile_map/show_tile_names", true); + EDITOR_DEF("tile_map/show_tile_ids", true); + EDITOR_DEF("tile_map/sort_tiles_by_name", false); EDITOR_DEF("tile_map/bucket_fill_preview", true); tile_map_editor = memnew(TileMapEditor(p_node)); diff --git a/editor/property_editor.cpp b/editor/property_editor.cpp index 33f50a99c..1d0449e44 100644 --- a/editor/property_editor.cpp +++ b/editor/property_editor.cpp @@ -3385,8 +3385,8 @@ void PropertyEditor::_item_edited() { } break; case Variant::BOOL: { - _edit_set(name, item->is_checked(1)); item->set_tooltip(1, item->is_checked(1) ? "True" : "False"); + _edit_set(name, item->is_checked(1)); } break; case Variant::INT: case Variant::REAL: { diff --git a/editor/scene_tree_editor.cpp b/editor/scene_tree_editor.cpp index 5123ae6a7..d862a02d3 100644 --- a/editor/scene_tree_editor.cpp +++ b/editor/scene_tree_editor.cpp @@ -1110,6 +1110,7 @@ SceneTreeEditor::SceneTreeEditor(bool p_label, bool p_can_rename, bool p_can_ope tree->set_anchor(MARGIN_BOTTOM, ANCHOR_END); tree->set_begin(Point2(0, p_label ? 18 : 0)); tree->set_end(Point2(0, 0)); + tree->add_constant_override("button_margin", 0); add_child(tree); diff --git a/main/input_default.cpp b/main/input_default.cpp index 61169985b..e9d1cf53a 100644 --- a/main/input_default.cpp +++ b/main/input_default.cpp @@ -440,12 +440,27 @@ void InputDefault::warp_mouse_pos(const Vector2 &p_to) { Point2i InputDefault::warp_mouse_motion(const InputEventMouseMotion &p_motion, const Rect2 &p_rect) { - const Point2i rel_warped(Math::fmod(p_motion.relative_x, p_rect.size.x), Math::fmod(p_motion.relative_y, p_rect.size.y)); + // The relative distance reported for the next event after a warp is in the boundaries of the + // size of the rect on that axis, but it may be greater, in which case there's not problem as fmod() + // will warp it, but if the pointer has moved in the opposite direction between the pointer relocation + // and the subsequent event, the reported relative distance will be less than the size of the rect + // and thus fmod() will be disabled for handling the situation. + // And due to this mouse warping mechanism being stateless, we need to apply some heuristics to + // 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.relative_x >= 0.0f ? 1 : -1, p_motion.relative_y >= 0.0 ? 1 : -1); + const Size2i warp_margin = p_rect.size * 0.5f; + const Point2i rel_warped( + Math::fmod(p_motion.relative_x + rel_sgn.x * warp_margin.x, p_rect.size.x) - rel_sgn.x * warp_margin.x, + Math::fmod(p_motion.relative_y + rel_sgn.y * warp_margin.y, p_rect.size.y) - rel_sgn.y * warp_margin.y); + const Point2i pos_local = Point2i(p_motion.global_x, p_motion.global_y) - p_rect.pos; const Point2i pos_warped(Math::fposmod(pos_local.x, p_rect.size.x), Math::fposmod(pos_local.y, p_rect.size.y)); if (pos_warped != pos_local) { OS::get_singleton()->warp_mouse_pos(pos_warped + p_rect.pos); } + return rel_warped; } @@ -523,6 +538,7 @@ static const char *s_ControllerMappings[] = { "0d0f4900000000000000504944564944,Hatsune Miku Sho Controller,a:b1,b:b2,x:b0,y:b3,back:b8,guide:b12,start:b9,leftstick:b10,rightstick:b11,leftshoulder:b4,rightshoulder:b5,dpup:h0.1,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,leftx:a0,lefty:a1,rightx:a2,righty:a3,lefttrigger:b6,righttrigger:b7,", "0d0f6e00000000000000504944564944,HORIPAD 4,a:b1,b:b2,y:b3,x:b0,start:b9,guide:b12,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:a2,righty:a3,lefttrigger:b6,righttrigger:b7,", "10080100000000000000504944564944,PS1 USB,a:b2,b:b1,x:b3,y:b0,back:b8,start:b9,leftshoulder:b6,rightshoulder:b7,leftstick:b10,rightstick:b11,leftx:a0,lefty:a1,rightx:a3,righty:a2,lefttrigger:b4,righttrigger:b5,dpup:h0.1,dpleft:h0.8,dpdown:h0.4,dpright:h0.2,", + "100801e5000000000000504944564944,NEXT Classic USB Game Controller,a:b0,b:b1,back:b8,start:b9,rightx:a2,righty:a3,leftx:a0,lefty:a1,", "10080300000000000000504944564944,PS2 USB,a:b2,b:b1,y:b0,x:b3,start:b9,back:b8,leftstick:b10,rightstick:b11,leftshoulder:b6,rightshoulder:b7,dpup:h0.1,dpleft:h0.8,dpdown:h0.4,dpright:h0.2,leftx:a0,lefty:a1,rightx:a4,righty:a2,lefttrigger:b4,righttrigger:b5,", "10280900000000000000504944564944,8Bitdo SFC30 GamePad,a:b1,b:b0,y:b3,x:b4,start:b11,back:b10,leftshoulder:b6,leftx:a0,lefty:a1,rightshoulder:b7,", "20380900000000000000504944564944,8Bitdo NES30 PRO Wireless,a:b0,b:b1,x:b3,y:b4,leftshoulder:b6,rightshoulder:b7,lefttrigger:b8,righttrigger:b9,back:b10,start:b11,leftstick:b13,rightstick:b14,leftx:a0,lefty:a1,rightx:a3,righty:a4,dpup:h0.1,dpright:h0.2,dpdown:h0.4,dpleft:h0.8,", @@ -533,25 +549,28 @@ static const char *s_ControllerMappings[] = { "341a0108000000000000504944564944,EXEQ RF USB Gamepad 8206,a:b0,b:b1,x:b2,y:b3,leftshoulder:b4,rightshoulder:b5,leftstick:b8,rightstick:b7,back:b8,start:b9,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftx:a0,lefty:a1,rightx:a2,righty:a3,", "341a3608000000000000504944564944,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,", "36280100000000000000504944564944,OUYA Controller,a:b0,b:b3,y:b2,x:b1,start:b14,guide:b15,leftstick:b6,rightstick:b7,leftshoulder:b4,rightshoulder:b5,dpup:b8,dpleft:b10,dpdown:b9,dpright:b11,leftx:a0,lefty:a1,rightx:a3,righty:a4,lefttrigger:b12,righttrigger:b13,", - "49190204000000000000504944564944,Ipega PG-9023,a:b0,b:b1,x:b3,y:b4,back:b10,start:b11,leftstick:b13,rightstick:b14,leftshoulder:b6,rightshoulder:b7,dpup:h0.1,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,leftx:a0,lefty:a1,rightx:a3,righty:a4,lefttrigger:b8,righttrigger:b9", + "49190204000000000000504944564944,Ipega PG-9023,a:b0,b:b1,x:b3,y:b4,back:b10,start:b11,leftstick:b13,rightstick:b14,leftshoulder:b6,rightshoulder:b7,dpup:h0.1,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,leftx:a0,lefty:a1,rightx:a3,righty:a4,lefttrigger:b8,righttrigger:b9,", "4b12014d000000000000504944564944,NYKO AIRFLO,a:b0,b:b1,x:b2,y:b3,back:b8,guide:b10,start:b9,leftstick:a0,rightstick:a2,leftshoulder:a3,rightshoulder:b5,dpup:h0.1,dpdown:h0.0,dpleft:h0.8,dpright:h0.2,leftx:h0.6,lefty:h0.12,rightx:h0.9,righty:h0.4,lefttrigger:b6,righttrigger:b7,", "4c056802000000000000504944564944,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,", + "4c05a00b000000000000504944564944,Sony DualShock 4 Wireless Adaptor,a:b1,b:b2,y:b3,x:b0,start:b9,guide:b12,back:b13,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:a2,righty:a5,lefttrigger:a3,righttrigger:a4,", "4c05c405000000000000504944564944,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,", + "4c05cc09000000000000504944564944,Sony DualShock 4,a:b1,b:b2,y:b3,x:b0,start:b9,guide:b12,back:b13,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:a2,righty:a5,lefttrigger:a3,righttrigger:a4,", "4f0400b3000000000000504944564944,Thrustmaster Firestorm Dual Power,a:b0,b:b2,y:b3,x:b1,start:b10,guide:b8,back:b9,leftstick:b11,rightstick:b12,leftshoulder:b4,rightshoulder:b6,dpup:h0.1,dpleft:h0.8,dpdown:h0.4,dpright:h0.2,leftx:a0,lefty:a1,rightx:a2,righty:a3,lefttrigger:b5,righttrigger:b7,", "4f0415b3000000000000504944564944,Thrustmaster Dual Analog 3.2,x:b1,a:b0,b:b2,y:b3,back:b8,start:b9,dpleft:h0.8,dpdown:h0.4,dpright:h0.2,dpup:h0.1,leftshoulder:b4,lefttrigger:b5,rightshoulder:b6,righttrigger:b7,leftstick:b10,rightstick:b11,leftx:a0,lefty:a1,rightx:a2,righty:a3,", - "4f0423b3000000000000504944564944,Dual Trigger 3-in-1,a:b1,b:b2,x:b0,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:a5,lefttrigger:b6,righttrigger:b7", + "4f0423b3000000000000504944564944,Dual Trigger 3-in-1,a:b1,b:b2,x:b0,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:a5,lefttrigger:b6,righttrigger:b7,", "63252305000000000000504944564944,USB Vibration Joystick (BM),x:b3,a:b2,b:b1,y:b0,back:b8,start:b9,dpleft:h0.8,dpdown:h0.4,dpright:h0.2,dpup:h0.1,leftshoulder:b4,lefttrigger:b6,rightshoulder:b5,righttrigger:b7,leftstick:b10,rightstick:b11,leftx:a0,lefty:a1,rightx:a2,righty:a3,", "6d0416c2000000000000504944564944,Generic DirectInput 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,", "6d0418c2000000000000504944564944,Logitech RumblePad 2 USB,x:b0,a:b1,b:b2,y:b3,back:b8,start:b9,dpleft:h0.8,dpdown:h0.4,dpright:h0.2,dpup:h0.1,leftshoulder:b4,lefttrigger:b6,rightshoulder:b5,righttrigger:b7,leftstick:b10,rightstick:b11,leftx:a0,lefty:a1,rightx:a2,righty:a3,", "6d0419c2000000000000504944564944,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,", "6f0e1e01000000000000504944564944,Rock Candy Gamepad for PS3,a:b1,b:b2,x:b0,y:b3,back:b8,start:b9,guide:b12,leftshoulder:b4,rightshoulder:b5,leftstick:b10,rightstick:b11,leftx:a0,lefty:a1,rightx:a2,righty:a3,lefttrigger:b6,righttrigger:b7,dpup:h0.1,dpleft:h0.8,dpdown:h0.4,dpright:h0.2,", "79000018000000000000504944564944,Mayflash WiiU Pro Game Controller Adapter (DInput),a:b1,b:b2,x:b0,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,", - "79000600000000000000504944564944,G-Shark GS-GP702,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:a4,lefttrigger:b6,righttrigger:b7", + "79000600000000000000504944564944,G-Shark GS-GP702,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:a4,lefttrigger:b6,righttrigger:b7,", + "79000600000000000000504944564944,NGS Phantom,a:b2,b:b3,y:b1,x:b0,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:a2,righty:a4,lefttrigger:b6,righttrigger:b7,", "79004318000000000000504944564944,Mayflash GameCube Controller Adapter,a:b1,b:b2,x:b0,y:b3,back:b0,start:b9,guide:b0,leftshoulder:b4,rightshoulder:b7,leftstick:b0,rightstick:b0,leftx:a0,lefty:a1,rightx:a5,righty:a2,lefttrigger:a3,righttrigger:a4,dpup:h0.1,dpleft:h0.8,dpdown:h0.4,dpright:h0.2,", "79000600000000000000504944564944,Generic Speedlink,a:b2,b:b1,y:b0,x:b3,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:a2,righty:a4,lefttrigger:b6,righttrigger:b7,", "83056020000000000000504944564944,iBuffalo USB 2-axis 8-button Gamepad,a:b1,b:b0,y:b2,x:b3,start:b7,back:b6,leftshoulder:b4,rightshoulder:b5,leftx:a0,lefty:a1,", "88880803000000000000504944564944,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,", - "8f0e0300000000000000504944564944,Trust GXT 28,a:b2,b:b1,y:b0,x:b3,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:a2,righty:a3,lefttrigger:b6,righttrigger:b7,", + "8f0e0300000000000000504944564944,Piranha xtreme,x:b3,a:b2,b:b1,y:b0,back:b8,start:b9,dpleft:h0.8,dpdown:h0.4,dpright:h0.2,dpup:h0.1,leftshoulder:b6,lefttrigger:b4,rightshoulder:b7,righttrigger:b5,leftstick:b10,rightstick:b11,leftx:a0,lefty:a1,rightx:a3,righty:a2,", "8f0e0d31000000000000504944564944,Multilaser JS071 USB,a:b1,b:b2,y:b3,x:b0,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:a2,righty:a3,lefttrigger:b6,righttrigger:b7,", "8f0e1200000000000000504944564944,Acme,x:b2,a:b0,b:b1,y:b3,back:b8,start:b9,dpleft:h0.8,dpdown:h0.4,dpright:h0.2,dpup:h0.1,leftshoulder:b4,lefttrigger:b5,rightshoulder:b6,righttrigger:b7,leftstick:b10,rightstick:b11,leftx:a0,lefty:a1,rightx:a3,righty:a2,", "9000318000000000000504944564944,Mayflash Wiimote PC Adapter,a:b2,b:h0.4,x:b0,y:b1,back:b4,start:b5,guide:b11,leftshoulder:b6,rightshoulder:b3,leftx:a0,lefty:a1,", @@ -576,21 +595,27 @@ static const char *s_ControllerMappings[] = { "351200000000000021ab000000000000,SFC30 Joystick,a:b1,b:b0,x:b4,y:b3,back:b10,start:b11,leftshoulder:b6,rightshoulder:b7,leftx:a0,lefty:a1,", "4c050000000000006802000000000000,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,", "4c05000000000000c405000000000000,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,", + "4c05000000000000cc09000000000000,Sony DualShock 4 V2,a:b1,b:b2,y:b3,x:b0,start:b9,guide:b12,back:b13,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:a2,righty:a5,lefttrigger:a3,righttrigger:a4,", "4f0400000000000000b3000000000000,Thrustmaster Firestorm Dual Power,a:b0,b:b2,y:b3,x:b1,start:b10,guide:b8,back:b9,leftstick:b11,rightstick:,leftshoulder:b4,rightshoulder:b6,dpup:h0.1,dpleft:h0.8,dpdown:h0.4,dpright:h0.2,leftx:a0,lefty:a1,rightx:a2,righty:a3,lefttrigger:b5,righttrigger:b7,", "4f0400000000000015b3000000000000,Thrustmaster Dual Analog 3.2,x:b1,a:b0,b:b2,y:b3,back:b8,start:b9,dpleft:h0.8,dpdown:h0.4,dpright:h0.2,dpup:h0.1,leftshoulder:b4,lefttrigger:b5,rightshoulder:b6,righttrigger:b7,leftstick:b10,rightstick:b11,leftx:a0,lefty:a1,rightx:a2,righty:a3,", "5e040000000000008e02000000000000,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,", "5e04000000000000dd02000000000000,Xbox One Wired Controller,x:b2,a:b0,b:b1,y:b3,back:b9,guide:b10,start:b8,dpleft:b13,dpdown:b12,dpright:b14,dpup:b11,leftshoulder:b4,lefttrigger:a2,rightshoulder:b5,righttrigger:a5,leftstick:b6,rightstick:b7,leftx:a0,lefty:a1,rightx:a3,righty:a4,", + "5e04000000000000e002000000000000,Xbox Wireless Controller,x:b2,a:b0,b:b1,y:b3,back:b6,guide:b10,start:b7,dpleft:h0.8,dpdown:h0.4,dpright:h0.2,dpup:h0.1,leftshoulder:b4,lefttrigger:a2,rightshoulder:b5,righttrigger:a5,leftstick:b8,rightstick:b9,leftx:a0,lefty:a1,rightx:a3,righty:a4,", + "5e04000000000000ea02000000000000,Xbox Wireless Controller,x:b2,a:b0,b:b1,y:b3,back:b9,guide:b10,start:b8,dpleft:b13,dpdown:b12,dpright:b14,dpup:b11,leftshoulder:b4,lefttrigger:a2,rightshoulder:b5,righttrigger:a5,leftstick:b6,rightstick:b7,leftx:a0,lefty:a1,rightx:a3,righty:a4,", "6d0400000000000016c2000000000000,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,", /* Guide button doesn't seem to be sent in DInput mode. */ "6d0400000000000018c2000000000000,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,", "6d0400000000000019c2000000000000,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,", /* This includes F710 in DInput mode and the "Logitech Cordless RumblePad 2", at the very least. */ "6d040000000000001fc2000000000000,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,", "79000000000000000018000000000000,Mayflash WiiU Pro Game Controller Adapter (DInput),a:b4,b:b8,x:b0,y:b12,back:b32,start:b36,leftstick:b40,rightstick:b44,leftshoulder:b16,rightshoulder:b20,dpup:h0.1,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,leftx:a0,lefty:a4,rightx:a8,righty:a12,lefttrigger:b24,righttrigger:b28,", "79000000000000000600000000000000,G-Shark GP-702,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:a3,righty:a4,lefttrigger:b6,righttrigger:b7,", + "79000000000000001100000000000000,Retrolink Classic Controller,x:b3,a:b2,b:b1,y:b0,back:b8,start:b9,leftshoulder:b4,rightshoulder:b5,leftx:a3,lefty:a4,", + "81170000000000007e05000000000000,Sega Saturn,x:b0,a:b2,b:b4,y:b6,start:b13,dpleft:b15,dpdown:b16,dpright:b14,dpup:b17,leftshoulder:b8,lefttrigger:a5,lefttrigger:b10,rightshoulder:b9,righttrigger:a4,righttrigger:b11,leftx:a0,lefty:a2,", "83050000000000006020000000000000,iBuffalo USB 2-axis 8-button Gamepad,a:b1,b:b0,x:b3,y:b2,back:b6,start:b7,leftshoulder:b4,rightshoulder:b5,leftx:a0,lefty:a1,", "891600000000000000fd000000000000,Razer Onza Tournament,a:b0,b:b1,y:b3,x:b2,start:b8,guide:b10,back:b9,leftstick:b6,rightstick:b7,leftshoulder:b4,rightshoulder:b5,dpup:b11,dpleft:b13,dpdown:b12,dpright:b14,leftx:a0,lefty:a1,rightx:a3,righty:a4,lefttrigger:a2,righttrigger:a5,", "8f0e0000000000000300000000000000,Piranha xtreme,x:b3,a:b2,b:b1,y:b0,back:b8,start:b9,dpleft:h0.8,dpdown:h0.4,dpright:h0.2,dpup:h0.1,leftshoulder:b6,lefttrigger:b4,rightshoulder:b7,righttrigger:b5,leftstick:b10,rightstick:b11,leftx:a0,lefty:a1,rightx:a3,righty:a2,", "ad1b00000000000001f9000000000000,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,", "b4040000000000000a01000000000000,Sega Saturn USB Gamepad,a:b0,b:b1,x:b3,y:b4,back:b5,guide:b2,start:b8,leftshoulder:b6,rightshoulder:b7,leftx:a0,lefty:a1,", + "bd1200000000000015d0000000000000,Tomee SNES USB Controller,x:b3,a:b2,b:b1,y:b0,back:b8,start:b9,leftshoulder:b4,rightshoulder:b5,leftx:a0,lefty:a1,", "d814000000000000cecf000000000000,MC Cthulhu,leftx:,lefty:,rightx:,righty:,lefttrigger:b6,a:b1,b:b2,y:b3,x:b0,start:b9,back:b8,leftshoulder:b4,rightshoulder:b5,dpup:h0.1,dpleft:h0.8,dpdown:h0.4,dpright:h0.2,righttrigger:b7,", #endif @@ -598,24 +623,30 @@ static const char *s_ControllerMappings[] = { "0000000058626f782047616d65706100,Xbox Gamepad (userspace driver),a:b0,b:b1,x:b2,y:b3,start:b7,back:b6,guide:b8,dpup:h0.1,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,leftshoulder:b4,rightshoulder:b5,lefttrigger:a5,righttrigger:a4,leftstick:b9,rightstick:b10,leftx:a0,lefty:a1,rightx:a2,righty:a3,", "0300000000f000000300000000010000,RetroUSB.com RetroPad,a:b1,b:b5,x:b0,y:b4,back:b2,start:b3,leftshoulder:b6,rightshoulder:b7,leftx:a0,lefty:a1,", "0300000000f00000f100000000010000,RetroUSB.com Super RetroPort,a:b1,b:b5,x:b0,y:b4,back:b2,start:b3,leftshoulder:b6,rightshoulder:b7,leftx:a0,lefty:a1,", + "030000000d0f00000d00000000010000,hori,a:b0,b:b6,y:b2,x:b1,dpup:h0.1,dpleft:h0.8,dpdown:h0.4,dpright:h0.2,start:b9,guide:b10,back:b8,leftshoulder:b3,rightshoulder:b7,leftx:b4,lefty:b5,", "030000000d0f00001000000011010000,HORI CO.,LTD. FIGHTING STICK 3,x:b0,a:b1,b:b2,y:b3,back:b8,guide:b12,start:b9,dpleft:h0.8,dpdown:h0.4,dpright:h0.2,dpup:h0.1,leftshoulder:b4,lefttrigger:b6,rightshoulder:b5,righttrigger:b7", "030000000d0f00002200000011010000,HORI CO.,LTD. REAL ARCADE Pro.V3,x:b0,a:b1,b:b2,y:b3,back:b8,guide:b12,start:b9,leftshoulder:b4,lefttrigger:b6,rightshoulder:b5,righttrigger:b7,dpleft:h0.8,dpdown:h0.4,dpright:h0.2,dpup:h0.1,", "030000000d0f00004d00000011010000,HORI Gem Pad 3,x:b0,a:b1,b:b2,y:b3,back:b8,guide:b12,start:b9,dpleft:h0.8,dpdown:h0.4,dpright:h0.2,dpup:h0.1,leftshoulder:b4,lefttrigger:b6,rightshoulder:b5,righttrigger:b7,leftstick:b10,rightstick:b11,leftx:a0,lefty:a1,rightx:a2,righty:a3,", "03000000100800000100000010010000,Twin USB PS2 Adapter,a:b2,b:b1,y:b0,x:b3,start:b9,guide:,back:b8,leftstick:b10,rightstick:b11,leftshoulder:b6,rightshoulder:b7,dpup:h0.1,dpleft:h0.8,dpdown:h0.4,dpright:h0.2,leftx:a0,lefty:a1,rightx:a3,righty:a2,lefttrigger:b4,righttrigger:b5,", + "030000001008000001e5000010010000,NEXT Classic USB Game Controller,a:b0,b:b1,back:b8,start:b9,rightx:a2,righty:a3,leftx:a0,lefty:a1,", + "03000000100800000300000010010000,USB Gamepad,a:b2,b:b1,x:b3,y:b0,start:b9,back:b8,leftstick:b10,rightstick:b11,leftshoulder:b6,rightshoulder:b7,dpup:h0.1,dpleft:h0.8,dpdown:h0.4,dpright:h0.2,leftx:a0,lefty:a1,rightx:a3,righty:a2,lefttrigger:b4,righttrigger:b5,", "03000000250900000500000000010000,Sony PS2 pad with SmartJoy adapter,a:b2,b:b1,y:b0,x:b3,start:b8,back:b9,leftstick:b10,rightstick:b11,leftshoulder:b6,rightshoulder:b7,dpup:h0.1,dpleft:h0.8,dpdown:h0.4,dpright:h0.2,leftx:a0,lefty:a1,rightx:a2,righty:a3,lefttrigger:b4,righttrigger:b5,", "03000000260900008888000000010000,GameCube {WiseGroup USB box},a:b0,b:b2,y:b3,x:b1,start:b7,leftshoulder:,rightshoulder:b6,dpup:h0.1,dpleft:h0.8,rightstick:,dpdown:h0.4,dpright:h0.2,leftx:a0,lefty:a1,rightx:a2,righty:a3,lefttrigger:a4,righttrigger:a5,", "03000000280400000140000000010000,Gravis GamePad Pro USB ,x:b0,a:b1,b:b2,y:b3,back:b8,start:b9,leftshoulder:b4,lefttrigger:b6,rightshoulder:b5,righttrigger:b7,leftx:a0,lefty:a1,", "03000000341a000005f7000010010000,GameCube {HuiJia USB box},a:b1,b:b2,y:b3,x:b0,start:b9,guide:,back:,leftstick:,rightstick:,leftshoulder:,dpleft:b15,dpdown:b14,dpright:b13,leftx:a0,lefty:a1,rightx:a5,righty:a2,lefttrigger:a3,righttrigger:a4,rightshoulder:b7,dpup:b12,", "03000000380700001647000010040000,Mad Catz Wired Xbox 360 Controller,x:b2,a:b0,b:b1,y:b3,back:b6,guide:b8,start:b7,dpleft:h0.8,dpdown:h0.0,dpdown:h0.4,dpright:h0.0,dpright:h0.2,dpup:h0.0,dpup:h0.1,leftshoulder:h0.0,leftshoulder:b4,lefttrigger:a2,rightshoulder:b5,righttrigger:a5,leftstick:b9,rightstick:b10,leftx:a0,lefty:a1,rightx:a3,righty:a4,", "030000004c0500006802000011010000,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,", + "030000004c050000a00b000011010000,Sony DualShock 4 Wireless Adaptor,a:b1,b:b2,y:b3,x:b0,start:b9,guide:b12,back:b13,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:a2,righty:a5,lefttrigger:a3,righttrigger:a4,", "030000004c050000c405000011010000,Sony DualShock 4,a:b1,b:b2,y:b3,x:b0,start:b9,guide:b12,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:a2,righty:a5,lefttrigger:a3,righttrigger:a4,", + "030000004c050000cc09000011010000,Sony DualShock 4 V2,a:b1,b:b2,y:b3,x:b0,start:b9,guide:b12,back:b13,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:a2,righty:a5,lefttrigger:a3,righttrigger:a4,", "030000004f04000000b3000010010000,Thrustmaster Firestorm Dual Power,a:b0,b:b2,y:b3,x:b1,start:b10,guide:b8,back:b9,leftstick:b11,rightstick:b12,leftshoulder:b4,rightshoulder:b6,dpup:h0.1,dpleft:h0.8,dpdown:h0.4,dpright:h0.2,leftx:a0,lefty:a1,rightx:a2,righty:a3,lefttrigger:b5,righttrigger:b7,", "030000004f04000008d0000000010000,Thrustmaster Run N Drive Wireless,a:b1,b:b2,x:b0,y:b3,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:a2,righty:a5,lefttrigger:b6,righttrigger:b7,", "030000004f04000009d0000000010000,Thrustmaster Run N Drive Wireless PS3,a:b1,b:b2,x:b0,y:b3,start:b9,guide:b12,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:a2,righty:a3,lefttrigger:b6,righttrigger:b7,", "030000004f04000015b3000010010000,Thrustmaster Dual Analog 4,a:b0,b:b2,x:b1,y:b3,start:b9,back:b8,leftstick:b10,rightstick:b11,leftshoulder:b4,rightshoulder:b6,dpup:h0.1,dpleft:h0.8,dpdown:h0.4,dpright:h0.2,leftx:a0,lefty:a1,rightx:a2,righty:a3,lefttrigger:b5,righttrigger:b7,", "030000004f04000020b3000010010000,Thrustmaster 2 in 1 DT,a:b0,b:b2,y:b3,x:b1,start:b9,guide:,back:b8,leftstick:b10,rightstick:b11,leftshoulder:b4,rightshoulder:b6,dpup:h0.1,dpleft:h0.8,dpdown:h0.4,dpright:h0.2,leftx:a0,lefty:a1,rightx:a2,righty:a3,lefttrigger:b5,righttrigger:b7,", "030000004f04000023b3000000010000,Thrustmaster Dual Trigger 3-in-1,x:b0,a:b1,b:b2,y:b3,back:b8,start:b9,dpleft:h0.8,dpdown:h0.0,dpdown:h0.4,dpright:h0.0,dpright:h0.2,dpup:h0.0,dpup:h0.1,leftshoulder:h0.0,leftshoulder:b4,lefttrigger:b6,rightshoulder:b5,righttrigger:b7,leftstick:b10,rightstick:b11,leftx:a0,lefty:a1,rightx:a2,righty:a5,", - "030000005e0400001907000000010000,X360 Wireless Controller,leftx:a0,lefty:a1,dpdown:h0.4,rightstick:b10,rightshoulder:b5,rightx:a3,start:b7,righty:a4,dpleft:h0.8,lefttrigger:a2,x:b2,dpup:h0.1,back:b6,leftstick:b9,leftshoulder:b4,y:b3,a:b0,dpright:h0.2,righttrigger:a5,b:b1,", + "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,", + "030000005e0400008502000000010000,Microsoft X-Box pad (Japan),x:b3,a:b0,b:b1,y:b4,back:b6,start:b7,dpleft:h0.8,dpdown:h0.4,dpright:h0.2,dpup:h0.1,leftshoulder:b5,lefttrigger:a2,rightshoulder:b2,righttrigger:a5,leftstick:b8,rightstick:b9,leftx:a0,lefty:a1,rightx:a3,righty:a4,", "030000005e0400008902000021010000,Microsoft X-Box pad v2 (US),x:b3,a:b0,b:b1,y:b4,back:b6,start:b7,dpleft:h0.8,dpdown:h0.4,dpright:h0.2,dpup:h0.1,leftshoulder:b5,lefttrigger:a2,rightshoulder:b2,righttrigger:a5,leftstick:b8,rightstick:b9,leftx:a0,lefty:a1,rightx:a3,righty:a4,", "030000005e0400008e02000001000000,Microsoft X-Box 360 pad,leftstick:b9,leftx:a0,lefty:a1,dpdown:h0.1,rightstick:b10,rightshoulder:b5,rightx:a3,start:b7,righty:a4,dpleft:h0.2,lefttrigger:a2,x:b2,dpup:h0.4,back:b6,leftshoulder:b4,y:b3,a:b0,dpright:h0.8,righttrigger:a5,b:b1,", "030000005e0400008e02000004010000,Microsoft X-Box 360 pad,a:b0,b:b1,x:b2,y:b3,back:b6,start:b7,guide:b8,leftshoulder:b4,rightshoulder:b5,leftstick:b9,rightstick:b10,leftx:a0,lefty:a1,rightx:a3,righty:a4,lefttrigger:a2,righttrigger:a5,dpup:h0.1,dpleft:h0.8,dpdown:h0.4,dpright:h0.2,", @@ -623,12 +654,15 @@ static const char *s_ControllerMappings[] = { "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,", "030000005e0400008e02000020200000,SpeedLink XEOX Pro Analog Gamepad pad,x:b2,a:b0,b:b1,y:b3,back:b6,guide:b8,start:b7,dpleft:h0.8,dpdown:h0.4,dpright:h0.2,dpup:h0.1,leftshoulder:b4,lefttrigger:a2,rightshoulder:b5,righttrigger:a5,leftstick:b9,rightstick:b10,leftx:a0,lefty:a1,rightx:a3,righty:a4,", "030000005e0400008e02000062230000,Microsoft X-Box 360 pad,x:b2,a:b0,b:b1,y:b3,back:b6,guide:b8,start:b7,dpleft:h0.8,dpdown:h0.4,dpright:h0.2,dpup:h0.1,leftshoulder:b4,lefttrigger:a2,rightshoulder:b5,righttrigger:a5,leftstick:b9,rightstick:b10,leftx:a0,lefty:a1,rightx:a3,righty:a4,", - "030000005e0400009102000007010000,X360 Wireless Controller,a:b0,b:b1,y:b3,x:b2,start:b7,guide:b8,back:b6,leftstick:b9,rightstick:b10,leftshoulder:b4,rightshoulder:b5,dpup:b13,dpleft:b11,dpdown:b14,dpright:b12,leftx:a0,lefty:a1,rightx:a3,righty:a4,lefttrigger:a2,righttrigger:a5,", + "030000005e0400008e02000073050000,Speedlink TORID Wireless Gamepad,x:b2,a:b0,b:b1,y:b3,back:b6,guide:b8,start:b7,dpleft:h0.8,dpdown:h0.4,dpright:h0.2,dpup:h0.1,leftshoulder:b4,lefttrigger:a2,rightshoulder:b5,righttrigger:a5,leftstick:b9,rightstick:b10,leftx:a0,lefty:a1,rightx:a3,righty:a4,", + "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,", + "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,", "030000005e040000d102000001010000,Microsoft X-Box One pad,x:b2,a:b0,b:b1,y:b3,back:b6,guide:b8,start:b7,dpleft:h0.8,dpdown:h0.0,dpdown:h0.4,dpright:h0.0,dpright:h0.2,dpup:h0.0,dpup:h0.1,leftshoulder:h0.0,leftshoulder:b4,lefttrigger:a2,rightshoulder:b5,righttrigger:a5,leftstick:b9,rightstick:b10,leftx:a0,lefty:a1,rightx:a3,righty:a4,", "030000005e040000dd02000003020000,Microsoft X-Box One pad v2,x:b2,a:b0,b:b1,y:b3,back:b6,guide:b8,start:b7,dpleft:h0.8,dpdown:h0.0,dpdown:h0.4,dpright:h0.0,dpright:h0.2,dpup:h0.0,dpup:h0.1,leftshoulder:h0.0,leftshoulder:b4,lefttrigger:a2,rightshoulder:b5,righttrigger:a5,leftstick:b9,rightstick:b10,leftx:a0,lefty:a1,rightx:a3,righty:a4,", "03000000666600000488000000010000,Super Joy Box 5 Pro,a:b2,b:b1,x:b3,y:b0,back:b9,start:b8,leftshoulder:b6,rightshoulder:b7,leftstick:b10,rightstick:b11,leftx:a0,lefty:a1,rightx:a2,righty:a3,lefttrigger:b4,righttrigger:b5,dpup:b12,dpleft:b15,dpdown:b14,dpright:b13,", "030000006d04000011c2000010010000,Logitech WingMan Cordless RumblePad,a:b0,b:b1,y:b4,x:b3,start:b8,guide:b5,back:b2,leftshoulder:b6,rightshoulder:b7,dpup:h0.1,dpleft:h0.8,dpdown:h0.4,dpright:h0.2,leftx:a0,lefty:a1,rightx:a3,righty:a4,lefttrigger:b9,righttrigger:b10,", "030000006d04000016c2000010010000,Logitech Logitech Dual Action,x:b0,a:b1,b:b2,y:b3,back:b8,start:b9,dpleft:h0.8,dpdown:h0.0,dpdown:h0.4,dpright:h0.0,dpright:h0.2,dpup:h0.0,dpup:h0.1,leftshoulder:h0.0,dpup:h0.1,leftshoulder:h0.0,leftshoulder:b4,lefttrigger:b6,rightshoulder:b5,righttrigger:b7,leftstick:b10,rightstick:b11,leftx:a0,lefty:a1,rightx:a2,righty:a3,", + "030000006d04000016c2000011010000,Logitech F310 Gamepad (DInput),x:b0,a:b1,b:b2,y:b3,back:b8,start:b9,dpleft:h0.8,dpdown:h0.0,dpdown:h0.4,dpright:h0.0,dpright:h0.2,dpup:h0.0,dpup:h0.1,leftshoulder:h0.0,dpup:h0.1,leftshoulder:h0.0,leftshoulder:b4,lefttrigger:b6,rightshoulder:b5,righttrigger:b7,leftstick:b10,rightstick:b11,leftx:a0,lefty:a1,rightx:a2,righty:a3,", "030000006d04000018c2000010010000,Logitech Logitech RumblePad 2 USB,x:b0,a:b1,b:b2,y:b3,back:b8,start:b9,dpleft:h0.8,dpdown:h0.4,dpright:h0.2,dpup:h0.1,leftshoulder:b4,lefttrigger:b6,rightshoulder:b5,righttrigger:b7,leftstick:b10,rightstick:b11,leftx:a0,lefty:a1,rightx:a2,righty:a3,", "030000006d04000019c2000010010000,Logitech Cordless RumblePad 2,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:,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,", "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,", @@ -645,6 +679,7 @@ static const char *s_ControllerMappings[] = { "030000006f0e00003901000020060000,Afterglow Wired Controller for Xbox One,x:b2,a:b0,b:b1,y:b3,back:b6,guide:b8,start:b7,dpleft:h0.8,dpdown:h0.4,dpright:h0.2,dpup:h0.1,leftshoulder:b4,lefttrigger:a2,rightshoulder:b5,righttrigger:a5,leftstick:b9,rightstick:b10,leftx:a0,lefty:a1,rightx:a3,righty:a4,", "030000006f0e00004601000001010000,Rock Candy Wired Controller for Xbox One,a:b0,b:b1,x:b2,y:b3,leftshoulder:b4,rightshoulder:b5,back:b6,start:b7,guide:b8,leftstick:b9,rightstick:b10,lefttrigger:a2,righttrigger:a5,leftx:a0,lefty:a1,rightx:a3,righty:a4,", "03000000790000000600000010010000,DragonRise Inc. Generic USB Joystick,x:b3,a:b2,b:b1,y:b0,back:b8,start:b9,dpleft:h0.8,dpdown:h0.4,dpright:h0.2,dpup:h0.1,leftshoulder:b4,lefttrigger:b6,rightshoulder:b5,righttrigger:b7,leftstick:b10,rightstick:b11,leftx:a0,lefty:a1,rightx:a3,righty:a4,", + "03000000790000001100000010010000,Retrolink Classic Controller,x:b3,a:b2,b:b1,y:b0,back:b8,start:b9,leftshoulder:b4,rightshoulder:b5,leftx:a0,lefty:a1,", "03000000790000001100000010010000,RetroLink Saturn Classic Controller,x:b3,a:b0,b:b1,y:b4,back:b5,guide:b2,start:b8,leftshoulder:b6,rightshoulder:b7,leftx:a0,lefty:a1,", "03000000830500006020000010010000,iBuffalo USB 2-axis 8-button Gamepad,a:b1,b:b0,x:b3,y:b2,back:b6,start:b7,leftshoulder:b4,rightshoulder:b5,leftx:a0,lefty:a1,", "030000008916000000fd000024010000,Razer Onza Tournament,a:b0,b:b1,y:b3,x:b2,start:b7,guide:b8,back:b6,leftstick:b9,rightstick:b10,leftshoulder:b4,rightshoulder:b5,dpup:b13,dpleft:b11,dpdown:b14,dpright:b12,leftx:a0,lefty:a1,rightx:a3,righty:a4,lefttrigger:a2,righttrigger:a5,", @@ -657,24 +692,29 @@ static const char *s_ControllerMappings[] = { "03000000a306000023f6000011010000,Saitek Cyborg V.1 Game Pad,a:b1,b:b2,y:b3,x:b0,start:b9,guide:b12,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:a2,righty:a4,lefttrigger:b6,righttrigger:b7,", "03000000ad1b000001f5000033050000,Hori Pad EX Turbo 2,a:b0,b:b1,y:b3,x:b2,start:b7,guide:b8,back:b6,leftstick:b9,rightstick:b10,leftshoulder:b4,rightshoulder:b5,dpup:h0.1,dpleft:h0.8,dpdown:h0.4,dpright:h0.2,leftx:a0,lefty:a1,rightx:a3,righty:a4,lefttrigger:a2,righttrigger:a5,", "03000000ad1b000016f0000090040000,Mad Catz Xbox 360 Controller,a:b0,b:b1,y:b3,x:b2,start:b7,guide:b8,back:b6,leftstick:b9,rightstick:b10,leftshoulder:b4,rightshoulder:b5,dpup:h0.1,dpleft:h0.8,dpdown:h0.4,dpright:h0.2,leftx:a0,lefty:a1,rightx:a3,righty:a4,lefttrigger:a2,righttrigger:a5,", + "03000000ad1b00002ef0000090040000,Mad Catz Fightpad SFxT,a:b0,b:b1,y:b3,x:b2,start:b7,guide:b8,back:b6,leftshoulder:b4,rightshoulder:b5,dpup:h0.1,dpleft:h0.8,dpdown:h0.4,dpright:h0.2,lefttrigger:a2,righttrigger:a5,", "03000000ba2200002010000001010000,Jess Technology USB Game Controller,a:b2,b:b1,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:,leftshoulder:b4,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,righttrigger:b7,rightx:a3,righty:a2,start:b9,x:b3,y:b0,", + "03000000bd12000015d0000010010000,Tomee SNES USB Controller,x:b3,a:b2,b:b1,y:b0,back:b8,start:b9,leftshoulder:b4,rightshoulder:b5,leftx:a0,lefty:a1,", "03000000c9110000f055000011010000,HJC Game GAMEPAD,platform:Linux,x:b2,a:b0,b:b1,y:b3,back:b4,back:b8,start:b9,dpleft:h0.8,dpdown:h0.0,dpdown:h0.4,dpright:h0.0,dpright:h0.2,dpup:h0.0,dpup:h0.1,leftshoulder:h0.0,leftshoulder:b4,lefttrigger:b6,rightshoulder:b5,righttrigger:b7,leftstick:b10,rightstick:b11,leftx:a0,lefty:a1,rightx:a2,righty:a3,", "03000000d814000007cd000011010000,Toodles 2008 Chimp PC/PS3,a:b0,b:b1,y:b2,x:b3,start:b9,back:b8,leftshoulder:b4,rightshoulder:b5,leftx:a0,lefty:a1,lefttrigger:b6,righttrigger:b7,", "03000000d81400000862000011010000,HitBox (PS3/PC) Analog Mode,a:b1,b:b2,y:b3,x:b0,start:b12,guide:b9,back:b8,leftshoulder:b4,rightshoulder:b5,lefttrigger:b6,righttrigger:b7,leftx:a0,lefty:a1,", "03000000de280000ff11000001000000,Valve Streaming 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,", "03000000f0250000c183000010010000,Goodbetterbest Ltd USB Controller,x:b0,a:b1,b:b2,y:b3,back:b8,guide:b12,start:b9,dpleft:h0.8,dpdown:h0.0,dpdown:h0.4,dpright:h0.0,dpright:h0.2,dpup:h0.0,dpup:h0.1,leftshoulder:h0.0,leftshoulder:b4,lefttrigger:b6,rightshoulder:b5,righttrigger:b7,leftstick:b10,rightstick:b11,leftx:a0,lefty:a1,rightx:a2,righty:a3,", + "03000000fd0500000030000000010000,InterAct GoPad I-73000 (Fighting Game Layout),a:b3,b:b4,y:b1,x:b0,start:b7,back:b6,leftx:a0,lefty:a1,rightshoulder:b2,righttrigger:b5,", "03000000fd0500002a26000000010000,3dfx InterAct HammerHead FX,leftx:a0,lefty:a1,dpdown:h0.4,rightstick:b5,rightshoulder:b7,rightx:a2,start:b11,righty:a3,dpleft:h0.8,lefttrigger:b8,x:b0,dpup:h0.1,back:b10,leftstick:b2,leftshoulder:b6,y:b1,a:b3,dpright:h0.2,righttrigger:b9,b:b4,", "03000000ff1100003133000010010000,PC Game Controller,a:b2,b:b1,y:b0,x:b3,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:a2,righty:a3,lefttrigger:b6,righttrigger:b7,", "05000000010000000100000003000000,Nintendo Wiimote,a:b0,b:b1,y:b3,x:b2,start:b9,guide:b10,back:b8,leftstick:b11,rightstick:b12,leftshoulder:b4,rightshoulder:b5,dpup:h0.1,dpleft:h0.8,dpdown:h0.4,dpright:h0.2,leftx:a0,lefty:a1,rightx:a2,righty:a3,lefttrigger:b6,righttrigger:b7,", "05000000102800000900000000010000,8Bitdo SFC30 GamePad,x:b4,a:b1,b:b0,y:b3,back:b10,start:b11,leftshoulder:b6,rightshoulder:b7,leftx:a0,lefty:a1,", - "05000000362800000100000002010000,OUYA Game Controller,leftx:a0,lefty:a1,dpdown:b9,rightstick:b7,rightshoulder:b5,rightx:a3,start:b16,righty:a4,dpleft:b10,lefttrigger:b12,x:b1,dpup:b8,back:b14,leftstick:b6,leftshoulder:b4,y:b2,a:b0,dpright:b11,righttrigger:b13,b:b3,", - "05000000362800000100000003010000,OUYA Game Controller,leftx:a0,lefty:a1,dpdown:b9,rightstick:b7,rightshoulder:b5,rightx:a3,start:b16,righty:a4,dpleft:b10,lefttrigger:b12,x:b1,dpup:b8,back:b14,leftstick:b6,leftshoulder:b4,y:b2,a:b0,dpright:b11,righttrigger:b13,b:b3,", - "05000000362800000100000004010000,OUYA Game Controller,leftx:a0,lefty:a1,dpdown:b9,rightstick:b7,rightshoulder:b5,rightx:a3,start:b16,righty:a4,dpleft:b10,lefttrigger:b12,x:b1,dpup:b8,back:b14,leftstick:b6,leftshoulder:b4,y:b2,a:b0,dpright:b11,righttrigger:b13,b:b3,", - "05000000380700006652000025010000,Mad Catz C.T.R.L.R,x:b0,a:b1,b:b2,y:b3,back:b8,guide:b12,start:b9,dpleft:h0.8,dpdown:h0.4,dpright:h0.2,dpup:h0.1,leftshoulder:b4,lefttrigger:b6,rightshoulder:b5,righttrigger:b7,leftstick:b10,rightstick:b11,leftx:a0,lefty:a1,rightx:a2,righty:a3,", + "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,", + "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,", + "05000000380700006652000025010000,Mad Catz C.T.R.L.R ,x:b0,a:b1,b:b2,y:b3,back:b8,guide:b12,start:b9,dpleft:h0.8,dpdown:h0.4,dpright:h0.2,dpup:h0.1,leftshoulder:b4,lefttrigger:b6,rightshoulder:b5,righttrigger:b7,leftstick:b10,rightstick:b11,leftx:a0,lefty:a1,rightx:a2,righty:a3,", "0500000047532047616d657061640000,GameStop Gamepad,a:b0,b:b1,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:,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,", "050000004c0500006802000000010000,PS3 Controller (Bluetooth),a:b14,b:b13,y:b12,x:b15,start:b3,guide:b16,back:b0,leftstick:b1,rightstick:b2,leftshoulder:b10,rightshoulder:b11,dpup:b4,dpleft:b7,dpdown:b6,dpright:b5,leftx:a0,lefty:a1,rightx:a2,righty:a3,lefttrigger:b8,righttrigger:b9,", "050000004c050000c405000000010000,PS4 Controller (Bluetooth),a: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,", + "050000004c050000cc09000000010000,Sony DualShock 4 V2 BT,a:b1,b:b2,y:b3,x:b0,start:b9,guide:b12,back:b13,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:a2,righty:a5,lefttrigger:a3,righttrigger:a4,", "050000007e0500003003000001000000,Nintendo Wii U Pro Controller,a:b0,b:b1,x:b3,y:b2,back:b8,start:b9,guide:b10,leftshoulder:b4,rightshoulder:b5,leftstick:b11,rightstick:b12,leftx:a0,lefty:a1,rightx:a2,righty:a3,lefttrigger:b6,righttrigger:b7,dpup:b13,dpleft:b15,dpdown:b14,dpright:b16,", + "05000000a00500003232000001000000,8Bitdo Zero GamePad,a:b0,b:b1,x:b3,y:b4,back:b10,start:b11,leftshoulder:b6,rightshoulder:b7,leftx:a0,lefty:a1,", + "05000000ac0500003232000001000000,VR-BOX,a:b0,b:b1,x:b2,y:b3,start:b9,back:b8,leftstick:b10,rightstick:b11,leftshoulder:b6,rightshoulder:b7,dpup:h0.1,dpleft:h0.8,dpdown:h0.4,dpright:h0.2,leftx:a0,lefty:a1,rightx:a3,righty:a2,lefttrigger:b4,righttrigger:b5,", "05000000d6200000ad0d000001000000,Moga Pro,a:b0,b:b1,y:b3,x:b2,start:b6,leftstick:b7,rightstick:b8,leftshoulder:b4,rightshoulder:b5,dpup:h0.1,dpleft:h0.8,dpdown:h0.4,dpright:h0.2,leftx:a0,lefty:a1,rightx:a2,righty:a3,lefttrigger:a5,righttrigger:a4,", "060000004c0500006802000000010000,PS3 Controller (Bluetooth),a:b14,b:b13,y:b12,x:b15,start:b3,guide:b16,back:b0,leftstick:b1,rightstick:b2,leftshoulder:b10,rightshoulder:b11,dpup:b4,dpleft:b7,dpdown:b6,dpright:b5,leftx:a0,lefty:a1,rightx:a2,righty:a3,lefttrigger:b8,righttrigger:b9,", #endif @@ -989,6 +1029,8 @@ void InputDefault::parse_mapping(String p_mapping) { _THREAD_SAFE_METHOD_; JoyDeviceMapping mapping; + for (int i = 0; i < HAT_MAX; ++i) + mapping.hat[i].index = 1024 + i; Vector<String> entry = p_mapping.split(","); CharString uid; diff --git a/modules/gdscript/gd_parser.cpp b/modules/gdscript/gd_parser.cpp index 74a3d5e9e..009100cb3 100644 --- a/modules/gdscript/gd_parser.cpp +++ b/modules/gdscript/gd_parser.cpp @@ -3153,6 +3153,110 @@ void GDParser::_parse_class(ClassNode *p_class) { } } break; + case GDTokenizer::TK_PR_ENUM: { + //mutiple constant declarations.. + + int last_assign = -1; // Incremented by 1 right before the assingment. + String enum_name; + Dictionary enum_dict; + + tokenizer->advance(); + if (tokenizer->get_token() == GDTokenizer::TK_IDENTIFIER) { + enum_name = tokenizer->get_token_identifier(); + tokenizer->advance(); + } + if (tokenizer->get_token() != GDTokenizer::TK_CURLY_BRACKET_OPEN) { + _set_error("Expected '{' in enum declaration"); + return; + } + tokenizer->advance(); + + while (true) { + if (tokenizer->get_token() == GDTokenizer::TK_NEWLINE) { + + tokenizer->advance(); // Ignore newlines + } else if (tokenizer->get_token() == GDTokenizer::TK_CURLY_BRACKET_CLOSE) { + + tokenizer->advance(); + break; // End of enum + } else if (tokenizer->get_token() != GDTokenizer::TK_IDENTIFIER) { + + if (tokenizer->get_token() == GDTokenizer::TK_EOF) { + _set_error("Unexpected end of file."); + } else { + _set_error(String("Unexpected ") + GDTokenizer::get_token_name(tokenizer->get_token()) + ", expected identifier"); + } + + return; + } else { // tokenizer->get_token()==GDTokenizer::TK_IDENTIFIER + ClassNode::Constant constant; + + constant.identifier = tokenizer->get_token_identifier(); + + tokenizer->advance(); + + if (tokenizer->get_token() == GDTokenizer::TK_OP_ASSIGN) { + tokenizer->advance(); + + Node *subexpr = NULL; + + subexpr = _parse_and_reduce_expression(p_class, true, true); + if (!subexpr) { + if (_recover_from_completion()) { + break; + } + return; + } + + if (subexpr->type != Node::TYPE_CONSTANT) { + _set_error("Expected constant expression"); + } + + const ConstantNode *subexpr_const = static_cast<const ConstantNode *>(subexpr); + + if (subexpr_const->value.get_type() != Variant::INT) { + _set_error("Expected an int value for enum"); + } + + last_assign = subexpr_const->value; + + constant.expression = subexpr; + + } else { + last_assign = last_assign + 1; + ConstantNode *cn = alloc_node<ConstantNode>(); + cn->value = last_assign; + constant.expression = cn; + } + + if (tokenizer->get_token() == GDTokenizer::TK_COMMA) { + tokenizer->advance(); + } + + if (enum_name != "") { + const ConstantNode *cn = static_cast<const ConstantNode *>(constant.expression); + enum_dict[constant.identifier] = cn->value; + } + + p_class->constant_expressions.push_back(constant); + } + } + + if (enum_name != "") { + ClassNode::Constant enum_constant; + enum_constant.identifier = enum_name; + ConstantNode *cn = alloc_node<ConstantNode>(); + cn->value = enum_dict; + enum_constant.expression = cn; + p_class->constant_expressions.push_back(enum_constant); + } + + if (!_end_statement()) { + _set_error("Expected end of statement (enum)"); + return; + } + + } break; default: { diff --git a/modules/gdscript/gd_tokenizer.cpp b/modules/gdscript/gd_tokenizer.cpp index 3d9d49303..65156f0a9 100644 --- a/modules/gdscript/gd_tokenizer.cpp +++ b/modules/gdscript/gd_tokenizer.cpp @@ -95,6 +95,7 @@ const char *GDTokenizer::token_names[TK_MAX] = { "setget", "const", "var", + "enum", "preload", "assert", "yield", @@ -861,6 +862,7 @@ void GDTokenizerText::_advance() { { TK_PR_SIGNAL, "signal" }, { TK_PR_BREAKPOINT, "breakpoint" }, { TK_PR_CONST, "const" }, + { TK_PR_ENUM, "enum" }, //controlflow { TK_CF_IF, "if" }, { TK_CF_ELIF, "elif" }, diff --git a/modules/gdscript/gd_tokenizer.h b/modules/gdscript/gd_tokenizer.h index 1fe0910c3..84d15a56e 100644 --- a/modules/gdscript/gd_tokenizer.h +++ b/modules/gdscript/gd_tokenizer.h @@ -101,6 +101,7 @@ public: TK_PR_SETGET, TK_PR_CONST, TK_PR_VAR, + TK_PR_ENUM, TK_PR_PRELOAD, TK_PR_ASSERT, TK_PR_YIELD, diff --git a/platform/android/build.gradle.template b/platform/android/build.gradle.template index 24aab8e01..ec5bbb663 100644 --- a/platform/android/build.gradle.template +++ b/platform/android/build.gradle.template @@ -12,6 +12,7 @@ apply plugin: 'com.android.application' allprojects { repositories { + jcenter() mavenCentral() $$GRADLE_REPOSITORY_URLS$$ } diff --git a/platform/android/detect.py b/platform/android/detect.py index 2522a55aa..31551a5bc 100644 --- a/platform/android/detect.py +++ b/platform/android/detect.py @@ -175,6 +175,8 @@ def configure(env): if env['android_arch'] == 'x86': can_vectorize = True target_opts = ['-target', 'i686-none-linux-android'] + # The NDK adds this if targeting API < 21, so we can drop it when Godot targets it at least + env.Append(CPPFLAGS=['-mstackrealign']) elif env["android_arch"] == "armv6": can_vectorize = False target_opts = ['-target', 'armv6-none-linux-androideabi'] diff --git a/platform/windows/os_windows.cpp b/platform/windows/os_windows.cpp index 2b9574458..436c6ebf4 100644 --- a/platform/windows/os_windows.cpp +++ b/platform/windows/os_windows.cpp @@ -2176,6 +2176,9 @@ void OS_Windows::run() { if (!main_loop) return; + // Process all events before the main initialization so the cursor will get initialized properly + process_events(); // get rid of pending events + main_loop->init(); uint64_t last_ticks = get_ticks_usec(); diff --git a/platform/x11/os_x11.cpp b/platform/x11/os_x11.cpp index 5a829d62d..3975a6184 100644 --- a/platform/x11/os_x11.cpp +++ b/platform/x11/os_x11.cpp @@ -1282,8 +1282,12 @@ void OS_X11::process_xevents() { if (main_loop && mouse_mode != MOUSE_MODE_CAPTURED) main_loop->notification(MainLoop::NOTIFICATION_WM_MOUSE_ENTER); - if (input) + if (input) { + // Update mouse position. It is triggered before mouse motion. + Point2i pos(event.xmotion.x, event.xmotion.y); + input->set_mouse_pos(pos); input->set_mouse_in_window(true); + } } break; case FocusIn: minimized = false; @@ -1893,6 +1897,9 @@ void OS_X11::run() { if (!main_loop) return; + // Process all events before the main initialization so the cursor will get initialized properly + process_xevents(); // get rid of pending events + main_loop->init(); // uint64_t last_ticks=get_ticks_usec(); diff --git a/scene/2d/area_2d.cpp b/scene/2d/area_2d.cpp index fff399f8f..1a53f684e 100644 --- a/scene/2d/area_2d.cpp +++ b/scene/2d/area_2d.cpp @@ -380,6 +380,10 @@ void Area2D::_notification(int p_what) { switch (p_what) { + case NOTIFICATION_READY: { + + is_ready = true; + } break; case NOTIFICATION_EXIT_TREE: { monitoring_stored = monitoring; @@ -387,8 +391,8 @@ void Area2D::_notification(int p_what) { _clear_monitoring(); } break; case NOTIFICATION_ENTER_TREE: { - - set_enable_monitoring(monitoring_stored); + if (is_ready) + set_enable_monitoring(monitoring_stored); } break; } } @@ -646,7 +650,8 @@ Area2D::Area2D() monitorable = false; collision_mask = 1; layer_mask = 1; - monitoring_stored = true; + monitoring_stored = false; + is_ready = false; set_enable_monitoring(true); set_monitorable(true); } diff --git a/scene/2d/area_2d.h b/scene/2d/area_2d.h index 8e854d474..1860127cb 100644 --- a/scene/2d/area_2d.h +++ b/scene/2d/area_2d.h @@ -60,6 +60,7 @@ private: bool monitoring_stored; bool monitorable; bool locked; + bool is_ready; void _body_inout(int p_status, const RID &p_body, int p_instance, int p_body_shape, int p_area_shape); diff --git a/scene/2d/sample_player_2d.cpp b/scene/2d/sample_player_2d.cpp index 07f0e3fb3..5e958058a 100644 --- a/scene/2d/sample_player_2d.cpp +++ b/scene/2d/sample_player_2d.cpp @@ -130,8 +130,9 @@ SamplePlayer2D::VoiceID SamplePlayer2D::play(const String &p_sample, int p_voice Ref<Sample> sample = library->get_sample(p_sample); float vol_change = library->sample_get_volume_db(p_sample); float pitch_change = library->sample_get_pitch_scale(p_sample); + int priority = library->sample_get_priority(p_sample); - VoiceID vid = SpatialSound2DServer::get_singleton()->source_play_sample(get_source_rid(), sample->get_rid(), sample->get_mix_rate() * pitch_change, p_voice); + VoiceID vid = SpatialSound2DServer::get_singleton()->source_play_sample(get_source_rid(), sample->get_rid(), sample->get_mix_rate() * pitch_change, p_voice, priority); if (vol_change) SpatialSound2DServer::get_singleton()->source_voice_set_volume_scale_db(get_source_rid(), vid, vol_change); diff --git a/scene/2d/screen_button.cpp b/scene/2d/screen_button.cpp index 569303138..8335106d9 100644 --- a/scene/2d/screen_button.cpp +++ b/scene/2d/screen_button.cpp @@ -65,12 +65,14 @@ Ref<BitMap> TouchScreenButton::get_bitmask() const { void TouchScreenButton::set_shape(const Ref<Shape2D> &p_shape) { + if (shape.is_valid()) + shape->disconnect("changed", this, "update"); + shape = p_shape; - if (!is_inside_tree()) - return; - if (!get_tree()->is_editor_hint() && !get_tree()->is_debugging_collisions_hint()) - return; + if (shape.is_valid()) + shape->connect("changed", this, "update"); + update(); } @@ -82,11 +84,17 @@ Ref<Shape2D> TouchScreenButton::get_shape() const { void TouchScreenButton::set_shape_centered(bool p_shape_centered) { shape_centered = p_shape_centered; + update(); +} - if (!is_inside_tree()) - return; - if (!get_tree()->is_editor_hint() && !get_tree()->is_debugging_collisions_hint()) - return; +bool TouchScreenButton::is_shape_visible() const { + + return shape_visible; +} + +void TouchScreenButton::set_shape_visible(bool p_shape_visible) { + + shape_visible = p_shape_visible; update(); } @@ -118,6 +126,8 @@ void TouchScreenButton::_notification(int p_what) { draw_texture(texture, Point2()); } + if (!shape_visible) + return; if (!get_tree()->is_editor_hint() && !get_tree()->is_debugging_collisions_hint()) return; if (shape.is_valid()) { @@ -373,6 +383,9 @@ void TouchScreenButton::_bind_methods() { ObjectTypeDB::bind_method(_MD("set_shape_centered", "bool"), &TouchScreenButton::set_shape_centered); ObjectTypeDB::bind_method(_MD("is_shape_centered"), &TouchScreenButton::is_shape_centered); + ObjectTypeDB::bind_method(_MD("set_shape_visible", "bool"), &TouchScreenButton::set_shape_visible); + ObjectTypeDB::bind_method(_MD("is_shape_visible"), &TouchScreenButton::is_shape_visible); + ObjectTypeDB::bind_method(_MD("set_action", "action"), &TouchScreenButton::set_action); ObjectTypeDB::bind_method(_MD("get_action"), &TouchScreenButton::get_action); @@ -391,6 +404,7 @@ void TouchScreenButton::_bind_methods() { ADD_PROPERTY(PropertyInfo(Variant::OBJECT, "bitmask", PROPERTY_HINT_RESOURCE_TYPE, "BitMap"), _SCS("set_bitmask"), _SCS("get_bitmask")); ADD_PROPERTY(PropertyInfo(Variant::OBJECT, "shape", PROPERTY_HINT_RESOURCE_TYPE, "Shape2D"), _SCS("set_shape"), _SCS("get_shape")); ADD_PROPERTY(PropertyInfo(Variant::BOOL, "shape_centered"), _SCS("set_shape_centered"), _SCS("is_shape_centered")); + ADD_PROPERTY(PropertyInfo(Variant::BOOL, "shape_visible"), _SCS("set_shape_visible"), _SCS("is_shape_visible")); ADD_PROPERTY(PropertyInfo(Variant::BOOL, "passby_press"), _SCS("set_passby_press"), _SCS("is_passby_press_enabled")); ADD_PROPERTY(PropertyInfo(Variant::STRING, "action"), _SCS("set_action"), _SCS("get_action")); ADD_PROPERTY(PropertyInfo(Variant::INT, "visibility_mode", PROPERTY_HINT_ENUM, "Always,TouchScreen Only"), _SCS("set_visibility_mode"), _SCS("get_visibility_mode")); @@ -406,6 +420,7 @@ TouchScreenButton::TouchScreenButton() { passby_press = false; visibility = VISIBILITY_ALWAYS; shape_centered = true; + shape_visible = true; unit_rect = Ref<RectangleShape2D>(memnew(RectangleShape2D)); unit_rect->set_extents(Vector2(0.5, 0.5)); } diff --git a/scene/2d/screen_button.h b/scene/2d/screen_button.h index bbd69a35b..84be43144 100644 --- a/scene/2d/screen_button.h +++ b/scene/2d/screen_button.h @@ -50,6 +50,7 @@ private: Ref<BitMap> bitmask; Ref<Shape2D> shape; bool shape_centered; + bool shape_visible; Ref<RectangleShape2D> unit_rect; @@ -85,6 +86,9 @@ public: void set_shape_centered(bool p_shape_centered); bool is_shape_centered() const; + void set_shape_visible(bool p_shape_visible); + bool is_shape_visible() const; + void set_action(const String &p_action); String get_action() const; diff --git a/scene/3d/area.cpp b/scene/3d/area.cpp index f0dec5d2e..b4c63d629 100644 --- a/scene/3d/area.cpp +++ b/scene/3d/area.cpp @@ -227,6 +227,10 @@ void Area::_clear_monitoring() { Object *obj = ObjectDB::get_instance(E->key()); Node *node = obj ? obj->cast_to<Node>() : NULL; ERR_CONTINUE(!node); + + node->disconnect(SceneStringNames::get_singleton()->enter_tree, this, SceneStringNames::get_singleton()->_body_enter_tree); + node->disconnect(SceneStringNames::get_singleton()->exit_tree, this, SceneStringNames::get_singleton()->_body_exit_tree); + if (!E->get().in_tree) continue; @@ -236,9 +240,6 @@ void Area::_clear_monitoring() { } emit_signal(SceneStringNames::get_singleton()->body_exit, obj); - - node->disconnect(SceneStringNames::get_singleton()->enter_tree, this, SceneStringNames::get_singleton()->_body_enter_tree); - node->disconnect(SceneStringNames::get_singleton()->exit_tree, this, SceneStringNames::get_singleton()->_body_exit_tree); } } @@ -253,6 +254,10 @@ void Area::_clear_monitoring() { Object *obj = ObjectDB::get_instance(E->key()); Node *node = obj ? obj->cast_to<Node>() : NULL; ERR_CONTINUE(!node); + + node->disconnect(SceneStringNames::get_singleton()->enter_tree, this, SceneStringNames::get_singleton()->_area_enter_tree); + node->disconnect(SceneStringNames::get_singleton()->exit_tree, this, SceneStringNames::get_singleton()->_area_exit_tree); + if (!E->get().in_tree) continue; @@ -262,16 +267,27 @@ void Area::_clear_monitoring() { } emit_signal(SceneStringNames::get_singleton()->area_exit, obj); - - node->disconnect(SceneStringNames::get_singleton()->enter_tree, this, SceneStringNames::get_singleton()->_area_enter_tree); - node->disconnect(SceneStringNames::get_singleton()->exit_tree, this, SceneStringNames::get_singleton()->_area_exit_tree); } } } void Area::_notification(int p_what) { - if (p_what == NOTIFICATION_EXIT_TREE) { - _clear_monitoring(); + switch (p_what) { + + case NOTIFICATION_READY: { + + is_ready = true; + } break; + case NOTIFICATION_EXIT_TREE: { + + monitoring_stored = monitoring; + set_enable_monitoring(false); + _clear_monitoring(); + } break; + case NOTIFICATION_ENTER_TREE: { + if (is_ready) + set_enable_monitoring(monitoring_stored); + } break; } } @@ -627,6 +643,8 @@ Area::Area() monitoring = false; collision_mask = 1; layer_mask = 1; + monitoring_stored = false; + is_ready = false; set_ray_pickable(false); set_enable_monitoring(true); set_monitorable(true); diff --git a/scene/3d/area.h b/scene/3d/area.h index 75c66c88b..718243fdb 100644 --- a/scene/3d/area.h +++ b/scene/3d/area.h @@ -57,8 +57,10 @@ private: uint32_t layer_mask; int priority; bool monitoring; + bool monitoring_stored; bool monitorable; bool locked; + bool is_ready; void _body_inout(int p_status, const RID &p_body, int p_instance, int p_body_shape, int p_area_shape); diff --git a/scene/3d/spatial_sample_player.cpp b/scene/3d/spatial_sample_player.cpp index c2860b4f7..25873bcfb 100644 --- a/scene/3d/spatial_sample_player.cpp +++ b/scene/3d/spatial_sample_player.cpp @@ -130,6 +130,7 @@ SpatialSamplePlayer::VoiceID SpatialSamplePlayer::play(const String &p_sample, i Ref<Sample> sample = library->get_sample(p_sample); float vol_change = library->sample_get_volume_db(p_sample); float pitch_change = library->sample_get_pitch_scale(p_sample); + int priority = library->sample_get_priority(p_sample); VoiceID vid = SpatialSoundServer::get_singleton()->source_play_sample(get_source_rid(), sample->get_rid(), sample->get_mix_rate() * pitch_change, p_voice); if (vol_change) diff --git a/scene/animation/tween.cpp b/scene/animation/tween.cpp index 394e152b3..fd3abc543 100644 --- a/scene/animation/tween.cpp +++ b/scene/animation/tween.cpp @@ -609,6 +609,7 @@ void Tween::_tween_process(float p_delta) { _apply_tween_value(data, result); if (data.finish) { + _apply_tween_value(data, data.final_val); emit_signal("tween_complete", object, data.key); // not repeat mode, remove completed action if (!repeat) diff --git a/scene/audio/sample_player.cpp b/scene/audio/sample_player.cpp index dfccc5c7c..416d560b7 100644 --- a/scene/audio/sample_player.cpp +++ b/scene/audio/sample_player.cpp @@ -187,6 +187,7 @@ void SamplePlayer::Voice::clear() { reverb_room = REVERB_HALL; reverb_send = 0; active = false; + priority = 0; } SamplePlayer::Voice::~Voice() { @@ -214,13 +215,28 @@ SamplePlayer::VoiceID SamplePlayer::play(const String &p_name, bool unique) { Ref<Sample> sample = library->get_sample(p_name); float vol_change = library->sample_get_volume_db(p_name); float pitch_change = library->sample_get_pitch_scale(p_name); + int priority = library->sample_get_priority(p_name); last_check++; - last_id = (last_id + 1) % voices.size(); + + const int num_voices = voices.size(); + bool found = false; + for (int i = 0; i < num_voices; i++) { + const int candidate = (last_id + 1 + i) % num_voices; + if (voices[candidate].priority <= priority) { + found = true; + last_id = candidate; + break; + } + } + + if (!found) + return INVALID_VOICE_ID; Voice &v = voices[last_id]; v.clear(); + v.priority = priority; v.mix_rate = sample->get_mix_rate() * (_default.pitch_scale * pitch_change); v.sample_mix_rate = sample->get_mix_rate(); v.check = last_check; diff --git a/scene/audio/sample_player.h b/scene/audio/sample_player.h index 0f026a085..392679f05 100644 --- a/scene/audio/sample_player.h +++ b/scene/audio/sample_player.h @@ -74,6 +74,7 @@ private: uint32_t check; bool active; + int priority; int sample_mix_rate; int mix_rate; float volume; diff --git a/scene/main/scene_main_loop.cpp b/scene/main/scene_main_loop.cpp index 79a6b79f9..e4a863b90 100644 --- a/scene/main/scene_main_loop.cpp +++ b/scene/main/scene_main_loop.cpp @@ -327,6 +327,10 @@ void SceneTree::input_text(const String &p_text) { root_lock--; } +bool SceneTree::is_input_handled() { + return input_handled; +} + void SceneTree::input_event(const InputEvent &p_event) { if (is_editor_hint() && (p_event.type == InputEvent::JOYSTICK_MOTION || p_event.type == InputEvent::JOYSTICK_BUTTON)) @@ -1556,6 +1560,7 @@ void SceneTree::_bind_methods() { ObjectTypeDB::bind_method(_MD("set_pause", "enable"), &SceneTree::set_pause); ObjectTypeDB::bind_method(_MD("is_paused"), &SceneTree::is_paused); ObjectTypeDB::bind_method(_MD("set_input_as_handled"), &SceneTree::set_input_as_handled); + ObjectTypeDB::bind_method(_MD("is_input_handled"), &SceneTree::is_input_handled); ObjectTypeDB::bind_method(_MD("get_node_count"), &SceneTree::get_node_count); ObjectTypeDB::bind_method(_MD("get_frame"), &SceneTree::get_frame); diff --git a/scene/main/scene_main_loop.h b/scene/main/scene_main_loop.h index 8b20c8dbf..9a658f197 100644 --- a/scene/main/scene_main_loop.h +++ b/scene/main/scene_main_loop.h @@ -262,6 +262,7 @@ public: void quit(); void set_input_as_handled(); + bool is_input_handled(); _FORCE_INLINE_ float get_fixed_process_time() const { return fixed_process_time; } _FORCE_INLINE_ float get_idle_process_time() const { return idle_process_time; } diff --git a/scene/main/timer.cpp b/scene/main/timer.cpp index 1010e76ba..3fb0d1e25 100644 --- a/scene/main/timer.cpp +++ b/scene/main/timer.cpp @@ -50,8 +50,7 @@ void Timer::_notification(int p_what) { if (time_left < 0) { if (!one_shot) - //time_left=wait_time+time_left; - time_left = wait_time; + time_left += wait_time; else stop(); @@ -66,8 +65,7 @@ void Timer::_notification(int p_what) { if (time_left < 0) { if (!one_shot) - //time_left = wait_time + time_left; - time_left = wait_time; + time_left += wait_time; else stop(); emit_signal("timeout"); diff --git a/scene/main/viewport.cpp b/scene/main/viewport.cpp index d37f95641..2dd12a6bb 100644 --- a/scene/main/viewport.cpp +++ b/scene/main/viewport.cpp @@ -1347,7 +1347,7 @@ void Viewport::_vp_input(const InputEvent &p_ev) { return; #ifdef TOOLS_ENABLED - if (get_tree()->is_editor_hint() && get_tree()->get_edited_scene_root()->is_a_parent_of(this)) { + if (get_tree()->is_editor_hint() && get_tree()->get_edited_scene_root() && get_tree()->get_edited_scene_root()->is_a_parent_of(this)) { return; } #endif @@ -1371,7 +1371,7 @@ void Viewport::_vp_unhandled_input(const InputEvent &p_ev) { if (disable_input) return; #ifdef TOOLS_ENABLED - if (get_tree()->is_editor_hint() && get_tree()->get_edited_scene_root()->is_a_parent_of(this)) { + if (get_tree()->is_editor_hint() && get_tree()->get_edited_scene_root() && get_tree()->get_edited_scene_root()->is_a_parent_of(this)) { return; } #endif diff --git a/scene/resources/sample_library.cpp b/scene/resources/sample_library.cpp index e6ccdceb3..752b988d8 100644 --- a/scene/resources/sample_library.cpp +++ b/scene/resources/sample_library.cpp @@ -49,6 +49,7 @@ bool SampleLibrary::_set(const StringName &p_name, const Variant &p_value) { sd.sample = d["sample"]; sd.pitch_scale = d["pitch"]; sd.db = d["db"]; + sd.priority = d.has("priority") ? d["priority"] : Variant(0); // For libraries before priority was introduced } sample_map[name] = sd; @@ -70,6 +71,7 @@ bool SampleLibrary::_get(const StringName &p_name, Variant &r_ret) const { d["sample"] = sample_map[name].sample; d["pitch"] = sample_map[name].pitch_scale; d["db"] = sample_map[name].db; + d["priority"] = sample_map[name].priority; r_ret = d; } else { return false; @@ -170,6 +172,19 @@ float SampleLibrary::sample_get_pitch_scale(const StringName &p_name) const { return sample_map[p_name].pitch_scale; } +void SampleLibrary::sample_set_priority(const StringName &p_name, int p_priority) { + + ERR_FAIL_COND(!sample_map.has(p_name)); + sample_map[p_name].priority = p_priority; +} + +int SampleLibrary::sample_get_priority(const StringName &p_name) const { + + ERR_FAIL_COND_V(!sample_map.has(p_name), 0); + + return sample_map[p_name].priority; +} + Array SampleLibrary::_get_sample_list() const { List<StringName> snames; @@ -199,6 +214,9 @@ void SampleLibrary::_bind_methods() { ObjectTypeDB::bind_method(_MD("sample_set_pitch_scale", "name", "pitch"), &SampleLibrary::sample_set_pitch_scale); ObjectTypeDB::bind_method(_MD("sample_get_pitch_scale", "name"), &SampleLibrary::sample_get_pitch_scale); + + ObjectTypeDB::bind_method(_MD("sample_set_priority", "name", "priority"), &SampleLibrary::sample_set_priority); + ObjectTypeDB::bind_method(_MD("sample_get_priority", "name"), &SampleLibrary::sample_get_priority); } SampleLibrary::SampleLibrary() { diff --git a/scene/resources/sample_library.h b/scene/resources/sample_library.h index 1928e55bb..d8008106b 100644 --- a/scene/resources/sample_library.h +++ b/scene/resources/sample_library.h @@ -42,10 +42,12 @@ class SampleLibrary : public Resource { Ref<Sample> sample; float db; float pitch_scale; + int priority; SampleData() { db = 0; pitch_scale = 1; + priority = 0; } }; @@ -67,6 +69,8 @@ public: float sample_get_volume_db(const StringName &p_name) const; void sample_set_pitch_scale(const StringName &p_name, float p_pitch); float sample_get_pitch_scale(const StringName &p_name) const; + void sample_set_priority(const StringName &p_name, int p_priority); + int sample_get_priority(const StringName &p_name) const; Ref<Sample> get_sample(const StringName &p_name) const; void get_sample_list(List<StringName> *p_samples) const; void remove_sample(const StringName &p_name); diff --git a/scene/scene_string_names.cpp b/scene/scene_string_names.cpp index 458f5c220..18873808e 100644 --- a/scene/scene_string_names.cpp +++ b/scene/scene_string_names.cpp @@ -32,6 +32,9 @@ SceneStringNames *SceneStringNames::singleton = NULL; SceneStringNames::SceneStringNames() { + _estimate_cost = StaticCString::create("_estimate_cost"); + _compute_cost = StaticCString::create("_compute_cost"); + resized = StaticCString::create("resized"); dot = StaticCString::create("."); doubledot = StaticCString::create(".."); diff --git a/scene/scene_string_names.h b/scene/scene_string_names.h index 6d0382ba7..e18128fe4 100644 --- a/scene/scene_string_names.h +++ b/scene/scene_string_names.h @@ -49,6 +49,9 @@ class SceneStringNames { public: _FORCE_INLINE_ static SceneStringNames *get_singleton() { return singleton; } + StringName _estimate_cost; + StringName _compute_cost; + StringName resized; StringName dot; StringName doubledot; diff --git a/servers/spatial_sound/spatial_sound_server_sw.cpp b/servers/spatial_sound/spatial_sound_server_sw.cpp index 6a10b175e..410159d23 100644 --- a/servers/spatial_sound/spatial_sound_server_sw.cpp +++ b/servers/spatial_sound/spatial_sound_server_sw.cpp @@ -97,6 +97,7 @@ SpatialSoundServerSW::Source::Voice::Voice() { active = false; restart = false; + priority = 0; pitch_scale = 1.0; volume_scale = 0.0; voice_rid = AudioServer::get_singleton()->voice_create(); @@ -390,7 +391,7 @@ void SpatialSoundServerSW::source_set_audio_stream(RID p_source, AudioServer::Au } //null to unset -SpatialSoundServer::SourceVoiceID SpatialSoundServerSW::source_play_sample(RID p_source, RID p_sample, int p_mix_rate, int p_voice) { +SpatialSoundServer::SourceVoiceID SpatialSoundServerSW::source_play_sample(RID p_source, RID p_sample, int p_mix_rate, int p_voice, int p_priority) { Source *source = source_owner.get(p_source); ERR_FAIL_COND_V(!source, SOURCE_INVALID_VOICE); @@ -398,16 +399,35 @@ SpatialSoundServer::SourceVoiceID SpatialSoundServerSW::source_play_sample(RID p int to_play = 0; if (p_voice == SOURCE_NEXT_VOICE) { - to_play = source->last_voice + 1; - if (to_play >= source->voices.size()) - to_play = 0; - + const int num_voices = source->voices.size(); + bool free_found = false; + int lowest_priority_voice = 0; + int lowest_priority = 0x7FFFFFFF; + for (int i = 0; i < num_voices; i++) { + const int candidate = (source->last_voice + 1 + i) % num_voices; + const Source::Voice &v = source->voices[candidate]; + if (!v.active && !v.restart) { + free_found = true; + to_play = candidate; + break; + } + if (v.priority < lowest_priority) { + lowest_priority = v.priority; + lowest_priority_voice = candidate; + } + } + if (!free_found) + to_play = (source->last_voice + 1) % num_voices; } else to_play = p_voice; ERR_FAIL_INDEX_V(to_play, source->voices.size(), SOURCE_INVALID_VOICE); + if ((source->voices[to_play].active || source->voices[to_play].restart) && source->voices[to_play].priority > p_priority) + return SOURCE_INVALID_VOICE; + source->voices[to_play].restart = true; + source->voices[to_play].priority = p_priority; source->voices[to_play].sample_rid = p_sample; source->voices[to_play].sample_mix_rate = p_mix_rate; source->voices[to_play].pitch_scale = 1; diff --git a/servers/spatial_sound/spatial_sound_server_sw.h b/servers/spatial_sound/spatial_sound_server_sw.h index e05b78a94..54f276ede 100644 --- a/servers/spatial_sound/spatial_sound_server_sw.h +++ b/servers/spatial_sound/spatial_sound_server_sw.h @@ -101,6 +101,7 @@ class SpatialSoundServerSW : public SpatialSoundServer { RID sample_rid; bool active; bool restart; + int priority; float pitch_scale; float volume_scale; int sample_mix_rate; @@ -226,7 +227,7 @@ public: virtual float source_get_param(RID p_source, SourceParam p_param) const; virtual void source_set_audio_stream(RID p_source, AudioServer::AudioStream *p_stream); //null to unset - virtual SourceVoiceID source_play_sample(RID p_source, RID p_sample, int p_mix_rate, int p_voice = SOURCE_NEXT_VOICE); + virtual SourceVoiceID source_play_sample(RID p_source, RID p_sample, int p_mix_rate, int p_voice = SOURCE_NEXT_VOICE, int p_priority = 0); /* VOICES */ virtual void source_voice_set_pitch_scale(RID p_source, SourceVoiceID p_voice, float p_pitch_scale); virtual void source_voice_set_volume_scale_db(RID p_source, SourceVoiceID p_voice, float p_volume); diff --git a/servers/spatial_sound_2d/spatial_sound_2d_server_sw.cpp b/servers/spatial_sound_2d/spatial_sound_2d_server_sw.cpp index 2c6614da8..6f0ae8910 100644 --- a/servers/spatial_sound_2d/spatial_sound_2d_server_sw.cpp +++ b/servers/spatial_sound_2d/spatial_sound_2d_server_sw.cpp @@ -94,6 +94,7 @@ SpatialSound2DServerSW::Source::Voice::Voice() { active = false; restart = false; + priority = 0; pitch_scale = 1.0; volume_scale = 0.0; voice_rid = AudioServer::get_singleton()->voice_create(); @@ -387,7 +388,7 @@ void SpatialSound2DServerSW::source_set_audio_stream(RID p_source, AudioServer:: } //null to unset -SpatialSound2DServer::SourceVoiceID SpatialSound2DServerSW::source_play_sample(RID p_source, RID p_sample, int p_mix_rate, int p_voice) { +SpatialSound2DServer::SourceVoiceID SpatialSound2DServerSW::source_play_sample(RID p_source, RID p_sample, int p_mix_rate, int p_voice, int p_priority) { Source *source = source_owner.get(p_source); ERR_FAIL_COND_V(!source, SOURCE_INVALID_VOICE); @@ -395,16 +396,35 @@ SpatialSound2DServer::SourceVoiceID SpatialSound2DServerSW::source_play_sample(R int to_play = 0; if (p_voice == SOURCE_NEXT_VOICE) { - to_play = source->last_voice + 1; - if (to_play >= source->voices.size()) - to_play = 0; - + const int num_voices = source->voices.size(); + bool free_found = false; + int lowest_priority_voice = 0; + int lowest_priority = 0x7FFFFFFF; + for (int i = 0; i < num_voices; i++) { + const int candidate = (source->last_voice + 1 + i) % num_voices; + const Source::Voice &v = source->voices[candidate]; + if (!v.active && !v.restart) { + free_found = true; + to_play = candidate; + break; + } + if (v.priority < lowest_priority) { + lowest_priority = v.priority; + lowest_priority_voice = candidate; + } + } + if (!free_found) + to_play = (source->last_voice + 1) % num_voices; } else to_play = p_voice; ERR_FAIL_INDEX_V(to_play, source->voices.size(), SOURCE_INVALID_VOICE); + if ((source->voices[to_play].active || source->voices[to_play].restart) && source->voices[to_play].priority > p_priority) + return SOURCE_INVALID_VOICE; + source->voices[to_play].restart = true; + source->voices[to_play].priority = p_priority; source->voices[to_play].sample_rid = p_sample; source->voices[to_play].sample_mix_rate = p_mix_rate; source->voices[to_play].pitch_scale = 1; diff --git a/servers/spatial_sound_2d/spatial_sound_2d_server_sw.h b/servers/spatial_sound_2d/spatial_sound_2d_server_sw.h index acc70e69c..de4cfee68 100644 --- a/servers/spatial_sound_2d/spatial_sound_2d_server_sw.h +++ b/servers/spatial_sound_2d/spatial_sound_2d_server_sw.h @@ -100,6 +100,7 @@ class SpatialSound2DServerSW : public SpatialSound2DServer { RID sample_rid; bool active; bool restart; + int priority; float pitch_scale; float volume_scale; int sample_mix_rate; @@ -225,7 +226,7 @@ public: virtual float source_get_param(RID p_source, SourceParam p_param) const; virtual void source_set_audio_stream(RID p_source, AudioServer::AudioStream *p_stream); //null to unset - virtual SourceVoiceID source_play_sample(RID p_source, RID p_sample, int p_mix_rate, int p_voice = SOURCE_NEXT_VOICE); + virtual SourceVoiceID source_play_sample(RID p_source, RID p_sample, int p_mix_rate, int p_voice = SOURCE_NEXT_VOICE, int p_priority = 0); /* VOICES */ virtual void source_voice_set_pitch_scale(RID p_source, SourceVoiceID p_voice, float p_pitch_scale); virtual void source_voice_set_volume_scale_db(RID p_source, SourceVoiceID p_voice, float p_volume); diff --git a/servers/spatial_sound_2d_server.h b/servers/spatial_sound_2d_server.h index 7c577e8be..08833287e 100644 --- a/servers/spatial_sound_2d_server.h +++ b/servers/spatial_sound_2d_server.h @@ -117,7 +117,7 @@ public: virtual float source_get_param(RID p_source, SourceParam p_param) const = 0; virtual void source_set_audio_stream(RID p_source, AudioServer::AudioStream *p_stream) = 0; //null to unset - virtual SourceVoiceID source_play_sample(RID p_source, RID p_sample, int p_mix_rate, int p_voice = SOURCE_NEXT_VOICE) = 0; + virtual SourceVoiceID source_play_sample(RID p_source, RID p_sample, int p_mix_rate, int p_voice = SOURCE_NEXT_VOICE, int p_priority = 0) = 0; //voices virtual void source_voice_set_pitch_scale(RID p_source, SourceVoiceID p_voice, float p_pitch_scale) = 0; virtual void source_voice_set_volume_scale_db(RID p_source, SourceVoiceID p_voice, float p_volume_db) = 0; diff --git a/servers/spatial_sound_server.h b/servers/spatial_sound_server.h index 72d3ae0af..be37f9b50 100644 --- a/servers/spatial_sound_server.h +++ b/servers/spatial_sound_server.h @@ -121,7 +121,7 @@ public: virtual float source_get_param(RID p_source, SourceParam p_param) const = 0; virtual void source_set_audio_stream(RID p_source, AudioServer::AudioStream *p_stream) = 0; //null to unset - virtual SourceVoiceID source_play_sample(RID p_source, RID p_sample, int p_mix_rate, int p_voice = SOURCE_NEXT_VOICE) = 0; + virtual SourceVoiceID source_play_sample(RID p_source, RID p_sample, int p_mix_rate, int p_voice = SOURCE_NEXT_VOICE, int p_priority = 0) = 0; //voices virtual void source_voice_set_pitch_scale(RID p_source, SourceVoiceID p_voice, float p_pitch_scale) = 0; virtual void source_voice_set_volume_scale_db(RID p_source, SourceVoiceID p_voice, float p_volume_db) = 0; |
