Qt/input: ignore button press values unless they increase

This commit is contained in:
Megamouse 2024-08-08 03:04:21 +02:00
parent 28781d9bfb
commit 16a6915525
11 changed files with 214 additions and 100 deletions

View File

@ -220,11 +220,14 @@ cfg_pad* PadHandlerBase::get_config(const std::string& pad_id)
return nullptr; return nullptr;
} }
PadHandlerBase::connection PadHandlerBase::get_next_button_press(const std::string& pad_id, const pad_callback& callback, const pad_fail_callback& fail_callback, bool get_blacklist, const std::vector<std::string>& /*buttons*/) PadHandlerBase::connection PadHandlerBase::get_next_button_press(const std::string& pad_id, const pad_callback& callback, const pad_fail_callback& fail_callback, bool first_call, bool get_blacklist, const std::vector<std::string>& /*buttons*/)
{ {
if (get_blacklist) if (get_blacklist)
blacklist.clear(); blacklist.clear();
if (first_call)
min_button_values.clear();
auto device = get_device(pad_id); auto device = get_device(pad_id);
const connection status = update_connection(device); const connection status = update_connection(device);
@ -254,11 +257,20 @@ PadHandlerBase::connection PadHandlerBase::get_next_button_press(const std::stri
for (const auto& [keycode, name] : button_list) for (const auto& [keycode, name] : button_list)
{ {
const u16& value = data[keycode];
if (!get_blacklist && blacklist.contains(keycode)) if (!get_blacklist && blacklist.contains(keycode))
continue; continue;
const u16 value = data[keycode];
u16& min_value = min_button_values[keycode];
if (first_call || value < min_value)
{
min_value = value;
continue;
}
constexpr u16 touch_threshold = static_cast<u16>(255 * 0.9f);
const bool is_trigger = get_is_left_trigger(device, keycode) || get_is_right_trigger(device, keycode); const bool is_trigger = get_is_left_trigger(device, keycode) || get_is_right_trigger(device, keycode);
const bool is_stick = !is_trigger && (get_is_left_stick(device, keycode) || get_is_right_stick(device, keycode)); const bool is_stick = !is_trigger && (get_is_left_stick(device, keycode) || get_is_right_stick(device, keycode));
const bool is_touch_motion = !is_trigger && !is_stick && get_is_touch_pad_motion(device, keycode); const bool is_touch_motion = !is_trigger && !is_stick && get_is_touch_pad_motion(device, keycode);
@ -266,21 +278,30 @@ PadHandlerBase::connection PadHandlerBase::get_next_button_press(const std::stri
if ((is_trigger && (value > m_trigger_threshold)) || if ((is_trigger && (value > m_trigger_threshold)) ||
(is_stick && (value > m_thumb_threshold)) || (is_stick && (value > m_thumb_threshold)) ||
(is_button && (value > 0)) || (is_button && (value > button_press_threshold)) ||
(is_touch_motion && (value > 255 * 0.9))) (is_touch_motion && (value > touch_threshold)))
{ {
if (get_blacklist) if (get_blacklist)
{ {
blacklist.insert(keycode); blacklist.insert(keycode);
input_log.error("%s Calibration: Added key [ %d = %s ] to blacklist. Value = %d", m_type, keycode, name, value); input_log.error("%s Calibration: Added key [ %d = %s ] to blacklist. Value = %d", m_type, keycode, name, value);
continue;
} }
else if (value > pressed_button.value)
const u16 diff = std::abs(min_value - value);
if (diff > button_press_threshold && value > pressed_button.value)
{ {
pressed_button = { .value = value, .name = name }; pressed_button = { .value = value, .name = name };
} }
} }
} }
if (first_call)
{
return connection::no_data;
}
if (get_blacklist) if (get_blacklist)
{ {
if (blacklist.empty()) if (blacklist.empty())

View File

@ -111,13 +111,14 @@ protected:
}; };
static constexpr u32 MAX_GAMEPADS = 7; static constexpr u32 MAX_GAMEPADS = 7;
static constexpr u16 button_press_threshold = 50;
std::array<bool, MAX_GAMEPADS> last_connection_status{{ false, false, false, false, false, false, false }}; std::array<bool, MAX_GAMEPADS> last_connection_status{{ false, false, false, false, false, false, false }};
std::string m_name_string; std::string m_name_string;
usz m_max_devices = 0; usz m_max_devices = 0;
int m_trigger_threshold = 0; u32 m_trigger_threshold = 0;
int m_thumb_threshold = 0; u32 m_thumb_threshold = 0;
bool b_has_led = false; bool b_has_led = false;
bool b_has_rgb = false; bool b_has_rgb = false;
@ -132,6 +133,7 @@ protected:
std::array<cfg_pad, MAX_GAMEPADS> m_pad_configs; std::array<cfg_pad, MAX_GAMEPADS> m_pad_configs;
std::vector<pad_ensemble> m_bindings; std::vector<pad_ensemble> m_bindings;
std::unordered_map<u32, std::string> button_list; std::unordered_map<u32, std::string> button_list;
std::unordered_map<u32, u16> min_button_values;
std::set<u32> blacklist; std::set<u32> blacklist;
static std::set<u32> narrow_set(const std::set<u64>& src); static std::set<u32> narrow_set(const std::set<u64>& src);
@ -280,7 +282,7 @@ public:
// Binds a Pad to a device // Binds a Pad to a device
virtual bool bindPadToDevice(std::shared_ptr<Pad> pad); virtual bool bindPadToDevice(std::shared_ptr<Pad> pad);
virtual void init_config(cfg_pad* cfg) = 0; virtual void init_config(cfg_pad* cfg) = 0;
virtual connection get_next_button_press(const std::string& padId, const pad_callback& callback, const pad_fail_callback& fail_callback, bool get_blacklist, const std::vector<std::string>& buttons = {}); virtual connection get_next_button_press(const std::string& padId, const pad_callback& callback, const pad_fail_callback& fail_callback, bool first_call, bool get_blacklist, const std::vector<std::string>& buttons);
virtual void get_motion_sensors(const std::string& pad_id, const motion_callback& callback, const motion_fail_callback& fail_callback, motion_preview_values preview_values, const std::array<AnalogSensor, 4>& sensors); virtual void get_motion_sensors(const std::string& pad_id, const motion_callback& callback, const motion_fail_callback& fail_callback, motion_preview_values preview_values, const std::array<AnalogSensor, 4>& sensors);
virtual std::unordered_map<u32, std::string> get_motion_axis_list() const { return {}; } virtual std::unordered_map<u32, std::string> get_motion_axis_list() const { return {}; }

View File

@ -297,11 +297,14 @@ std::shared_ptr<evdev_joystick_handler::EvdevDevice> evdev_joystick_handler::get
return evdev_device; return evdev_device;
} }
PadHandlerBase::connection evdev_joystick_handler::get_next_button_press(const std::string& padId, const pad_callback& callback, const pad_fail_callback& fail_callback, bool get_blacklist, const std::vector<std::string>& buttons) PadHandlerBase::connection evdev_joystick_handler::get_next_button_press(const std::string& padId, const pad_callback& callback, const pad_fail_callback& fail_callback, bool first_call, bool get_blacklist, const std::vector<std::string>& buttons)
{ {
if (get_blacklist) if (get_blacklist)
m_blacklist.clear(); m_blacklist.clear();
if (first_call)
m_min_button_values.clear();
// Get our evdev device // Get our evdev device
std::shared_ptr<EvdevDevice> device = get_evdev_device(padId); std::shared_ptr<EvdevDevice> device = get_evdev_device(padId);
if (!device || !device->device) if (!device || !device->device)
@ -310,6 +313,7 @@ PadHandlerBase::connection evdev_joystick_handler::get_next_button_press(const s
fail_callback(padId); fail_callback(padId);
return connection::disconnected; return connection::disconnected;
} }
libevdev* dev = device->device; libevdev* dev = device->device;
// Try to fetch all new events from the joystick. // Try to fetch all new events from the joystick.
@ -377,8 +381,8 @@ PadHandlerBase::connection evdev_joystick_handler::get_next_button_press(const s
preview_values[5] = find_value(buttons[9]) - find_value(buttons[8]); // Right Stick Y preview_values[5] = find_value(buttons[9]) - find_value(buttons[8]); // Right Stick Y
} }
// return if nothing new has happened. ignore this to get the current state for blacklist // return if nothing new has happened. ignore this to get the current state for blacklist or first_call
if (!get_blacklist && !has_new_event) if (!get_blacklist && !first_call && !has_new_event)
{ {
if (callback) if (callback)
callback(0, "", padId, 0, preview_values); callback(0, "", padId, 0, preview_values);
@ -391,6 +395,17 @@ PadHandlerBase::connection evdev_joystick_handler::get_next_button_press(const s
std::string name; std::string name;
} pressed_button{}; } pressed_button{};
const auto set_button_press = [this, &pressed_button](const u16 value, const std::string& name)
{
const u16 min_value = m_min_button_values.contains(name) ? m_min_button_values[name] : 0;
const u16 diff = std::abs(min_value - value);
if (diff > button_press_threshold && value > pressed_button.value)
{
pressed_button = { .value = value, .name = name };
}
};
const bool is_xbox_360_controller = padId.find("Xbox 360") != umax; const bool is_xbox_360_controller = padId.find("Xbox 360") != umax;
const bool is_sony_controller = !is_xbox_360_controller && padId.find("Sony") != umax; const bool is_sony_controller = !is_xbox_360_controller && padId.find("Sony") != umax;
const bool is_sony_guitar = is_sony_controller && padId.find("Guitar") != umax; const bool is_sony_guitar = is_sony_controller && padId.find("Guitar") != umax;
@ -409,18 +424,25 @@ PadHandlerBase::connection evdev_joystick_handler::get_next_button_press(const s
continue; continue;
const u16 value = data[code].first; const u16 value = data[code].first;
if (value > 0) u16& min_value = m_min_button_values[name];
if (first_call || value < min_value)
{ {
if (get_blacklist) min_value = value;
{ return;
m_blacklist.insert(name);
evdev_log.error("Evdev Calibration: Added button [ %d = %s = %s ] to blacklist. Value = %d", code, libevdev_event_code_get_name(EV_KEY, code), name, value);
}
else if (value > pressed_button.value)
{
pressed_button = { value, name };
}
} }
if (value <= 0)
continue;
if (get_blacklist)
{
m_blacklist.insert(name);
evdev_log.error("Evdev Calibration: Added button [ %d = %s = %s ] to blacklist. Value = %d", code, libevdev_event_code_get_name(EV_KEY, code), name, value);
continue;
}
set_button_press(value, name);
} }
for (const auto& [code, name] : axis_list) for (const auto& [code, name] : axis_list)
@ -432,20 +454,27 @@ PadHandlerBase::connection evdev_joystick_handler::get_next_button_press(const s
continue; continue;
const u16 value = data[code].first; const u16 value = data[code].first;
if (value > 0 && value >= m_thumb_threshold) u16& min_value = m_min_button_values[name];
if (first_call || value < min_value)
{ {
if (get_blacklist) min_value = value;
{ return;
const int min = libevdev_get_abs_minimum(dev, code);
const int max = libevdev_get_abs_maximum(dev, code);
m_blacklist.insert(name);
evdev_log.error("Evdev Calibration: Added axis [ %d = %s = %s ] to blacklist. [ Value = %d ] [ Min = %d ] [ Max = %d ]", code, libevdev_event_code_get_name(EV_ABS, code), name, value, min, max);
}
else if (value > pressed_button.value)
{
pressed_button = { value, name };
}
} }
if (value <= m_thumb_threshold)
continue;
if (get_blacklist)
{
const int min = libevdev_get_abs_minimum(dev, code);
const int max = libevdev_get_abs_maximum(dev, code);
m_blacklist.insert(name);
evdev_log.error("Evdev Calibration: Added axis [ %d = %s = %s ] to blacklist. [ Value = %d ] [ Min = %d ] [ Max = %d ]", code, libevdev_event_code_get_name(EV_ABS, code), name, value, min, max);
continue;
}
set_button_press(value, name);
} }
for (const auto& [code, name] : rev_axis_list) for (const auto& [code, name] : rev_axis_list)
@ -457,20 +486,32 @@ PadHandlerBase::connection evdev_joystick_handler::get_next_button_press(const s
continue; continue;
const u16 value = data[code].first; const u16 value = data[code].first;
if (value > 0 && value >= m_thumb_threshold) u16& min_value = m_min_button_values[name];
if (first_call || value < min_value)
{ {
if (get_blacklist) min_value = value;
{ return;
const int min = libevdev_get_abs_minimum(dev, code);
const int max = libevdev_get_abs_maximum(dev, code);
m_blacklist.insert(name);
evdev_log.error("Evdev Calibration: Added rev axis [ %d = %s = %s ] to blacklist. [ Value = %d ] [ Min = %d ] [ Max = %d ]", code, libevdev_event_code_get_name(EV_ABS, code), name, value, min, max);
}
else if (value > pressed_button.value)
{
pressed_button = { value, name };
}
} }
if (value <= m_thumb_threshold)
continue;
if (get_blacklist)
{
const int min = libevdev_get_abs_minimum(dev, code);
const int max = libevdev_get_abs_maximum(dev, code);
m_blacklist.insert(name);
evdev_log.error("Evdev Calibration: Added rev axis [ %d = %s = %s ] to blacklist. [ Value = %d ] [ Min = %d ] [ Max = %d ]", code, libevdev_event_code_get_name(EV_ABS, code), name, value, min, max);
continue;
}
set_button_press(value, name);
}
if (first_call)
{
return connection::no_data;
} }
if (get_blacklist) if (get_blacklist)

