Fix Input::remove_joy_mapping

Erasing a joypad mapping can invalidate other attached joypads and the fallback mapping guid
This commit is contained in:
MJacred
2024-12-15 13:39:29 +01:00
parent 4364ed6ccd
commit 40832387ce
3 changed files with 31 additions and 3 deletions

View File

@ -1712,18 +1712,46 @@ void Input::add_joy_mapping(const String &p_mapping, bool p_update_existing) {
}
void Input::remove_joy_mapping(const String &p_guid) {
int fallback_mapping_offset = 0; // Fix the fallback, if we invalidate its index.
for (int i = map_db.size() - 1; i >= 0; i--) {
if (p_guid == map_db[i].uid) {
map_db.remove_at(i);
if (i == fallback_mapping) {
fallback_mapping = -1;
WARN_PRINT_ONCE(vformat("Removed fallback joypad input mapping \"%s\". This could lead to joypads not working as intended.", p_guid));
} else if (i < fallback_mapping) {
fallback_mapping_offset--;
}
}
}
if (fallback_mapping_offset < 0) {
fallback_mapping += fallback_mapping_offset;
}
for (KeyValue<int, Joypad> &E : joy_names) {
Joypad &joy = E.value;
int mapping;
if (joy.uid == p_guid) {
_set_joypad_mapping(joy, -1);
mapping = -1;
} else if (joy.mapping == (fallback_mapping - fallback_mapping_offset)) {
// Fix the mapping for the joypad that uses an outdated fallback index.
mapping = fallback_mapping;
} else {
// Re-validate the joypad's correct mapping. Fix it if necessary.
mapping = fallback_mapping;
for (int i = 0; i < map_db.size(); i++) {
if (joy.uid == map_db[i].uid) {
mapping = i;
}
}
}
_set_joypad_mapping(joy, mapping);
}
}
void Input::_set_joypad_mapping(Joypad &p_js, int p_map_index) {
if (p_map_index != fallback_mapping && p_map_index >= 0 && p_map_index < map_db.size() && p_js.uid != "__XINPUT_DEVICE__") {

View File

@ -184,7 +184,7 @@ private:
HashSet<uint32_t> ignored_device_ids;
int fallback_mapping = -1;
int fallback_mapping = -1; // Index of the guid in map_db.
CursorShape default_shape = CURSOR_ARROW;

View File

@ -311,7 +311,7 @@
<return type="void" />
<param index="0" name="guid" type="String" />
<description>
Removes all mappings from the internal database that match the given GUID.
Removes all mappings from the internal database that match the given GUID. All currently connected joypads that use this GUID will become unmapped.
</description>
</method>
<method name="set_accelerometer">