From 853c3f9e39c28cadf88965fbc2549d2f3f077388 Mon Sep 17 00:00:00 2001 From: Unknown Date: Thu, 30 Nov 2017 00:43:52 +0100 Subject: [PATCH] Qt/Input: implement blacklist to Filter Noise in pad dialog --- rpcs3/Emu/Io/PadHandler.h | 2 +- rpcs3/ds4_pad_handler.cpp | 134 ++++++++++++-------------- rpcs3/ds4_pad_handler.h | 6 +- rpcs3/evdev_joystick_handler.cpp | 70 ++++++++++++-- rpcs3/evdev_joystick_handler.h | 3 +- rpcs3/mm_joystick_handler.cpp | 64 +++++++++--- rpcs3/mm_joystick_handler.h | 3 +- rpcs3/rpcs3qt/pad_settings_dialog.cpp | 11 ++- rpcs3/rpcs3qt/pad_settings_dialog.h | 1 + rpcs3/rpcs3qt/pad_settings_dialog.ui | 31 ++++-- rpcs3/xinput_pad_handler.cpp | 92 +++++++++--------- rpcs3/xinput_pad_handler.h | 4 +- 12 files changed, 263 insertions(+), 158 deletions(-) diff --git a/rpcs3/Emu/Io/PadHandler.h b/rpcs3/Emu/Io/PadHandler.h index 43d9619fb7..fcef61e425 100644 --- a/rpcs3/Emu/Io/PadHandler.h +++ b/rpcs3/Emu/Io/PadHandler.h @@ -546,7 +546,7 @@ public: bool has_deadzones() { return b_has_deadzones; }; pad_config* GetConfig() { return &m_pad_config; }; //Sets window to config the controller(optional) - virtual void GetNextButtonPress(const std::string& padId, const std::function& callback) {}; + virtual void GetNextButtonPress(const std::string& padId, const std::function& callback, bool get_blacklist = false) {}; virtual void TestVibration(const std::string& padId, u32 largeMotor, u32 smallMotor) {}; //Return list of devices for that handler virtual std::vector ListDevices() = 0; diff --git a/rpcs3/ds4_pad_handler.cpp b/rpcs3/ds4_pad_handler.cpp index 1f57ddb4c4..aec8b8f6e8 100644 --- a/rpcs3/ds4_pad_handler.cpp +++ b/rpcs3/ds4_pad_handler.cpp @@ -147,45 +147,15 @@ ds4_pad_handler::ds4_pad_handler() : is_init(false) m_thumb_threshold = thumb_max / 2; } -void ds4_pad_handler::GetNextButtonPress(const std::string& padId, const std::function& callback) +void ds4_pad_handler::GetNextButtonPress(const std::string& padId, const std::function& callback, bool get_blacklist) { - if (!Init()) - { + if (get_blacklist) + blacklist.clear(); + + std::shared_ptr device = GetDevice(padId); + + if (CheckDeviceState(device) == false) return; - } - - // Get the DS4 Device or return if none found - size_t pos = padId.find("Ds4 Pad #"); - - if (pos == std::string::npos) return; - - std::string pad_serial = padId.substr(pos + 9); - - std::shared_ptr device = nullptr; - - for (auto& cur_control : controllers) - { - if (pad_serial == cur_control.first) - { - device = cur_control.second; - break; - } - } - - if (device == nullptr || device->hidDevice == nullptr) return; - - // Now that we have found a device, get its status - DS4DataStatus status = GetRawData(device); - - if (status == DS4DataStatus::ReadError) - { - // this also can mean disconnected, either way deal with it on next loop and reconnect - hid_close(device->hidDevice); - device->hidDevice = nullptr; - return; - } - - if (status != DS4DataStatus::NewData) return; // Get the current button values auto data = GetButtonValues(device); @@ -199,19 +169,32 @@ void ds4_pad_handler::GetNextButtonPress(const std::string& padId, const std::fu u32 keycode = button.first; u16 value = data[keycode]; + if (!get_blacklist && std::find(blacklist.begin(), blacklist.end(), keycode) != blacklist.end()) + continue; + if (((keycode < DS4KeyCodes::L2) && (value > 0)) || ((keycode == DS4KeyCodes::L2) && (value > m_trigger_threshold)) || ((keycode == DS4KeyCodes::R2) && (value > m_trigger_threshold)) || ((keycode >= DS4KeyCodes::LSXNeg && keycode <= DS4KeyCodes::LSYPos) && (value > m_thumb_threshold)) || ((keycode >= DS4KeyCodes::RSXNeg && keycode <= DS4KeyCodes::RSYPos) && (value > m_thumb_threshold))) { - if (value > pressed_button.first) + if (get_blacklist) { - pressed_button = { value, button.second}; + blacklist.emplace_back(keycode); + LOG_ERROR(HLE, "DS4 Calibration: Added key [ %d = %s ] to blacklist. Value = %d", keycode, button.second, value); } + else if (value > pressed_button.first) + pressed_button = { value, button.second }; } } + if (get_blacklist) + { + if (blacklist.size() <= 0) + LOG_SUCCESS(HLE, "DS4 Calibration: Blacklist is clear. No input spam detected"); + return; + } + int preview_values[6] = { data[L2], data[R2], data[LSXPos] - data[LSXNeg], data[LSYPos] - data[LSYNeg], data[RSXPos] - data[RSXNeg], data[RSYPos] - data[RSYNeg] }; if (pressed_button.first > 0) @@ -222,17 +205,28 @@ void ds4_pad_handler::GetNextButtonPress(const std::string& padId, const std::fu void ds4_pad_handler::TestVibration(const std::string& padId, u32 largeMotor, u32 smallMotor) { - if (!Init()) - { + std::shared_ptr device = GetDevice(padId); + if (device == nullptr || device->hidDevice == nullptr) return; - } + + // Set the device's motor speeds to our requested values 0-255 + device->largeVibrate = largeMotor; + device->smallVibrate = smallMotor; + + // Start/Stop the engines :) + SendVibrateData(device); +} + +std::shared_ptr ds4_pad_handler::GetDevice(const std::string& padId) +{ + if (!Init()) + return nullptr; size_t pos = padId.find("Ds4 Pad #"); - - if (pos == std::string::npos) return; + if (pos == std::string::npos) + return nullptr; std::string pad_serial = padId.substr(pos + 9); - std::shared_ptr device = nullptr; for (auto& cur_control : controllers) @@ -244,14 +238,29 @@ void ds4_pad_handler::TestVibration(const std::string& padId, u32 largeMotor, u3 } } - if (device == nullptr || device->hidDevice == nullptr) return; + return device; +} - // Set the device's motor speeds to our requested values 0-255 - device->largeVibrate = largeMotor; - device->smallVibrate = smallMotor; +bool ds4_pad_handler::CheckDeviceState(std::shared_ptr device) +{ + if (device == nullptr || device->hidDevice == nullptr) + return false; - // Start/Stop the engines :) - SendVibrateData(device); + // Now that we have found a device, get its status + DS4DataStatus status = GetRawData(device); + + if (status == DS4DataStatus::ReadError) + { + // this also can mean disconnected, either way deal with it on next loop and reconnect + hid_close(device->hidDevice); + device->hidDevice = nullptr; + return false; + } + + if (status != DS4DataStatus::NewData) + return false; + + return true; } void ds4_pad_handler::TranslateButtonPress(u64 keyCode, bool& pressed, u16& val, bool ignore_threshold) @@ -754,24 +763,9 @@ std::vector ds4_pad_handler::ListDevices() bool ds4_pad_handler::bindPadToDevice(std::shared_ptr pad, const std::string& device) { - size_t pos = device.find("Ds4 Pad #"); - - if (pos == std::string::npos) return false; - - std::string pad_serial = device.substr(pos + 9); - - std::shared_ptr device_id = nullptr; - - for (auto& cur_control : controllers) - { - if (pad_serial == cur_control.first) - { - device_id = cur_control.second; - break; - } - } - - if (device_id == nullptr) return false; + std::shared_ptr ds4device = GetDevice(device); + if (ds4device == nullptr || ds4device->hidDevice == nullptr) + return false; m_pad_config.load(); @@ -816,7 +810,7 @@ bool ds4_pad_handler::bindPadToDevice(std::shared_ptr pad, const std::strin pad->m_vibrateMotors.emplace_back(true, 0); pad->m_vibrateMotors.emplace_back(false, 0); - bindings.emplace_back(device_id, pad); + bindings.emplace_back(ds4device, pad); return true; } diff --git a/rpcs3/ds4_pad_handler.h b/rpcs3/ds4_pad_handler.h index 5c0e0d0ba5..1d979c8b33 100644 --- a/rpcs3/ds4_pad_handler.h +++ b/rpcs3/ds4_pad_handler.h @@ -141,7 +141,7 @@ public: std::vector ListDevices() override; bool bindPadToDevice(std::shared_ptr pad, const std::string& device) override; void ThreadProc() override; - void GetNextButtonPress(const std::string& padId, const std::function& buttonCallback) override; + void GetNextButtonPress(const std::string& padId, const std::function& buttonCallback, bool get_blacklist = false) override; void TestVibration(const std::string& padId, u32 largeMotor, u32 smallMotor) override; private: @@ -149,10 +149,12 @@ private: // holds internal controller state change std::array last_connection_status = {}; - + std::vector blacklist; std::vector, std::shared_ptr>> bindings; private: + std::shared_ptr GetDevice(const std::string& padId); + bool CheckDeviceState(std::shared_ptr device); void TranslateButtonPress(u64 keyCode, bool& pressed, u16& val, bool ignore_threshold = false) override; void ProcessDataToPad(const std::shared_ptr& ds4Device, const std::shared_ptr& pad); // Copies data into padData if status is NewData, otherwise buffer is untouched diff --git a/rpcs3/evdev_joystick_handler.cpp b/rpcs3/evdev_joystick_handler.cpp index 502cb659f3..2291c27345 100644 --- a/rpcs3/evdev_joystick_handler.cpp +++ b/rpcs3/evdev_joystick_handler.cpp @@ -213,8 +213,11 @@ std::unordered_map> evdev_joystick_handler::GetButtonV return button_values; } -void evdev_joystick_handler::GetNextButtonPress(const std::string& padId, const std::function& callback) +void evdev_joystick_handler::GetNextButtonPress(const std::string& padId, const std::function& callback, bool get_blacklist) { + if (get_blacklist) + blacklist.clear(); + // Add device if not yet present m_pad_index = add_device(padId, true); @@ -243,22 +246,41 @@ void evdev_joystick_handler::GetNextButtonPress(const std::string& padId, const std::pair pressed_button = { 0, "" }; for (const auto& button : button_list) { - if (padId.find("Xbox 360") != std::string::npos && button.first >= BTN_TRIGGER_HAPPY) + int code = button.first; + std::string name = button.second; + + if (padId.find("Xbox 360") != std::string::npos && code >= BTN_TRIGGER_HAPPY) continue; - if (padId.find("Sony") != std::string::npos && (button.first == BTN_TL2 || button.first == BTN_TR2)) + if (padId.find("Sony") != std::string::npos && (code == BTN_TL2 || code == BTN_TR2)) continue; - u16 value = data[button.first].first; - if (value > 0 && value > pressed_button.first) - pressed_button = { value, button.second }; + if (!get_blacklist && std::find(blacklist.begin(), blacklist.end(), name) != blacklist.end()) + continue; + + u16 value = data[code].first; + if (value > 0) + { + if (get_blacklist) + { + blacklist.emplace_back(name); + LOG_ERROR(HLE, "Evdev Calibration: Added button [ %d = %s ] to blacklist. Value = %d", code, name, value); + } + else if (value > pressed_button.first) + pressed_button = { value, name }; + } } for (const auto& button : axis_list) { int code = button.first; + std::string name = button.second; + if (data[code].second) continue; + if (!get_blacklist && std::find(blacklist.begin(), blacklist.end(), name) != blacklist.end()) + continue; + u16 value = data[code].first; if (((code == ABS_X || code == ABS_Y) && value < m_thumb_threshold) @@ -267,16 +289,29 @@ void evdev_joystick_handler::GetNextButtonPress(const std::string& padId, const || (code == ABS_RZ && value < m_trigger_threshold)) continue; - if (value > 0 && value > pressed_button.first) - pressed_button = { value, button.second }; + if (value > 0) + { + if (get_blacklist) + { + blacklist.emplace_back(name); + LOG_ERROR(HLE, "Evdev Calibration: Added axis [ %d = %s ] to blacklist. Value = %d", code, name, value); + } + else if (value > pressed_button.first) + pressed_button = { value, name }; + } } for (const auto& button : rev_axis_list) { int code = button.first; + std::string name = button.second; + if (!data[code].second) continue; + if (!get_blacklist && std::find(blacklist.begin(), blacklist.end(), name) != blacklist.end()) + continue; + u16 value = data[code].first; if (((code == ABS_X || code == ABS_Y) && value < m_thumb_threshold) @@ -285,8 +320,23 @@ void evdev_joystick_handler::GetNextButtonPress(const std::string& padId, const || (code == ABS_RZ && value < m_trigger_threshold)) continue; - if (value > 0 && value > pressed_button.first) - pressed_button = { value, button.second }; + if (value > 0) + { + if (get_blacklist) + { + blacklist.emplace_back(name); + LOG_ERROR(HLE, "Evdev Calibration: Added rev axis [ %d = %s ] to blacklist. Value = %d", code, name, value); + } + else if (value > pressed_button.first) + pressed_button = { value, name }; + } + } + + if (get_blacklist) + { + if (blacklist.size() <= 0) + LOG_SUCCESS(HLE, "Evdev Calibration: Blacklist is clear. No input spam detected"); + return; } // get stick values diff --git a/rpcs3/evdev_joystick_handler.h b/rpcs3/evdev_joystick_handler.h index 3e03e96ec8..2fd7aebf17 100644 --- a/rpcs3/evdev_joystick_handler.h +++ b/rpcs3/evdev_joystick_handler.h @@ -247,7 +247,7 @@ public: bool bindPadToDevice(std::shared_ptr pad, const std::string& device) override; void ThreadProc() override; void Close(); - void GetNextButtonPress(const std::string& padId, const std::function& callback) override; + void GetNextButtonPress(const std::string& padId, const std::function& callback, bool get_blacklist = false) override; void TestVibration(const std::string& padId, u32 largeMotor, u32 smallMotor) override; private: @@ -261,6 +261,7 @@ private: // Search axis_orientations map for the direction by index, returns -1 if not found, 0 for positive and 1 for negative int FindAxisDirection(const std::unordered_map& map, int index); + std::vector blacklist; std::vector devices; int m_pad_index = -1; }; diff --git a/rpcs3/mm_joystick_handler.cpp b/rpcs3/mm_joystick_handler.cpp index 2708edfe3c..271481ee17 100644 --- a/rpcs3/mm_joystick_handler.cpp +++ b/rpcs3/mm_joystick_handler.cpp @@ -284,12 +284,13 @@ void mm_joystick_handler::ThreadProc() } } -void mm_joystick_handler::GetNextButtonPress(const std::string& padId, const std::function& callback) +void mm_joystick_handler::GetNextButtonPress(const std::string& padId, const std::function& callback, bool get_blacklist) { + if (get_blacklist) + blacklist.clear(); + if (!Init()) - { return; - } static std::string cur_pad = ""; static int id = -1; @@ -328,33 +329,72 @@ void mm_joystick_handler::GetNextButtonPress(const std::string& padId, const std for (const auto& button : axis_list) { - u32 keycode = button.first; + u64 keycode = button.first; u16 value = data[keycode]; + if (!get_blacklist && std::find(blacklist.begin(), blacklist.end(), keycode) != blacklist.end()) + continue; + if (((keycode == mmjoy_axis::joy_z_neg) && (value > m_trigger_threshold)) || ((keycode == mmjoy_axis::joy_z_pos) && (value > m_trigger_threshold)) || ((keycode <= mmjoy_axis::joy_y_neg) && (value > m_thumb_threshold)) || ((keycode <= mmjoy_axis::joy_u_neg && keycode > mmjoy_axis::joy_z_neg) && (value > m_thumb_threshold))) { - if (value > pressed_button.first) + if (get_blacklist) { - pressed_button = { value, button.second }; + blacklist.emplace_back(keycode); + LOG_ERROR(HLE, "MMJOY Calibration: Added axis [ %d = %s ] to blacklist. Value = %d", keycode, button.second, value); } + else if (value > pressed_button.first) + pressed_button = { value, button.second }; } } for (const auto& button : pov_list) { - u16 value = data[button.first]; - if (value > 0 && value > pressed_button.first) - pressed_button = { value, button.second }; + u64 keycode = button.first; + u16 value = data[keycode]; + + if (!get_blacklist && std::find(blacklist.begin(), blacklist.end(), keycode) != blacklist.end()) + continue; + + if (value > 0) + { + if (get_blacklist) + { + blacklist.emplace_back(keycode); + LOG_ERROR(HLE, "MMJOY Calibration: Added pov [ %d = %s ] to blacklist. Value = %d", keycode, button.second, value); + } + else if (value > pressed_button.first) + pressed_button = { value, button.second }; + } } for (const auto& button : button_list) { - u16 value = data[button.first]; - if (value > 0 && value > pressed_button.first) - pressed_button = { value, button.second }; + u64 keycode = button.first; + u16 value = data[keycode]; + + if (!get_blacklist && std::find(blacklist.begin(), blacklist.end(), keycode) != blacklist.end()) + continue; + + if (value > 0) + { + if (get_blacklist) + { + blacklist.emplace_back(keycode); + LOG_ERROR(HLE, "MMJOY Calibration: Added button [ %d = %s ] to blacklist. Value = %d", keycode, button.second, value); + } + else if (value > pressed_button.first) + pressed_button = { value, button.second }; + } + } + + if (get_blacklist) + { + if (blacklist.size() <= 0) + LOG_SUCCESS(HLE, "MMJOY Calibration: Blacklist is clear. No input spam detected"); + return; } int preview_values[6] = diff --git a/rpcs3/mm_joystick_handler.h b/rpcs3/mm_joystick_handler.h index cadde8585a..9ce03a2d2e 100644 --- a/rpcs3/mm_joystick_handler.h +++ b/rpcs3/mm_joystick_handler.h @@ -103,7 +103,7 @@ public: std::vector ListDevices() override; bool bindPadToDevice(std::shared_ptr pad, const std::string& device) override; void ThreadProc() override; - void GetNextButtonPress(const std::string& padId, const std::function& callback) override; + void GetNextButtonPress(const std::string& padId, const std::function& callback, bool get_blacklist = false) override; private: void TranslateButtonPress(u64 keyCode, bool& pressed, u16& val, bool ignore_threshold = false) override; @@ -113,6 +113,7 @@ private: bool is_init = false; u32 supportedJoysticks = 0; + std::vector blacklist; std::unordered_map m_devices; std::vector, std::shared_ptr>> bindings; std::array last_connection_status = {}; diff --git a/rpcs3/rpcs3qt/pad_settings_dialog.cpp b/rpcs3/rpcs3qt/pad_settings_dialog.cpp index 8f41817426..e5c3f0f6b7 100644 --- a/rpcs3/rpcs3qt/pad_settings_dialog.cpp +++ b/rpcs3/rpcs3qt/pad_settings_dialog.cpp @@ -37,6 +37,7 @@ pad_settings_dialog::pad_settings_dialog(const std::string& device, std::shared_ { setWindowTitle(tr("Configure Keyboard")); m_handler_type = handler_type::handler_type_keyboard; + ui->b_blacklist->setEnabled(false); } else if (m_handler_cfg->cfg_type == "xinput") { @@ -241,9 +242,10 @@ pad_settings_dialog::pad_settings_dialog(const std::string& device, std::shared_ insertButton(button_ids::id_pad_rstick_right, ui->b_rstick_right, &m_handler_cfg->rs_right); insertButton(button_ids::id_pad_rstick_up, ui->b_rstick_up, &m_handler_cfg->rs_up); - m_padButtons->addButton(ui->b_reset, button_ids::id_reset_parameters); - m_padButtons->addButton(ui->b_ok, button_ids::id_ok); - m_padButtons->addButton(ui->b_cancel, button_ids::id_cancel); + m_padButtons->addButton(ui->b_reset, button_ids::id_reset_parameters); + m_padButtons->addButton(ui->b_blacklist, button_ids::id_blacklist); + m_padButtons->addButton(ui->b_ok, button_ids::id_ok); + m_padButtons->addButton(ui->b_cancel, button_ids::id_cancel); connect(m_padButtons, static_cast(&QButtonGroup::buttonClicked), this, &pad_settings_dialog::OnPadButtonClicked); @@ -415,6 +417,9 @@ void pad_settings_dialog::OnPadButtonClicked(int id) m_handler_cfg->from_default(); UpdateLabel(true); return; + case button_ids::id_blacklist: + m_handler->GetNextButtonPress(m_device_name, nullptr, true); + return; case button_ids::id_ok: SaveConfig(); QDialog::accept(); diff --git a/rpcs3/rpcs3qt/pad_settings_dialog.h b/rpcs3/rpcs3qt/pad_settings_dialog.h index 93f9a34d6f..61fd585fcb 100644 --- a/rpcs3/rpcs3qt/pad_settings_dialog.h +++ b/rpcs3/rpcs3qt/pad_settings_dialog.h @@ -67,6 +67,7 @@ class pad_settings_dialog : public QDialog id_pad_end, // end id_reset_parameters, + id_blacklist, id_ok, id_cancel }; diff --git a/rpcs3/rpcs3qt/pad_settings_dialog.ui b/rpcs3/rpcs3qt/pad_settings_dialog.ui index dde6afcba6..fe26ee6e0f 100644 --- a/rpcs3/rpcs3qt/pad_settings_dialog.ui +++ b/rpcs3/rpcs3qt/pad_settings_dialog.ui @@ -6,8 +6,8 @@ 0 0 - 892 - 568 + 1044 + 640 @@ -1729,14 +1729,25 @@ - - - Restore Defaults - - - false - - + + + + + Filter Noise + + + + + + + Restore Defaults + + + false + + + + diff --git a/rpcs3/xinput_pad_handler.cpp b/rpcs3/xinput_pad_handler.cpp index ec50aefe94..ff1b70928f 100644 --- a/rpcs3/xinput_pad_handler.cpp +++ b/rpcs3/xinput_pad_handler.cpp @@ -70,37 +70,23 @@ xinput_pad_handler::~xinput_pad_handler() Close(); } -void xinput_pad_handler::GetNextButtonPress(const std::string& padId, const std::function& callback) +void xinput_pad_handler::GetNextButtonPress(const std::string& padId, const std::function& callback, bool get_blacklist) { - if (!Init()) - { + if (get_blacklist) + blacklist.clear(); + + int device_number = GetDeviceNumber(padId); + if (device_number < 0) return; - } - - size_t pos = padId.find("Xinput Pad #"); - int device_number; - - if (pos != std::string::npos) - { - device_number = std::stoul(padId.substr(pos + 12)); - } - - if (pos == std::string::npos || device_number >= XUSER_MAX_COUNT) - { - return; - } DWORD dwResult; XINPUT_STATE state; ZeroMemory(&state, sizeof(XINPUT_STATE)); // Simply get the state of the controller from XInput. - dwResult = (*xinputGetState)(device_number, &state); - + dwResult = (*xinputGetState)(static_cast(device_number), &state); if (dwResult != ERROR_SUCCESS) - { return; - } // Check for each button in our list if its corresponding (maybe remapped) button or axis was pressed. // Return the new value if the button was pressed (aka. its value was bigger than 0 or the defined threshold) @@ -112,19 +98,32 @@ void xinput_pad_handler::GetNextButtonPress(const std::string& padId, const std: u32 keycode = button.first; u16 value = data[keycode]; + if (!get_blacklist && std::find(blacklist.begin(), blacklist.end(), keycode) != blacklist.end()) + continue; + if (((keycode < XInputKeyCodes::LT) && (value > 0)) || ((keycode == XInputKeyCodes::LT) && (value > m_trigger_threshold)) || ((keycode == XInputKeyCodes::RT) && (value > m_trigger_threshold)) || ((keycode >= XInputKeyCodes::LSXNeg && keycode <= XInputKeyCodes::LSYPos) && (value > m_thumb_threshold)) || ((keycode >= XInputKeyCodes::RSXNeg && keycode <= XInputKeyCodes::RSYPos) && (value > m_thumb_threshold))) { - if (value > pressed_button.first) + if (get_blacklist) { - pressed_button = { value, button.second }; + blacklist.emplace_back(keycode); + LOG_ERROR(HLE, "XInput Calibration: Added key [ %d = %s ] to blacklist. Value = %d", keycode, button.second, value); } + else if (value > pressed_button.first) + pressed_button = { value, button.second }; } } + if (get_blacklist) + { + if (blacklist.size() <= 0) + LOG_SUCCESS(HLE, "XInput Calibration: Blacklist is clear. No input spam detected"); + return; + } + int preview_values[6] = { data[LT], data[RT], data[LSXPos] - data[LSXNeg], data[LSYPos] - data[LSYNeg], data[RSXPos] - data[RSXNeg], data[RSYPos] - data[RSYNeg] }; if (pressed_button.first > 0) @@ -135,23 +134,9 @@ void xinput_pad_handler::GetNextButtonPress(const std::string& padId, const std: void xinput_pad_handler::TestVibration(const std::string& padId, u32 largeMotor, u32 smallMotor) { - if (!Init()) - { + int device_number = GetDeviceNumber(padId); + if (device_number < 0) return; - } - - u32 device_number = 0; - size_t pos = padId.find("Xinput Pad #"); - - if (pos != std::string::npos) - { - device_number = std::stoul(padId.substr(pos + 12)); - } - - if (pos == std::string::npos || device_number >= XUSER_MAX_COUNT) - { - return; - } // The left motor is the low-frequency rumble motor. The right motor is the high-frequency rumble motor. // The two motors are not the same, and they create different vibration effects. @@ -160,7 +145,7 @@ void xinput_pad_handler::TestVibration(const std::string& padId, u32 largeMotor, vibrate.wLeftMotorSpeed = largeMotor; // between 0 to 65535 vibrate.wRightMotorSpeed = smallMotor; // between 0 to 65535 - (*xinputSetState)(device_number, &vibrate); + (*xinputSetState)(static_cast(device_number), &vibrate); } void xinput_pad_handler::TranslateButtonPress(u64 keyCode, bool& pressed, u16& val, bool ignore_threshold) @@ -198,6 +183,22 @@ void xinput_pad_handler::TranslateButtonPress(u64 keyCode, bool& pressed, u16& v } } +int xinput_pad_handler::GetDeviceNumber(const std::string& padId) +{ + if (!Init()) + return -1; + + size_t pos = padId.find("Xinput Pad #"); + if (pos == std::string::npos) + return -1; + + int device_number = std::stoul(padId.substr(pos + 12)); + if (device_number >= XUSER_MAX_COUNT) + return -1; + + return device_number; +} + std::array xinput_pad_handler::GetButtonValues(const XINPUT_STATE& state) { std::array values; @@ -451,15 +452,12 @@ std::vector xinput_pad_handler::ListDevices() bool xinput_pad_handler::bindPadToDevice(std::shared_ptr pad, const std::string& device) { //Convert device string to u32 representing xinput device number - u32 device_number = 0; - size_t pos = device.find("Xinput Pad #"); - - if (pos != std::string::npos) device_number = std::stoul(device.substr(pos + 12)); - - if (pos == std::string::npos || device_number >= XUSER_MAX_COUNT) return false; + int device_number = GetDeviceNumber(device); + if (device_number < 0) + return false; std::shared_ptr device_id = std::make_shared(); - device_id->deviceNumber = device_number; + device_id->deviceNumber = static_cast(device_number); m_pad_config.load(); diff --git a/rpcs3/xinput_pad_handler.h b/rpcs3/xinput_pad_handler.h index c56ac4a740..131c155a62 100644 --- a/rpcs3/xinput_pad_handler.h +++ b/rpcs3/xinput_pad_handler.h @@ -107,7 +107,7 @@ public: std::vector ListDevices() override; bool bindPadToDevice(std::shared_ptr pad, const std::string& device) override; void ThreadProc() override; - void GetNextButtonPress(const std::string& padId, const std::function& callback) override; + void GetNextButtonPress(const std::string& padId, const std::function& callback, bool get_blacklist = false) override; void TestVibration(const std::string& padId, u32 largeMotor, u32 smallMotor) override; private: @@ -117,6 +117,7 @@ private: typedef DWORD (WINAPI * PFN_XINPUTGETBATTERYINFORMATION)(DWORD, BYTE, XINPUT_BATTERY_INFORMATION *); private: + int GetDeviceNumber(const std::string& padId); std::array GetButtonValues(const XINPUT_STATE& state); void TranslateButtonPress(u64 keyCode, bool& pressed, u16& val, bool ignore_threshold = false) override; @@ -127,6 +128,7 @@ private: PFN_XINPUTENABLE xinputEnable; PFN_XINPUTGETBATTERYINFORMATION xinputGetBatteryInformation; + std::vector blacklist; std::vector, std::shared_ptr>> bindings; std::array last_connection_status = {};