View File

@ -407,7 +407,7 @@ public:
bool Init() override; bool Init() override;
std::vector<pad_list_entry> list_devices() override; std::vector<pad_list_entry> list_devices() override;
bool bindPadToDevice(std::shared_ptr<Pad> pad) override; bool bindPadToDevice(std::shared_ptr<Pad> pad) override;
connection get_next_button_press(const std::string& padId, const pad_callback& callback, const pad_fail_callback& fail_callback, bool get_blacklist = false, const std::vector<std::string>& buttons = {}) override; connection get_next_button_press(const std::string& padId, const pad_callback& callback, const pad_fail_callback& fail_callback, bool first_call, bool get_blacklist, const std::vector<std::string>& buttons) override;
void get_motion_sensors(const std::string& padId, const motion_callback& callback, const motion_fail_callback& fail_callback, motion_preview_values preview_values, const std::array<AnalogSensor, 4>& sensors) override; void get_motion_sensors(const std::string& padId, const motion_callback& callback, const motion_fail_callback& fail_callback, motion_preview_values preview_values, const std::array<AnalogSensor, 4>& sensors) override;
std::unordered_map<u32, std::string> get_motion_axis_list() const override; std::unordered_map<u32, std::string> get_motion_axis_list() const override;
void SetPadData(const std::string& padId, u8 player_id, u8 large_motor, u8 small_motor, s32 r, s32 g, s32 b, bool player_led, bool battery_led, u32 battery_led_brightness) override; void SetPadData(const std::string& padId, u8 player_id, u8 large_motor, u8 small_motor, s32 r, s32 g, s32 b, bool player_led, bool battery_led, u32 battery_led_brightness) override;
@ -425,6 +425,7 @@ private:
positive_axis m_pos_axis_config; positive_axis m_pos_axis_config;
std::set<u32> m_positive_axis; std::set<u32> m_positive_axis;
std::set<std::string> m_blacklist; std::set<std::string> m_blacklist;
std::unordered_map<std::string, u16> m_min_button_values;
std::unordered_map<std::string, std::shared_ptr<evdev_joystick_handler::EvdevDevice>> m_settings_added; std::unordered_map<std::string, std::shared_ptr<evdev_joystick_handler::EvdevDevice>> m_settings_added;
std::unordered_map<std::string, std::shared_ptr<evdev_joystick_handler::EvdevDevice>> m_motion_settings_added; std::unordered_map<std::string, std::shared_ptr<evdev_joystick_handler::EvdevDevice>> m_motion_settings_added;
std::shared_ptr<EvdevDevice> m_dev; std::shared_ptr<EvdevDevice> m_dev;

