|
|
@@ -1709,15 +1709,23 @@ void Input::add_joy_mapping(const String &p_mapping, bool p_update_existing) {
|
|
|
}
|
|
|
|
|
|
void Input::remove_joy_mapping(const String &p_guid) {
|
|
|
- int count = 0; // The amount of removals performed.
|
|
|
- int index_removed = -1; // The smallest index where an entry was removed.
|
|
|
+ // One GUID can exist multiple times in `map_db`, and
|
|
|
+ // `add_joy_mapping` can choose not to update the existing mapping,
|
|
|
+ // so the indices can be all over the place. Therefore we need to remember them.
|
|
|
+ Vector<int> removed_idx;
|
|
|
+ int min_removed_idx = -1;
|
|
|
+ int max_removed_idx = -1;
|
|
|
int fallback_mapping_offset = 0;
|
|
|
|
|
|
for (int i = map_db.size() - 1; i >= 0; i--) {
|
|
|
if (p_guid == map_db[i].uid) {
|
|
|
map_db.remove_at(i);
|
|
|
- index_removed = i;
|
|
|
- count++;
|
|
|
+
|
|
|
+ if (max_removed_idx == -1) {
|
|
|
+ max_removed_idx = i;
|
|
|
+ }
|
|
|
+ min_removed_idx = i;
|
|
|
+ removed_idx.push_back(i);
|
|
|
|
|
|
if (i < fallback_mapping) {
|
|
|
fallback_mapping_offset++;
|
|
|
@@ -1728,33 +1736,44 @@ void Input::remove_joy_mapping(const String &p_guid) {
|
|
|
}
|
|
|
}
|
|
|
|
|
|
- if (index_removed == -1) {
|
|
|
- return; // Not found.
|
|
|
+ if (min_removed_idx == -1) {
|
|
|
+ return; // Nothing removed.
|
|
|
}
|
|
|
|
|
|
if (fallback_mapping > 0) {
|
|
|
- // Fixing the shifted index.
|
|
|
+ // Fix the shifted index.
|
|
|
fallback_mapping -= fallback_mapping_offset;
|
|
|
}
|
|
|
|
|
|
+ int removed_idx_size = removed_idx.size();
|
|
|
+
|
|
|
+ // Update joypad mapping references: some
|
|
|
+ // * should use the fallback_mapping (if set; if not, they get unmapped), or
|
|
|
+ // * need their mapping reference fixed, because the deletion(s) offset them.
|
|
|
for (KeyValue<int, Joypad> &E : joy_names) {
|
|
|
Joypad &joy = E.value;
|
|
|
+ if (joy.mapping < min_removed_idx) {
|
|
|
+ continue; // Not affected.
|
|
|
+ }
|
|
|
|
|
|
- if (joy.uid == p_guid) {
|
|
|
- _set_joypad_mapping(joy, fallback_mapping);
|
|
|
- } else if (joy.mapping > index_removed) {
|
|
|
- if (count == 1) {
|
|
|
- // The map_db update offset this joypad's mapping reference, update it:
|
|
|
- _set_joypad_mapping(joy, joy.mapping - 1);
|
|
|
- } else {
|
|
|
- // Re-validate the joypad's correct mapping. Fix it if necessary.
|
|
|
- int 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);
|
|
|
+ if (joy.mapping > max_removed_idx) {
|
|
|
+ _set_joypad_mapping(joy, joy.mapping - removed_idx_size);
|
|
|
+ continue; // Simple offset fix.
|
|
|
+ }
|
|
|
+
|
|
|
+ // removed_idx is in reverse order (ie. high to low), because the first loop is in reverse order.
|
|
|
+ for (int i = 0; i < removed_idx.size(); i++) {
|
|
|
+ if (removed_idx[i] == joy.mapping) {
|
|
|
+ // Set to fallback_mapping, if defined, else unmap the joypad.
|
|
|
+ // Currently, the fallback_mapping is only set internally, and only for Android.
|
|
|
+ _set_joypad_mapping(joy, fallback_mapping);
|
|
|
+ break;
|
|
|
+ }
|
|
|
+ if (removed_idx[i] < joy.mapping) {
|
|
|
+ // Complex offset fix:
|
|
|
+ // This mapping was shifted by `(removed_idx_size - i)` deletions.
|
|
|
+ _set_joypad_mapping(joy, joy.mapping - (removed_idx_size - i));
|
|
|
+ break;
|
|
|
}
|
|
|
}
|
|
|
}
|