View File

@ -84,7 +84,7 @@ public:
void init_config(cfg_pad* cfg) override; void init_config(cfg_pad* cfg) override;
std::vector<pad_list_entry> list_devices() override; std::vector<pad_list_entry> list_devices() override;
connection get_next_button_press(const std::string& /*padId*/, const pad_callback& /*callback*/, const pad_fail_callback& /*fail_callback*/, bool /*get_blacklist*/ = false, const std::vector<std::string>& /*buttons*/ = {}) override { return connection::connected; } connection get_next_button_press(const std::string& /*padId*/, const pad_callback& /*callback*/, const pad_fail_callback& /*fail_callback*/, bool /*first_call*/, bool /*get_blacklist*/, const std::vector<std::string>& /*buttons*/) override { return connection::connected; }
bool bindPadToDevice(std::shared_ptr<Pad> pad) override; bool bindPadToDevice(std::shared_ptr<Pad> pad) override;
void process() override; void process() override;

View File

@ -221,11 +221,14 @@ std::array<std::set<u32>, PadHandlerBase::button::button_count> mm_joystick_hand
return mapping; return mapping;
} }
PadHandlerBase::connection mm_joystick_handler::get_next_button_press(const std::string& padId, const pad_callback& callback, const pad_fail_callback& fail_callback, bool get_blacklist, const std::vector<std::string>& buttons) PadHandlerBase::connection mm_joystick_handler::get_next_button_press(const std::string& padId, const pad_callback& callback, const pad_fail_callback& fail_callback, bool first_call, bool get_blacklist, const std::vector<std::string>& buttons)
{ {
if (get_blacklist) if (get_blacklist)
m_blacklist.clear(); m_blacklist.clear();
if (first_call)
m_min_button_values.clear();
if (!Init()) if (!Init())
{ {
if (fail_callback) if (fail_callback)
@ -280,46 +283,69 @@ PadHandlerBase::connection mm_joystick_handler::get_next_button_press(const std:
std::string name; std::string name;
} pressed_button{}; } pressed_button{};
const auto set_button_press = [this, &pressed_button](const u16 value, const u64& keycode, const std::string& name)
{
const u16 min_value = m_min_button_values.contains(keycode) ? m_min_button_values[keycode] : 0;
const u16 diff = std::abs(min_value - value);
if (diff > button_press_threshold && value > pressed_button.value)
{
pressed_button = { .value = value, .name = name };
}
};
for (const auto& [keycode, name] : axis_list) for (const auto& [keycode, name] : axis_list)
{ {
u16 value = data[keycode];
if (!get_blacklist && m_blacklist.contains(keycode)) if (!get_blacklist && m_blacklist.contains(keycode))
continue; continue;
if (value > m_thumb_threshold) const u16 value = data[keycode];
u16& min_value = m_min_button_values[keycode];
if (first_call || value < min_value)
{ {
if (get_blacklist) min_value = value;
{ continue;
m_blacklist.insert(keycode);
input_log.error("MMJOY Calibration: Added axis [ %d = %s ] to blacklist. Value = %d", keycode, name, value);
}
else if (value > pressed_button.value)
{
pressed_button = { .value = value, .name = name };
}
} }
if (value <= m_thumb_threshold)
continue;
if (get_blacklist)
{
m_blacklist.insert(keycode);
input_log.error("MMJOY Calibration: Added axis [ %d = %s ] to blacklist. Value = %d", keycode, name, value);
continue;
}
set_button_press(value, keycode, name);
} }
for (const auto& [keycode, name] : pov_list) for (const auto& [keycode, name] : pov_list)
{ {
const u16 value = data[keycode];
if (!get_blacklist && m_blacklist.contains(keycode)) if (!get_blacklist && m_blacklist.contains(keycode))
continue; continue;
if (value > 0) const u16 value = data[keycode];
u16& min_value = m_min_button_values[keycode];
if (first_call || value < min_value)
{ {
if (get_blacklist) min_value = value;
{ continue;
m_blacklist.insert(keycode);
input_log.error("MMJOY Calibration: Added pov [ %d = %s ] to blacklist. Value = %d", keycode, name, value);
}
else if (value > pressed_button.value)
{
pressed_button = { .value = value, .name = name };
}
} }
if (value <= 0)
continue;
if (get_blacklist)
{
m_blacklist.insert(keycode);
input_log.error("MMJOY Calibration: Added pov [ %d = %s ] to blacklist. Value = %d", keycode, name, value);
continue;
}
set_button_press(value, keycode, name);
} }
for (const auto& [keycode, name] : button_list) for (const auto& [keycode, name] : button_list)
@ -331,19 +357,30 @@ PadHandlerBase::connection mm_joystick_handler::get_next_button_press(const std:
continue; continue;
const u16 value = data[keycode]; const u16 value = data[keycode];
u16& min_value = m_min_button_values[keycode];
if (value > 0) if (first_call || value < min_value)
{ {
if (get_blacklist) min_value = value;
{ continue;
m_blacklist.insert(keycode);
input_log.error("MMJOY Calibration: Added button [ %d = %s ] to blacklist. Value = %d", keycode, name, value);
}
else if (value > pressed_button.value)
{
pressed_button = { .value = value, .name = name };
}
} }
if (value <= 0)
continue;
if (get_blacklist)
{
m_blacklist.insert(keycode);
input_log.error("MMJOY Calibration: Added button [ %d = %s ] to blacklist. Value = %d", keycode, name, value);
continue;
}
set_button_press(value, keycode, name);
}
if (first_call)
{
return connection::no_data;
} }
if (get_blacklist) if (get_blacklist)

View File

@ -114,7 +114,7 @@ public:
bool Init() override; bool Init() override;
std::vector<pad_list_entry> list_devices() override; std::vector<pad_list_entry> list_devices() override;
connection get_next_button_press(const std::string& padId, const pad_callback& callback, const pad_fail_callback& fail_callback, bool get_blacklist = false, const std::vector<std::string>& buttons = {}) override; connection get_next_button_press(const std::string& padId, const pad_callback& callback, const pad_fail_callback& fail_callback, bool first_call, bool get_blacklist, const std::vector<std::string>& buttons) override;
void init_config(cfg_pad* cfg) override; void init_config(cfg_pad* cfg) override;
private: private:
@ -127,6 +127,7 @@ private:
bool m_is_init = false; bool m_is_init = false;
std::set<u64> m_blacklist; std::set<u64> m_blacklist;
std::unordered_map<u64, u16> m_min_button_values;
std::map<std::string, std::shared_ptr<MMJOYDevice>> m_devices; std::map<std::string, std::shared_ptr<MMJOYDevice>> m_devices;
template <typename T> template <typename T>

View File

@ -762,14 +762,14 @@ void sdl_pad_handler::get_motion_sensors(const std::string& pad_id, const motion
PadHandlerBase::get_motion_sensors(pad_id, callback, fail_callback, preview_values, sensors); PadHandlerBase::get_motion_sensors(pad_id, callback, fail_callback, preview_values, sensors);
} }
PadHandlerBase::connection sdl_pad_handler::get_next_button_press(const std::string& padId, const pad_callback& callback, const pad_fail_callback& fail_callback, bool get_blacklist, const std::vector<std::string>& buttons) PadHandlerBase::connection sdl_pad_handler::get_next_button_press(const std::string& padId, const pad_callback& callback, const pad_fail_callback& fail_callback, bool first_call, bool get_blacklist, const std::vector<std::string>& buttons)
{ {
if (!m_is_init) if (!m_is_init)
return connection::disconnected; return connection::disconnected;
SDL_PumpEvents(); SDL_PumpEvents();
return PadHandlerBase::get_next_button_press(padId, callback, fail_callback, get_blacklist, buttons); return PadHandlerBase::get_next_button_press(padId, callback, fail_callback, first_call, get_blacklist, buttons);
} }
void sdl_pad_handler::apply_pad_data(const pad_ensemble& binding) void sdl_pad_handler::apply_pad_data(const pad_ensemble& binding)

View File

@ -128,7 +128,7 @@ public:
void SetPadData(const std::string& padId, u8 player_id, u8 large_motor, u8 small_motor, s32 r, s32 g, s32 b, bool player_led, bool battery_led, u32 battery_led_brightness) override; void SetPadData(const std::string& padId, u8 player_id, u8 large_motor, u8 small_motor, s32 r, s32 g, s32 b, bool player_led, bool battery_led, u32 battery_led_brightness) override;
u32 get_battery_level(const std::string& padId) override; u32 get_battery_level(const std::string& padId) override;
void get_motion_sensors(const std::string& pad_id, const motion_callback& callback, const motion_fail_callback& fail_callback, motion_preview_values preview_values, const std::array<AnalogSensor, 4>& sensors) override; void get_motion_sensors(const std::string& pad_id, const motion_callback& callback, const motion_fail_callback& fail_callback, motion_preview_values preview_values, const std::array<AnalogSensor, 4>& sensors) override;
connection get_next_button_press(const std::string& padId, const pad_callback& callback, const pad_fail_callback& fail_callback, bool get_blacklist, const std::vector<std::string>& buttons) override; connection get_next_button_press(const std::string& padId, const pad_callback& callback, const pad_fail_callback& fail_callback, bool first_call, bool get_blacklist, const std::vector<std::string>& buttons) override;
private: private:
// pseudo 'controller id' to keep track of unique controllers // pseudo 'controller id' to keep track of unique controllers

View File

@ -450,7 +450,7 @@ void pad_settings_dialog::InitButtons()
}); });
// Enable Button Remapping // Enable Button Remapping
const auto callback = [this](PadHandlerBase::connection status, u16 val, std::string name, std::string pad_name, u32 battery_level, pad_preview_values preview_values) const auto callback = [this](PadHandlerBase::connection status, u32 button_id, u16 val, std::string name, std::string pad_name, u32 battery_level, pad_preview_values preview_values)
{ {
SwitchPadInfo(pad_name, true); SwitchPadInfo(pad_name, true);
@ -487,7 +487,7 @@ void pad_settings_dialog::InitButtons()
cfg_log.notice("get_next_button_press: %s device %s button %s pressed with value %d", m_handler->m_type, pad_name, name, val); cfg_log.notice("get_next_button_press: %s device %s button %s pressed with value %d", m_handler->m_type, pad_name, name, val);
if (m_button_id > button_ids::id_pad_begin && m_button_id < button_ids::id_pad_end) if (m_button_id > button_ids::id_pad_begin && m_button_id < button_ids::id_pad_end && m_button_id == button_id)
{ {
m_cfg_entries[m_button_id].insert_key(name, m_enable_multi_binding); m_cfg_entries[m_button_id].insert_key(name, m_enable_multi_binding);
ReactivateButtons(); ReactivateButtons();
@ -544,7 +544,7 @@ void pad_settings_dialog::InitButtons()
} }
else else
{ {
callback(data.status, data.val, std::move(data.name), std::move(data.pad_name), data.battery_level, std::move(data.preview_values)); callback(data.status, data.button_id, data.val, std::move(data.name), std::move(data.pad_name), data.battery_level, std::move(data.preview_values));
} }
} }
}); });
@ -555,6 +555,8 @@ void pad_settings_dialog::InitButtons()
// Use thread to get button input // Use thread to get button input
m_input_thread = std::make_unique<named_thread<std::function<void()>>>("Pad Settings Thread", [this]() m_input_thread = std::make_unique<named_thread<std::function<void()>>>("Pad Settings Thread", [this]()
{ {
u32 button_id = button_ids::id_pad_begin; // Used to check if this is the first call during a remap
while (thread_ctrl::state() != thread_state::aborting) while (thread_ctrl::state() != thread_state::aborting)
{ {
thread_ctrl::wait_for(1000); thread_ctrl::wait_for(1000);
@ -587,8 +589,13 @@ void pad_settings_dialog::InitButtons()
m_cfg_entries[button_ids::id_pad_rstick_up].keys m_cfg_entries[button_ids::id_pad_rstick_up].keys
}; };
// Check if this is the first call during a remap
const u32 new_button_id = m_button_id;
const bool is_mapping = new_button_id > button_ids::id_pad_begin && new_button_id < button_ids::id_pad_end;
const bool first_call = std::exchange(button_id, new_button_id) != button_id && is_mapping;
const PadHandlerBase::connection status = m_handler->get_next_button_press(m_device_name, const PadHandlerBase::connection status = m_handler->get_next_button_press(m_device_name,
[this](u16 val, std::string name, std::string pad_name, u32 battery_level, pad_preview_values preview_values) [this, button_id](u16 val, std::string name, std::string pad_name, u32 battery_level, pad_preview_values preview_values)
{ {
std::lock_guard lock(m_input_mutex); std::lock_guard lock(m_input_mutex);
m_input_callback_data.val = val; m_input_callback_data.val = val;
@ -598,15 +605,17 @@ void pad_settings_dialog::InitButtons()
m_input_callback_data.preview_values = std::move(preview_values); m_input_callback_data.preview_values = std::move(preview_values);
m_input_callback_data.has_new_data = true; m_input_callback_data.has_new_data = true;
m_input_callback_data.status = PadHandlerBase::connection::connected; m_input_callback_data.status = PadHandlerBase::connection::connected;
m_input_callback_data.button_id = button_id;
}, },
[this](std::string pad_name) [this, button_id](std::string pad_name)
{ {
std::lock_guard lock(m_input_mutex); std::lock_guard lock(m_input_mutex);
m_input_callback_data.pad_name = std::move(pad_name); m_input_callback_data.pad_name = std::move(pad_name);
m_input_callback_data.has_new_data = true; m_input_callback_data.has_new_data = true;
m_input_callback_data.status = PadHandlerBase::connection::disconnected; m_input_callback_data.status = PadHandlerBase::connection::disconnected;
m_input_callback_data.button_id = button_id;
}, },
false, buttons); first_call, false, buttons);
if (status == PadHandlerBase::connection::no_data) if (status == PadHandlerBase::connection::no_data)
{ {
@ -614,6 +623,7 @@ void pad_settings_dialog::InitButtons()
m_input_callback_data.pad_name = m_device_name; m_input_callback_data.pad_name = m_device_name;
m_input_callback_data.has_new_data = true; m_input_callback_data.has_new_data = true;
m_input_callback_data.status = status; m_input_callback_data.status = status;
m_input_callback_data.button_id = button_id;
} }
} }
}); });
@ -631,7 +641,7 @@ void pad_settings_dialog::RefreshPads()
} }
std::lock_guard lock(m_handler_mutex); std::lock_guard lock(m_handler_mutex);
const PadHandlerBase::connection status = m_handler->get_next_button_press(info.name, nullptr, nullptr, false); const PadHandlerBase::connection status = m_handler->get_next_button_press(info.name, nullptr, nullptr, false, false, {});
switch_pad_info(i, info, status != PadHandlerBase::connection::disconnected); switch_pad_info(i, info, status != PadHandlerBase::connection::disconnected);
} }
} }
@ -896,7 +906,7 @@ void pad_settings_dialog::keyPressEvent(QKeyEvent *keyEvent)
if (m_button_id <= button_ids::id_pad_begin || m_button_id >= button_ids::id_pad_end) if (m_button_id <= button_ids::id_pad_begin || m_button_id >= button_ids::id_pad_end)
{ {
cfg_log.error("Pad Settings: Handler Type: %d, Unknown button ID: %d", static_cast<int>(m_handler->m_type), m_button_id); cfg_log.error("Pad Settings: Handler Type: %d, Unknown button ID: %d", static_cast<int>(m_handler->m_type), m_button_id.load());
} }
else else
{ {
@ -923,7 +933,7 @@ void pad_settings_dialog::mouseReleaseEvent(QMouseEvent* event)
if (m_button_id <= button_ids::id_pad_begin || m_button_id >= button_ids::id_pad_end) if (m_button_id <= button_ids::id_pad_begin || m_button_id >= button_ids::id_pad_end)
{ {
cfg_log.error("Pad Settings: Handler Type: %d, Unknown button ID: %d", static_cast<int>(m_handler->m_type), m_button_id); cfg_log.error("Pad Settings: Handler Type: %d, Unknown button ID: %d", static_cast<int>(m_handler->m_type), m_button_id.load());
} }
else else
{ {
@ -950,7 +960,7 @@ void pad_settings_dialog::wheelEvent(QWheelEvent *event)
if (m_button_id <= button_ids::id_pad_begin || m_button_id >= button_ids::id_pad_end) if (m_button_id <= button_ids::id_pad_begin || m_button_id >= button_ids::id_pad_end)
{ {
cfg_log.error("Pad Settings: Handler Type: %d, Unknown button ID: %d", static_cast<int>(m_handler->m_type), m_button_id); cfg_log.error("Pad Settings: Handler Type: %d, Unknown button ID: %d", static_cast<int>(m_handler->m_type), m_button_id.load());
return; return;
} }
@ -1010,7 +1020,7 @@ void pad_settings_dialog::mouseMoveEvent(QMouseEvent* event)
if (m_button_id <= button_ids::id_pad_begin || m_button_id >= button_ids::id_pad_end) if (m_button_id <= button_ids::id_pad_begin || m_button_id >= button_ids::id_pad_end)
{ {
cfg_log.error("Pad Settings: Handler Type: %d, Unknown button ID: %d", static_cast<int>(m_handler->m_type), m_button_id); cfg_log.error("Pad Settings: Handler Type: %d, Unknown button ID: %d", static_cast<int>(m_handler->m_type), m_button_id.load());
} }
else else
{ {
@ -1311,7 +1321,7 @@ void pad_settings_dialog::OnPadButtonClicked(int id)
case button_ids::id_blacklist: case button_ids::id_blacklist:
{ {
std::lock_guard lock(m_handler_mutex); std::lock_guard lock(m_handler_mutex);
[[maybe_unused]] const PadHandlerBase::connection status = m_handler->get_next_button_press(m_device_name, nullptr, nullptr, true); [[maybe_unused]] const PadHandlerBase::connection status = m_handler->get_next_button_press(m_device_name, nullptr, nullptr, false, true, {});
return; return;
} }
default: default:

View File

@ -124,7 +124,7 @@ private:
// Button Mapping // Button Mapping
QButtonGroup* m_pad_buttons = nullptr; QButtonGroup* m_pad_buttons = nullptr;
u32 m_button_id = id_pad_begin; atomic_t<u32> m_button_id = button_ids::id_pad_begin;
std::map<int /*id*/, pad_button /*info*/> m_cfg_entries; std::map<int /*id*/, pad_button /*info*/> m_cfg_entries;
std::map<int /*id*/, std::string> m_duplicate_buttons; std::map<int /*id*/, std::string> m_duplicate_buttons;
@ -166,6 +166,7 @@ private:
{ {
PadHandlerBase::connection status = PadHandlerBase::connection::disconnected; PadHandlerBase::connection status = PadHandlerBase::connection::disconnected;
bool has_new_data = false; bool has_new_data = false;
u32 button_id = button_ids::id_pad_begin;
u16 val = 0; u16 val = 0;
std::string name; std::string name;
std::string pad_name; std::string pad_name;