From 08f81160cc49562dc139e323f01e5f22b2ad5eed Mon Sep 17 00:00:00 2001 From: Megamouse Date: Sat, 17 Aug 2024 11:21:11 +0200 Subject: [PATCH] Input: Abbreviate some variable names and add min output interval The abbreviation allows for easier diff between handlers. --- rpcs3/Emu/Io/PadHandler.h | 3 + rpcs3/Input/ds3_pad_handler.cpp | 25 ++-- rpcs3/Input/ds4_pad_handler.cpp | 99 +++++++------- rpcs3/Input/dualsense_pad_handler.cpp | 175 +++++++++++++------------ rpcs3/Input/dualsense_pad_handler.h | 2 +- rpcs3/Input/evdev_joystick_handler.cpp | 11 +- rpcs3/Input/evdev_joystick_handler.h | 1 - rpcs3/Input/hid_pad_handler.h | 1 - rpcs3/Input/mm_joystick_handler.cpp | 44 +++---- rpcs3/Input/sdl_pad_handler.cpp | 17 ++- rpcs3/Input/sdl_pad_handler.h | 3 - rpcs3/Input/skateboard_pad_handler.cpp | 50 +++---- rpcs3/Input/xinput_pad_handler.cpp | 34 +++-- rpcs3/Input/xinput_pad_handler.h | 2 - 14 files changed, 246 insertions(+), 221 deletions(-) diff --git a/rpcs3/Emu/Io/PadHandler.h b/rpcs3/Emu/Io/PadHandler.h index ee0b66bd0d..978ed00bde 100644 --- a/rpcs3/Emu/Io/PadHandler.h +++ b/rpcs3/Emu/Io/PadHandler.h @@ -23,6 +23,8 @@ public: u8 player_id{0}; u8 large_motor{0}; u8 small_motor{0}; + bool new_output_data{true}; + steady_clock::time_point last_output; std::set trigger_code_left{}; std::set trigger_code_right{}; std::array, 4> axis_code_left{}; @@ -114,6 +116,7 @@ protected: static constexpr u32 MAX_GAMEPADS = 7; static constexpr u16 button_press_threshold = 50; static constexpr u16 touch_threshold = static_cast(255 * 0.9f); + static constexpr auto min_output_interval = 300ms; std::array last_connection_status{{ false, false, false, false, false, false, false }}; diff --git a/rpcs3/Input/ds3_pad_handler.cpp b/rpcs3/Input/ds3_pad_handler.cpp index 68f31d2aa8..41afccfad0 100644 --- a/rpcs3/Input/ds3_pad_handler.cpp +++ b/rpcs3/Input/ds3_pad_handler.cpp @@ -421,14 +421,14 @@ void ds3_pad_handler::get_extended_info(const pad_ensemble& binding) const auto& device = binding.device; const auto& pad = binding.pad; - ds3_device* ds3dev = static_cast(device.get()); - if (!ds3dev || !pad) + ds3_device* dev = static_cast(device.get()); + if (!dev || !pad) return; - const ds3_input_report& report = ds3dev->report; + const ds3_input_report& report = dev->report; - pad->m_battery_level = ds3dev->battery_level; - pad->m_cable_state = ds3dev->cable_state; + pad->m_battery_level = dev->battery_level; + pad->m_cable_state = dev->cable_state; // For unknown reasons the sixaxis values seem to be in little endian on linux @@ -510,14 +510,13 @@ PadHandlerBase::connection ds3_pad_handler::update_connection(const std::shared_ if (dev->hidDevice == nullptr) { - hid_device* devhandle = hid_open_path(dev->path.c_str()); - if (devhandle) + if (hid_device* hid_dev = hid_open_path(dev->path.c_str())) { - if (hid_set_nonblocking(devhandle, 1) == -1) + if (hid_set_nonblocking(hid_dev, 1) == -1) { - ds3_log.error("Reconnecting Device %s: hid_set_nonblocking failed with error %s", dev->path, hid_error(devhandle)); + ds3_log.error("Reconnecting Device %s: hid_set_nonblocking failed with error %s", dev->path, hid_error(hid_dev)); } - dev->hidDevice = devhandle; + dev->hidDevice = hid_dev; } else { @@ -598,11 +597,15 @@ void ds3_pad_handler::apply_pad_data(const pad_ensemble& binding) dev->large_motor = speed_large; dev->small_motor = speed_small; - if (dev->new_output_data) + const auto now = steady_clock::now(); + const auto elapsed = now - dev->last_output; + + if (dev->new_output_data || elapsed > min_output_interval) { if (const int res = send_output_report(dev); res >= 0) { dev->new_output_data = false; + dev->last_output = now; } else if (res == -1) { diff --git a/rpcs3/Input/ds4_pad_handler.cpp b/rpcs3/Input/ds4_pad_handler.cpp index dcf5ee2f41..a80b185f63 100644 --- a/rpcs3/Input/ds4_pad_handler.cpp +++ b/rpcs3/Input/ds4_pad_handler.cpp @@ -253,11 +253,11 @@ void ds4_pad_handler::SetPadData(const std::string& padId, u8 player_id, u8 larg std::unordered_map ds4_pad_handler::get_button_values(const std::shared_ptr& device) { std::unordered_map keyBuffer; - DS4Device* ds4_dev = static_cast(device.get()); - if (!ds4_dev) + DS4Device* dev = static_cast(device.get()); + if (!dev) return keyBuffer; - const ds4_input_report_common& input = ds4_dev->bt_controller ? ds4_dev->report_bt.common : ds4_dev->report_usb.common; + const ds4_input_report_common& input = dev->bt_controller ? dev->report_bt.common : dev->report_usb.common; // Left Stick X Axis keyBuffer[DS4KeyCodes::LSXNeg] = Clamp0To255((127.5f - input.x) * 2.0f); @@ -383,9 +383,9 @@ std::unordered_map ds4_pad_handler::get_button_values(const std::share } }; - if (ds4_dev->bt_controller) + if (dev->bt_controller) { - const ds4_input_report_bt& report = ds4_dev->report_bt; + const ds4_input_report_bt& report = dev->report_bt; for (u32 i = 0; i < std::min(report.num_touch_reports, ::size32(report.touch_reports)); i++) { @@ -394,7 +394,7 @@ std::unordered_map ds4_pad_handler::get_button_values(const std::share } else { - const ds4_input_report_usb& report = ds4_dev->report_usb; + const ds4_input_report_usb& report = dev->report_usb; for (u32 i = 0; i < std::min(report.num_touch_reports, ::size32(report.touch_reports)); i++) { @@ -828,23 +828,26 @@ bool ds4_pad_handler::get_is_touch_pad_motion(const std::shared_ptr& PadHandlerBase::connection ds4_pad_handler::update_connection(const std::shared_ptr& device) { - DS4Device* ds4_dev = static_cast(device.get()); - if (!ds4_dev || ds4_dev->path.empty()) + DS4Device* dev = static_cast(device.get()); + if (!dev || dev->path.empty()) return connection::disconnected; - if (ds4_dev->hidDevice == nullptr) + if (dev->hidDevice == nullptr) { // try to reconnect - hid_device* dev = hid_open_path(ds4_dev->path.c_str()); - if (dev) + if (hid_device* hid_dev = hid_open_path(dev->path.c_str())) { - if (hid_set_nonblocking(dev, 1) == -1) + if (hid_set_nonblocking(hid_dev, 1) == -1) { - ds4_log.error("Reconnecting Device %s: hid_set_nonblocking failed with error %s", ds4_dev->path, hid_error(dev)); + ds4_log.error("Reconnecting Device %s: hid_set_nonblocking failed with error %s", dev->path, hid_error(hid_dev)); + } + + dev->hidDevice = hid_dev; + + if (!dev->has_calib_data) + { + dev->has_calib_data = GetCalibrationData(dev); } - ds4_dev->hidDevice = dev; - if (!ds4_dev->has_calib_data) - ds4_dev->has_calib_data = GetCalibrationData(ds4_dev); } else { @@ -853,10 +856,10 @@ PadHandlerBase::connection ds4_pad_handler::update_connection(const std::shared_ } } - if (get_data(ds4_dev) == DataStatus::ReadError) + if (get_data(dev) == DataStatus::ReadError) { // this also can mean disconnected, either way deal with it on next loop and reconnect - ds4_dev->close(); + dev->close(); return connection::no_data; } @@ -869,14 +872,14 @@ void ds4_pad_handler::get_extended_info(const pad_ensemble& binding) const auto& device = binding.device; const auto& pad = binding.pad; - DS4Device* ds4_device = static_cast(device.get()); - if (!ds4_device || !pad) + DS4Device* dev = static_cast(device.get()); + if (!dev || !pad) return; - const ds4_input_report_common& input = ds4_device->bt_controller ? ds4_device->report_bt.common : ds4_device->report_usb.common; + const ds4_input_report_common& input = dev->bt_controller ? dev->report_bt.common : dev->report_usb.common; - pad->m_battery_level = ds4_device->battery_level; - pad->m_cable_state = ds4_device->cable_state; + pad->m_battery_level = dev->battery_level; + pad->m_cable_state = dev->cable_state; // these values come already calibrated, all we need to do is convert to ds3 range @@ -910,11 +913,11 @@ void ds4_pad_handler::apply_pad_data(const pad_ensemble& binding) const auto& device = binding.device; const auto& pad = binding.pad; - DS4Device* ds4_dev = static_cast(device.get()); - if (!ds4_dev || !ds4_dev->hidDevice || !ds4_dev->config || !pad) + DS4Device* dev = static_cast(device.get()); + if (!dev || !dev->hidDevice || !dev->config || !pad) return; - cfg_pad* config = ds4_dev->config; + cfg_pad* config = dev->config; // Attempt to send rumble no matter what const int idx_l = config->switch_vibration_motors ? 1 : 0; @@ -923,9 +926,9 @@ void ds4_pad_handler::apply_pad_data(const pad_ensemble& binding) const u8 speed_large = config->enable_vibration_motor_large ? pad->m_vibrateMotors[idx_l].m_value : 0; const u8 speed_small = config->enable_vibration_motor_small ? pad->m_vibrateMotors[idx_s].m_value : 0; - const bool wireless = ds4_dev->cable_state == 0; - const bool low_battery = ds4_dev->battery_level < 2; - const bool is_blinking = ds4_dev->led_delay_on > 0 || ds4_dev->led_delay_off > 0; + const bool wireless = dev->cable_state == 0; + const bool low_battery = dev->battery_level < 2; + const bool is_blinking = dev->led_delay_on > 0 || dev->led_delay_off > 0; // Blink LED when battery is low if (config->led_low_battery_blink) @@ -933,16 +936,16 @@ void ds4_pad_handler::apply_pad_data(const pad_ensemble& binding) // we are now wired or have okay battery level -> stop blinking if (is_blinking && !(wireless && low_battery)) { - ds4_dev->led_delay_on = 0; - ds4_dev->led_delay_off = 0; - ds4_dev->new_output_data = true; + dev->led_delay_on = 0; + dev->led_delay_off = 0; + dev->new_output_data = true; } // we are now wireless and low on battery -> blink else if (!is_blinking && wireless && low_battery) { - ds4_dev->led_delay_on = 100; - ds4_dev->led_delay_off = 100; - ds4_dev->new_output_data = true; + dev->led_delay_on = 100; + dev->led_delay_off = 100; + dev->new_output_data = true; } } @@ -950,31 +953,35 @@ void ds4_pad_handler::apply_pad_data(const pad_ensemble& binding) if (config->led_battery_indicator) { // This makes sure that the LED color doesn't update every 1ms. DS4 only reports battery level in 10% increments - if (ds4_dev->last_battery_level != ds4_dev->battery_level) + if (dev->last_battery_level != dev->battery_level) { - const u32 combined_color = get_battery_color(ds4_dev->battery_level, config->led_battery_indicator_brightness); + const u32 combined_color = get_battery_color(dev->battery_level, config->led_battery_indicator_brightness); config->colorR.set(combined_color >> 8); config->colorG.set(combined_color & 0xff); config->colorB.set(0); - ds4_dev->new_output_data = true; - ds4_dev->last_battery_level = ds4_dev->battery_level; + dev->new_output_data = true; + dev->last_battery_level = dev->battery_level; } } - ds4_dev->new_output_data |= ds4_dev->large_motor != speed_large || ds4_dev->small_motor != speed_small; + dev->new_output_data |= dev->large_motor != speed_large || dev->small_motor != speed_small; - ds4_dev->large_motor = speed_large; - ds4_dev->small_motor = speed_small; + dev->large_motor = speed_large; + dev->small_motor = speed_small; - if (ds4_dev->new_output_data) + const auto now = steady_clock::now(); + const auto elapsed = now - dev->last_output; + + if (dev->new_output_data || elapsed > min_output_interval) { - if (const int res = send_output_report(ds4_dev); res >= 0) + if (const int res = send_output_report(dev); res >= 0) { - ds4_dev->new_output_data = false; + dev->new_output_data = false; + dev->last_output = now; } else if (res == -1) { - ds4_log.error("apply_pad_data: send_output_report failed! error=%s", hid_error(ds4_dev->hidDevice)); + ds4_log.error("apply_pad_data: send_output_report failed! error=%s", hid_error(dev->hidDevice)); } } } diff --git a/rpcs3/Input/dualsense_pad_handler.cpp b/rpcs3/Input/dualsense_pad_handler.cpp index 67ae346d6d..0400e69d08 100644 --- a/rpcs3/Input/dualsense_pad_handler.cpp +++ b/rpcs3/Input/dualsense_pad_handler.cpp @@ -383,9 +383,9 @@ dualsense_pad_handler::DataStatus dualsense_pad_handler::get_data(DualSenseDevic return DataStatus::NewData; } -bool dualsense_pad_handler::get_calibration_data(DualSenseDevice* dualsense_device) const +bool dualsense_pad_handler::get_calibration_data(DualSenseDevice* dev) const { - if (!dualsense_device || !dualsense_device->hidDevice) + if (!dev || !dev->hidDevice) { dualsense_log.error("get_calibration_data called with null device"); return false; @@ -393,16 +393,16 @@ bool dualsense_pad_handler::get_calibration_data(DualSenseDevice* dualsense_devi std::array buf{}; - if (dualsense_device->bt_controller) + if (dev->bt_controller) { for (int tries = 0; tries < 3; ++tries) { buf = {}; buf[0] = 0x05; - if (int res = hid_get_feature_report(dualsense_device->hidDevice, buf.data(), DUALSENSE_CALIBRATION_REPORT_SIZE); res != DUALSENSE_CALIBRATION_REPORT_SIZE || buf[0] != 0x05) + if (int res = hid_get_feature_report(dev->hidDevice, buf.data(), DUALSENSE_CALIBRATION_REPORT_SIZE); res != DUALSENSE_CALIBRATION_REPORT_SIZE || buf[0] != 0x05) { - dualsense_log.error("get_calibration_data: hid_get_feature_report 0x05 for bluetooth controller failed! result=%d, buf[0]=0x%x, error=%s", res, buf[0], hid_error(dualsense_device->hidDevice)); + dualsense_log.error("get_calibration_data: hid_get_feature_report 0x05 for bluetooth controller failed! result=%d, buf[0]=0x%x, error=%s", res, buf[0], hid_error(dev->hidDevice)); return false; } @@ -427,16 +427,16 @@ bool dualsense_pad_handler::get_calibration_data(DualSenseDevice* dualsense_devi { buf[0] = 0x05; - if (int res = hid_get_feature_report(dualsense_device->hidDevice, buf.data(), DUALSENSE_CALIBRATION_REPORT_SIZE); res != DUALSENSE_CALIBRATION_REPORT_SIZE || buf[0] != 0x05) + if (int res = hid_get_feature_report(dev->hidDevice, buf.data(), DUALSENSE_CALIBRATION_REPORT_SIZE); res != DUALSENSE_CALIBRATION_REPORT_SIZE || buf[0] != 0x05) { - dualsense_log.error("get_calibration_data: hid_get_feature_report 0x05 for wired controller failed! result=%d, buf[0]=0x%x, error=%s", res, buf[0], hid_error(dualsense_device->hidDevice)); + dualsense_log.error("get_calibration_data: hid_get_feature_report 0x05 for wired controller failed! result=%d, buf[0]=0x%x, error=%s", res, buf[0], hid_error(dev->hidDevice)); return false; } } - dualsense_device->calib_data[CalibIndex::PITCH].bias = read_s16(&buf[1]); - dualsense_device->calib_data[CalibIndex::YAW].bias = read_s16(&buf[3]); - dualsense_device->calib_data[CalibIndex::ROLL].bias = read_s16(&buf[5]); + dev->calib_data[CalibIndex::PITCH].bias = read_s16(&buf[1]); + dev->calib_data[CalibIndex::YAW].bias = read_s16(&buf[3]); + dev->calib_data[CalibIndex::ROLL].bias = read_s16(&buf[5]); const s16 pitch_plus = read_s16(&buf[7]); const s16 pitch_minus = read_s16(&buf[9]); @@ -455,14 +455,14 @@ bool dualsense_pad_handler::get_calibration_data(DualSenseDevice* dualsense_devi const s32 gyro_speed_scale = read_s16(&buf[19]) + read_s16(&buf[21]); - dualsense_device->calib_data[CalibIndex::PITCH].sens_numer = gyro_speed_scale * DUALSENSE_GYRO_RES_PER_DEG_S; - dualsense_device->calib_data[CalibIndex::PITCH].sens_denom = pitch_plus - pitch_minus; + dev->calib_data[CalibIndex::PITCH].sens_numer = gyro_speed_scale * DUALSENSE_GYRO_RES_PER_DEG_S; + dev->calib_data[CalibIndex::PITCH].sens_denom = pitch_plus - pitch_minus; - dualsense_device->calib_data[CalibIndex::YAW].sens_numer = gyro_speed_scale * DUALSENSE_GYRO_RES_PER_DEG_S; - dualsense_device->calib_data[CalibIndex::YAW].sens_denom = yaw_plus - yaw_minus; + dev->calib_data[CalibIndex::YAW].sens_numer = gyro_speed_scale * DUALSENSE_GYRO_RES_PER_DEG_S; + dev->calib_data[CalibIndex::YAW].sens_denom = yaw_plus - yaw_minus; - dualsense_device->calib_data[CalibIndex::ROLL].sens_numer = gyro_speed_scale * DUALSENSE_GYRO_RES_PER_DEG_S; - dualsense_device->calib_data[CalibIndex::ROLL].sens_denom = roll_plus - roll_minus; + dev->calib_data[CalibIndex::ROLL].sens_numer = gyro_speed_scale * DUALSENSE_GYRO_RES_PER_DEG_S; + dev->calib_data[CalibIndex::ROLL].sens_denom = roll_plus - roll_minus; const s16 accel_x_plus = read_s16(&buf[23]); const s16 accel_x_minus = read_s16(&buf[25]); @@ -475,23 +475,23 @@ bool dualsense_pad_handler::get_calibration_data(DualSenseDevice* dualsense_devi const s32 accel_y_range = accel_y_plus - accel_y_minus; const s32 accel_z_range = accel_z_plus - accel_z_minus; - dualsense_device->calib_data[CalibIndex::X].bias = accel_x_plus - accel_x_range / 2; - dualsense_device->calib_data[CalibIndex::X].sens_numer = 2 * DUALSENSE_ACC_RES_PER_G; - dualsense_device->calib_data[CalibIndex::X].sens_denom = accel_x_range; + dev->calib_data[CalibIndex::X].bias = accel_x_plus - accel_x_range / 2; + dev->calib_data[CalibIndex::X].sens_numer = 2 * DUALSENSE_ACC_RES_PER_G; + dev->calib_data[CalibIndex::X].sens_denom = accel_x_range; - dualsense_device->calib_data[CalibIndex::Y].bias = accel_y_plus - accel_y_range / 2; - dualsense_device->calib_data[CalibIndex::Y].sens_numer = 2 * DUALSENSE_ACC_RES_PER_G; - dualsense_device->calib_data[CalibIndex::Y].sens_denom = accel_y_range; + dev->calib_data[CalibIndex::Y].bias = accel_y_plus - accel_y_range / 2; + dev->calib_data[CalibIndex::Y].sens_numer = 2 * DUALSENSE_ACC_RES_PER_G; + dev->calib_data[CalibIndex::Y].sens_denom = accel_y_range; - dualsense_device->calib_data[CalibIndex::Z].bias = accel_z_plus - accel_z_range / 2; - dualsense_device->calib_data[CalibIndex::Z].sens_numer = 2 * DUALSENSE_ACC_RES_PER_G; - dualsense_device->calib_data[CalibIndex::Z].sens_denom = accel_z_range; + dev->calib_data[CalibIndex::Z].bias = accel_z_plus - accel_z_range / 2; + dev->calib_data[CalibIndex::Z].sens_numer = 2 * DUALSENSE_ACC_RES_PER_G; + dev->calib_data[CalibIndex::Z].sens_denom = accel_z_range; // Make sure data 'looks' valid, dongle will report invalid calibration data with no controller connected - for (size_t i = 0; i < dualsense_device->calib_data.size(); i++) + for (size_t i = 0; i < dev->calib_data.size(); i++) { - CalibData& data = dualsense_device->calib_data[i]; + CalibData& data = dev->calib_data[i]; if (data.sens_denom == 0) { @@ -559,23 +559,26 @@ bool dualsense_pad_handler::get_is_touch_pad_motion(const std::shared_ptr& device) { - DualSenseDevice* dualsense_dev = static_cast(device.get()); - if (!dualsense_dev || dualsense_dev->path.empty()) + DualSenseDevice* dev = static_cast(device.get()); + if (!dev || dev->path.empty()) return connection::disconnected; - if (dualsense_dev->hidDevice == nullptr) + if (dev->hidDevice == nullptr) { // try to reconnect - hid_device* dev = hid_open_path(dualsense_dev->path.c_str()); - if (dev) + if (hid_device* hid_dev = hid_open_path(dev->path.c_str())) { - if (hid_set_nonblocking(dev, 1) == -1) + if (hid_set_nonblocking(hid_dev, 1) == -1) { - dualsense_log.error("Reconnecting Device %s: hid_set_nonblocking failed with error %s", dualsense_dev->path, hid_error(dev)); + dualsense_log.error("Reconnecting Device %s: hid_set_nonblocking failed with error %s", dev->path, hid_error(hid_dev)); + } + + dev->hidDevice = hid_dev; + + if (!dev->has_calib_data) + { + dev->has_calib_data = get_calibration_data(dev); } - dualsense_dev->hidDevice = dev; - if (!dualsense_dev->has_calib_data) - dualsense_dev->has_calib_data = get_calibration_data(dualsense_dev); } else { @@ -584,10 +587,10 @@ PadHandlerBase::connection dualsense_pad_handler::update_connection(const std::s } } - if (get_data(dualsense_dev) == DataStatus::ReadError) + if (get_data(dev) == DataStatus::ReadError) { // this also can mean disconnected, either way deal with it on next loop and reconnect - dualsense_dev->close(); + dev->close(); return connection::no_data; } @@ -600,14 +603,14 @@ void dualsense_pad_handler::get_extended_info(const pad_ensemble& binding) const auto& device = binding.device; const auto& pad = binding.pad; - DualSenseDevice* dualsense_device = static_cast(device.get()); - if (!dualsense_device || !pad) + DualSenseDevice* dev = static_cast(device.get()); + if (!dev || !pad) return; - pad->m_battery_level = dualsense_device->battery_level; - pad->m_cable_state = dualsense_device->cable_state; + pad->m_battery_level = dev->battery_level; + pad->m_cable_state = dev->cable_state; - const dualsense_input_report_common& input = dualsense_device->report; + const dualsense_input_report_common& input = dev->report; // these values come already calibrated, all we need to do is convert to ds3 range @@ -638,13 +641,13 @@ void dualsense_pad_handler::get_extended_info(const pad_ensemble& binding) std::unordered_map dualsense_pad_handler::get_button_values(const std::shared_ptr& device) { std::unordered_map keyBuffer; - DualSenseDevice* dualsense_dev = static_cast(device.get()); - if (!dualsense_dev) + DualSenseDevice* dev = static_cast(device.get()); + if (!dev) return keyBuffer; - const dualsense_input_report_common& input = dualsense_dev->report; + const dualsense_input_report_common& input = dev->report; - const bool is_simple_mode = dualsense_dev->data_mode == DualSenseDevice::DualSenseDataMode::Simple; + const bool is_simple_mode = dev->data_mode == DualSenseDevice::DualSenseDataMode::Simple; // Left Stick X Axis keyBuffer[DualSenseKeyCodes::LSXNeg] = Clamp0To255((127.5f - input.x) * 2.0f); @@ -766,7 +769,7 @@ std::unordered_map dualsense_pad_handler::get_button_values(const std: } } - if (dualsense_dev->feature_set == DualSenseDevice::DualSenseFeatureSet::Edge) + if (dev->feature_set == DualSenseDevice::DualSenseFeatureSet::Edge) { keyBuffer[DualSenseKeyCodes::EdgeFnL] = ((data & 0x10) != 0) ? 255 : 0; keyBuffer[DualSenseKeyCodes::EdgeFnR] = ((data & 0x20) != 0) ? 255 : 0; @@ -930,11 +933,11 @@ void dualsense_pad_handler::apply_pad_data(const pad_ensemble& binding) const auto& device = binding.device; const auto& pad = binding.pad; - DualSenseDevice* dualsense_dev = static_cast(device.get()); - if (!dualsense_dev || !dualsense_dev->hidDevice || !dualsense_dev->config || !pad) + DualSenseDevice* dev = static_cast(device.get()); + if (!dev || !dev->hidDevice || !dev->config || !pad) return; - cfg_pad* config = dualsense_dev->config; + cfg_pad* config = dev->config; // Attempt to send rumble no matter what const int idx_l = config->switch_vibration_motors ? 1 : 0; @@ -943,9 +946,9 @@ void dualsense_pad_handler::apply_pad_data(const pad_ensemble& binding) const u8 speed_large = config->enable_vibration_motor_large ? pad->m_vibrateMotors[idx_l].m_value : 0; const u8 speed_small = config->enable_vibration_motor_small ? pad->m_vibrateMotors[idx_s].m_value : 0; - const bool wireless = dualsense_dev->cable_state == 0; - const bool low_battery = dualsense_dev->battery_level <= 1; - const bool is_blinking = dualsense_dev->led_delay_on > 0 || dualsense_dev->led_delay_off > 0; + const bool wireless = dev->cable_state == 0; + const bool low_battery = dev->battery_level <= 1; + const bool is_blinking = dev->led_delay_on > 0 || dev->led_delay_off > 0; // Blink LED when battery is low if (config->led_low_battery_blink) @@ -953,71 +956,75 @@ void dualsense_pad_handler::apply_pad_data(const pad_ensemble& binding) // we are now wired or have okay battery level -> stop blinking if (is_blinking && !(wireless && low_battery)) { - dualsense_dev->lightbar_on = true; - dualsense_dev->led_delay_on = 0; - dualsense_dev->led_delay_off = 0; - dualsense_dev->update_lightbar = true; + dev->lightbar_on = true; + dev->led_delay_on = 0; + dev->led_delay_off = 0; + dev->update_lightbar = true; } // we are now wireless and low on battery -> blink else if (!is_blinking && wireless && low_battery) { - dualsense_dev->led_delay_on = 100; - dualsense_dev->led_delay_off = 100; - dualsense_dev->update_lightbar = true; + dev->led_delay_on = 100; + dev->led_delay_off = 100; + dev->update_lightbar = true; } // Turn lightbar on and off in an interval. I wanted to do an automatic pulse, but I haven't found out how to do that yet. - if (dualsense_dev->led_delay_on > 0) + if (dev->led_delay_on > 0) { - if (const steady_clock::time_point now = steady_clock::now(); (now - dualsense_dev->last_lightbar_time) > 500ms) + if (const steady_clock::time_point now = steady_clock::now(); (now - dev->last_lightbar_time) > 500ms) { - dualsense_dev->lightbar_on = !dualsense_dev->lightbar_on; - dualsense_dev->last_lightbar_time = now; - dualsense_dev->update_lightbar = true; + dev->lightbar_on = !dev->lightbar_on; + dev->last_lightbar_time = now; + dev->update_lightbar = true; } } } - else if (!dualsense_dev->lightbar_on) + else if (!dev->lightbar_on) { - dualsense_dev->lightbar_on = true; - dualsense_dev->update_lightbar = true; + dev->lightbar_on = true; + dev->update_lightbar = true; } // Use LEDs to indicate battery level if (config->led_battery_indicator) { // This makes sure that the LED color doesn't update every 1ms. DS4 only reports battery level in 10% increments - if (dualsense_dev->last_battery_level != dualsense_dev->battery_level) + if (dev->last_battery_level != dev->battery_level) { - const u32 combined_color = get_battery_color(dualsense_dev->battery_level, config->led_battery_indicator_brightness); + const u32 combined_color = get_battery_color(dev->battery_level, config->led_battery_indicator_brightness); config->colorR.set(combined_color >> 8); config->colorG.set(combined_color & 0xff); config->colorB.set(0); - dualsense_dev->update_lightbar = true; - dualsense_dev->last_battery_level = dualsense_dev->battery_level; + dev->update_lightbar = true; + dev->last_battery_level = dev->battery_level; } } - if (dualsense_dev->enable_player_leds != config->player_led_enabled.get()) + if (dev->enable_player_leds != config->player_led_enabled.get()) { - dualsense_dev->enable_player_leds = config->player_led_enabled.get(); - dualsense_dev->update_player_leds = true; + dev->enable_player_leds = config->player_led_enabled.get(); + dev->update_player_leds = true; } - dualsense_dev->new_output_data |= dualsense_dev->release_leds || dualsense_dev->update_player_leds || dualsense_dev->update_lightbar || dualsense_dev->large_motor != speed_large || dualsense_dev->small_motor != speed_small; + dev->new_output_data |= dev->release_leds || dev->update_player_leds || dev->update_lightbar || dev->large_motor != speed_large || dev->small_motor != speed_small; - dualsense_dev->large_motor = speed_large; - dualsense_dev->small_motor = speed_small; + dev->large_motor = speed_large; + dev->small_motor = speed_small; - if (dualsense_dev->new_output_data) + const auto now = steady_clock::now(); + const auto elapsed = now - dev->last_output; + + if (dev->new_output_data || elapsed > min_output_interval) { - if (const int res = send_output_report(dualsense_dev); res >= 0) + if (const int res = send_output_report(dev); res >= 0) { - dualsense_dev->new_output_data = false; + dev->new_output_data = false; + dev->last_output = now; } else if (res == -1) { - dualsense_log.error("apply_pad_data: send_output_report failed! error=%s", hid_error(dualsense_dev->hidDevice)); + dualsense_log.error("apply_pad_data: send_output_report failed! error=%s", hid_error(dev->hidDevice)); } } } diff --git a/rpcs3/Input/dualsense_pad_handler.h b/rpcs3/Input/dualsense_pad_handler.h index 1a0ad46f0d..ac2b2afba8 100644 --- a/rpcs3/Input/dualsense_pad_handler.h +++ b/rpcs3/Input/dualsense_pad_handler.h @@ -243,7 +243,7 @@ public: void init_config(cfg_pad* cfg) override; private: - bool get_calibration_data(DualSenseDevice* dualsense_device) const; + bool get_calibration_data(DualSenseDevice* dev) const; DataStatus get_data(DualSenseDevice* device) override; void check_add_device(hid_device* hidDevice, std::string_view path, std::wstring_view wide_serial) override; diff --git a/rpcs3/Input/evdev_joystick_handler.cpp b/rpcs3/Input/evdev_joystick_handler.cpp index 89447fee34..d885fd30fa 100644 --- a/rpcs3/Input/evdev_joystick_handler.cpp +++ b/rpcs3/Input/evdev_joystick_handler.cpp @@ -587,15 +587,18 @@ void evdev_joystick_handler::SetRumble(EvdevDevice* device, u8 large, u8 small) if (fd < 0) return; - if (large == device->large_motor && small == device->small_motor) - return; + device->new_output_data = large != device->large_motor || small != device->small_motor; + + const auto now = steady_clock::now(); + const auto elapsed = now - device->last_output; // XBox One Controller can't handle faster vibration updates than ~10ms. Elite is even worse. // So I'll use 20ms to be on the safe side. No lag was noticable. - if (clock() - device->last_vibration < 20) + if ((!device->new_output_data || elapsed <= 20ms) && elapsed <= min_output_interval) return; - device->last_vibration = clock(); + device->new_output_data = false; + device->last_output = now; // delete the previous effect (which also stops it) if (device->effect_id != -1) diff --git a/rpcs3/Input/evdev_joystick_handler.h b/rpcs3/Input/evdev_joystick_handler.h index 3ac4fd1df0..f90fe12038 100644 --- a/rpcs3/Input/evdev_joystick_handler.h +++ b/rpcs3/Input/evdev_joystick_handler.h @@ -396,7 +396,6 @@ class evdev_joystick_handler final : public PadHandlerBase int effect_id = -1; bool has_rumble = false; bool has_motion = false; - clock_t last_vibration = 0; }; public: diff --git a/rpcs3/Input/hid_pad_handler.h b/rpcs3/Input/hid_pad_handler.h index 7dcdae31e2..5293eb4981 100644 --- a/rpcs3/Input/hid_pad_handler.h +++ b/rpcs3/Input/hid_pad_handler.h @@ -34,7 +34,6 @@ public: hid_device* hidDevice{nullptr}; std::string path; - bool new_output_data{true}; bool enable_player_leds{false}; u8 led_delay_on{0}; u8 led_delay_off{0}; diff --git a/rpcs3/Input/mm_joystick_handler.cpp b/rpcs3/Input/mm_joystick_handler.cpp index 1ea805a022..3d48efccf9 100644 --- a/rpcs3/Input/mm_joystick_handler.cpp +++ b/rpcs3/Input/mm_joystick_handler.cpp @@ -169,20 +169,20 @@ std::array, PadHandlerBase::button::button_count> mm_joystick_hand { std::array, button::button_count> mapping{}; - MMJOYDevice* joy_device = static_cast(device.get()); - if (!joy_device || !cfg) + MMJOYDevice* dev = static_cast(device.get()); + if (!dev || !cfg) return mapping; - joy_device->trigger_code_left = find_keys(cfg->l2); - joy_device->trigger_code_right = find_keys(cfg->r2); - joy_device->axis_code_left[0] = find_keys(cfg->ls_left); - joy_device->axis_code_left[1] = find_keys(cfg->ls_right); - joy_device->axis_code_left[2] = find_keys(cfg->ls_down); - joy_device->axis_code_left[3] = find_keys(cfg->ls_up); - joy_device->axis_code_right[0] = find_keys(cfg->rs_left); - joy_device->axis_code_right[1] = find_keys(cfg->rs_right); - joy_device->axis_code_right[2] = find_keys(cfg->rs_down); - joy_device->axis_code_right[3] = find_keys(cfg->rs_up); + dev->trigger_code_left = find_keys(cfg->l2); + dev->trigger_code_right = find_keys(cfg->r2); + dev->axis_code_left[0] = find_keys(cfg->ls_left); + dev->axis_code_left[1] = find_keys(cfg->ls_right); + dev->axis_code_left[2] = find_keys(cfg->ls_down); + dev->axis_code_left[3] = find_keys(cfg->ls_up); + dev->axis_code_right[0] = find_keys(cfg->rs_left); + dev->axis_code_right[1] = find_keys(cfg->rs_right); + dev->axis_code_right[2] = find_keys(cfg->rs_down); + dev->axis_code_right[3] = find_keys(cfg->rs_up); mapping[button::up] = find_keys(cfg->up); mapping[button::down] = find_keys(cfg->down); @@ -193,22 +193,22 @@ std::array, PadHandlerBase::button::button_count> mm_joystick_hand mapping[button::circle] = find_keys(cfg->circle); mapping[button::triangle] = find_keys(cfg->triangle); mapping[button::l1] = find_keys(cfg->l1); - mapping[button::l2] = narrow_set(joy_device->trigger_code_left); + mapping[button::l2] = narrow_set(dev->trigger_code_left); mapping[button::l3] = find_keys(cfg->l3); mapping[button::r1] = find_keys(cfg->r1); - mapping[button::r2] = narrow_set(joy_device->trigger_code_right); + mapping[button::r2] = narrow_set(dev->trigger_code_right); mapping[button::r3] = find_keys(cfg->r3); mapping[button::start] = find_keys(cfg->start); mapping[button::select] = find_keys(cfg->select); mapping[button::ps] = find_keys(cfg->ps); - mapping[button::ls_left] = narrow_set(joy_device->axis_code_left[0]); - mapping[button::ls_right] = narrow_set(joy_device->axis_code_left[1]); - mapping[button::ls_down] = narrow_set(joy_device->axis_code_left[2]); - mapping[button::ls_up] = narrow_set(joy_device->axis_code_left[3]); - mapping[button::rs_left] = narrow_set(joy_device->axis_code_right[0]); - mapping[button::rs_right] = narrow_set(joy_device->axis_code_right[1]); - mapping[button::rs_down] = narrow_set(joy_device->axis_code_right[2]); - mapping[button::rs_up] = narrow_set(joy_device->axis_code_right[3]); + mapping[button::ls_left] = narrow_set(dev->axis_code_left[0]); + mapping[button::ls_right] = narrow_set(dev->axis_code_left[1]); + mapping[button::ls_down] = narrow_set(dev->axis_code_left[2]); + mapping[button::ls_up] = narrow_set(dev->axis_code_left[3]); + mapping[button::rs_left] = narrow_set(dev->axis_code_right[0]); + mapping[button::rs_right] = narrow_set(dev->axis_code_right[1]); + mapping[button::rs_down] = narrow_set(dev->axis_code_right[2]); + mapping[button::rs_up] = narrow_set(dev->axis_code_right[3]); mapping[button::skateboard_ir_nose] = find_keys(cfg->ir_nose); mapping[button::skateboard_ir_tail] = find_keys(cfg->ir_tail); diff --git a/rpcs3/Input/sdl_pad_handler.cpp b/rpcs3/Input/sdl_pad_handler.cpp index 65d5628c13..cc3b171428 100644 --- a/rpcs3/Input/sdl_pad_handler.cpp +++ b/rpcs3/Input/sdl_pad_handler.cpp @@ -114,9 +114,6 @@ private: bool m_initialized = false; }; -constexpr u32 rumble_duration_ms = 500; // Some high number to keep rumble updates at a minimum. -constexpr u32 rumble_refresh_ms = rumble_duration_ms - 100; // We need to keep updating the rumble. Choose a refresh timeout that is unlikely to run into missed rumble updates. - sdl_pad_handler::sdl_pad_handler() : PadHandlerBase(pad_handler::sdl) { button_list = @@ -792,21 +789,21 @@ void sdl_pad_handler::apply_pad_data(const pad_ensemble& binding) const u8 speed_large = cfg->enable_vibration_motor_large ? pad->m_vibrateMotors[idx_l].m_value : 0; const u8 speed_small = cfg->enable_vibration_motor_small ? pad->m_vibrateMotors[idx_s].m_value : 0; - dev->has_new_rumble_data |= dev->large_motor != speed_large || dev->small_motor != speed_small; + dev->new_output_data |= dev->large_motor != speed_large || dev->small_motor != speed_small; dev->large_motor = speed_large; dev->small_motor = speed_small; - const steady_clock::time_point now = steady_clock::now(); - const s64 elapsed_ms = std::chrono::duration_cast(now - dev->last_vibration).count(); + const auto now = steady_clock::now(); + const auto elapsed = now - dev->last_output; // XBox One Controller can't handle faster vibration updates than ~10ms. Elite is even worse. So I'll use 20ms to be on the safe side. No lag was noticable. - if ((dev->has_new_rumble_data && elapsed_ms > 20) || (elapsed_ms > rumble_refresh_ms)) + if ((dev->new_output_data && elapsed > 20ms) || elapsed > min_output_interval) { set_rumble(dev, speed_large, speed_small); - dev->has_new_rumble_data = false; - dev->last_vibration = steady_clock::now(); + dev->new_output_data = false; + dev->last_output = now; } } @@ -880,6 +877,8 @@ void sdl_pad_handler::set_rumble(SDLDevice* dev, u8 speed_large, u8 speed_small) { if (!dev || !dev->sdl.game_controller) return; + constexpr u32 rumble_duration_ms = static_cast((min_output_interval + 100ms).count()); // Some number higher than the min_output_interval. + if (dev->sdl.has_rumble) { if (SDL_GameControllerRumble(dev->sdl.game_controller, speed_large * 257, speed_small * 257, rumble_duration_ms) != 0) diff --git a/rpcs3/Input/sdl_pad_handler.h b/rpcs3/Input/sdl_pad_handler.h index 1ac8398474..f4fa256d29 100644 --- a/rpcs3/Input/sdl_pad_handler.h +++ b/rpcs3/Input/sdl_pad_handler.h @@ -64,9 +64,6 @@ public: bool led_is_on = true; bool led_is_blinking = false; steady_clock::time_point led_timestamp{}; - - bool has_new_rumble_data = true; - steady_clock::time_point last_vibration{}; }; class sdl_pad_handler : public PadHandlerBase diff --git a/rpcs3/Input/skateboard_pad_handler.cpp b/rpcs3/Input/skateboard_pad_handler.cpp index 20fafa739b..372ff2c5ec 100644 --- a/rpcs3/Input/skateboard_pad_handler.cpp +++ b/rpcs3/Input/skateboard_pad_handler.cpp @@ -228,39 +228,38 @@ skateboard_pad_handler::DataStatus skateboard_pad_handler::get_data(skateboard_d PadHandlerBase::connection skateboard_pad_handler::update_connection(const std::shared_ptr& device) { - skateboard_device* skateboard_dev = static_cast(device.get()); - if (!skateboard_dev || skateboard_dev->path.empty()) + skateboard_device* dev = static_cast(device.get()); + if (!dev || dev->path.empty()) return connection::disconnected; - if (skateboard_dev->hidDevice == nullptr) + if (dev->hidDevice == nullptr) { // try to reconnect - hid_device* dev = hid_open_path(skateboard_dev->path.c_str()); - if (dev) + if (hid_device* hid_dev = hid_open_path(dev->path.c_str())) { - if (hid_set_nonblocking(dev, 1) == -1) + if (hid_set_nonblocking(hid_dev, 1) == -1) { - skateboard_log.error("Reconnecting Device %s: hid_set_nonblocking failed with error %s", skateboard_dev->path, hid_error(dev)); + skateboard_log.error("Reconnecting Device %s: hid_set_nonblocking failed with error %s", dev->path, hid_error(hid_dev)); } - skateboard_dev->hidDevice = dev; + dev->hidDevice = hid_dev; } else { // nope, not there - skateboard_log.error("Device %s: disconnected", skateboard_dev->path); + skateboard_log.error("Device %s: disconnected", dev->path); return connection::disconnected; } } - if (get_data(skateboard_dev) == DataStatus::ReadError) + if (get_data(dev) == DataStatus::ReadError) { // this also can mean disconnected, either way deal with it on next loop and reconnect - skateboard_dev->close(); + dev->close(); return connection::no_data; } - if (!skateboard_dev->skateboard_is_on) + if (!dev->skateboard_is_on) { // This means that the dongle is still connected, but the skateboard is turned off. // There is no need to reconnect the hid device again, we just have to check the input report for proper data. @@ -356,17 +355,22 @@ void skateboard_pad_handler::apply_pad_data(const pad_ensemble& binding) dev->new_output_data = false; - if (dev->new_output_data) - { - if (const int res = send_output_report(dev); res >= 0) - { - dev->new_output_data = false; - } - else if (res == -1) - { - skateboard_log.error("apply_pad_data: send_output_report failed! error=%s", hid_error(dev->hidDevice)); - } - } + // Disabled until needed + //const auto now = steady_clock::now(); + //const auto elapsed = now - dev->last_output; + + //if (dev->new_output_data || elapsed > min_output_interval) + //{ + // if (const int res = send_output_report(dev); res >= 0) + // { + // dev->new_output_data = false; + // dev->last_output = now; + // } + // else if (res == -1) + // { + // skateboard_log.error("apply_pad_data: send_output_report failed! error=%s", hid_error(dev->hidDevice)); + // } + //} } void skateboard_pad_handler::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*/) diff --git a/rpcs3/Input/xinput_pad_handler.cpp b/rpcs3/Input/xinput_pad_handler.cpp index 3929d860df..4088a08f90 100644 --- a/rpcs3/Input/xinput_pad_handler.cpp +++ b/rpcs3/Input/xinput_pad_handler.cpp @@ -142,10 +142,11 @@ void xinput_pad_handler::SetPadData(const std::string& padId, u8 /*player_id*/, // 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. - XINPUT_VIBRATION vibrate; - - vibrate.wLeftMotorSpeed = large_motor * 257; // between 0 to 65535 - vibrate.wRightMotorSpeed = small_motor * 257; // between 0 to 65535 + XINPUT_VIBRATION vibrate + { + .wLeftMotorSpeed = static_cast(large_motor * 257), // between 0 to 65535 + .wRightMotorSpeed = static_cast(small_motor * 257) // between 0 to 65535 + }; xinputSetState(static_cast(device_number), &vibrate); } @@ -449,10 +450,10 @@ std::shared_ptr xinput_pad_handler::get_device(const std::string& dev if (device_number < 0) return nullptr; - std::shared_ptr x_device = std::make_shared(); - x_device->deviceNumber = static_cast(device_number); + std::shared_ptr dev = std::make_shared(); + dev->deviceNumber = static_cast(device_number); - return x_device; + return dev; } bool xinput_pad_handler::get_is_left_trigger(const std::shared_ptr& /*device*/, u64 keyCode) @@ -568,22 +569,27 @@ void xinput_pad_handler::apply_pad_data(const pad_ensemble& binding) const u8 speed_large = cfg->enable_vibration_motor_large ? pad->m_vibrateMotors[idx_l].m_value : 0; const u8 speed_small = cfg->enable_vibration_motor_small ? pad->m_vibrateMotors[idx_s].m_value : 0; - dev->newVibrateData |= dev->large_motor != speed_large || dev->small_motor != speed_small; + dev->new_output_data |= dev->large_motor != speed_large || dev->small_motor != speed_small; dev->large_motor = speed_large; dev->small_motor = speed_small; + const auto now = steady_clock::now(); + const auto elapsed = now - dev->last_output; + // XBox One Controller can't handle faster vibration updates than ~10ms. Elite is even worse. So I'll use 20ms to be on the safe side. No lag was noticable. - if (dev->newVibrateData && steady_clock::now() - dev->last_vibration > 20ms) + if ((dev->new_output_data && elapsed > 20ms) || elapsed > min_output_interval) { - XINPUT_VIBRATION vibrate; - vibrate.wLeftMotorSpeed = speed_large * 257; // between 0 to 65535 - vibrate.wRightMotorSpeed = speed_small * 257; // between 0 to 65535 + XINPUT_VIBRATION vibrate + { + .wLeftMotorSpeed = static_cast(speed_large * 257), // between 0 to 65535 + .wRightMotorSpeed = static_cast(speed_small * 257) // between 0 to 65535 + }; if (xinputSetState(padnum, &vibrate) == ERROR_SUCCESS) { - dev->newVibrateData = false; - dev->last_vibration = steady_clock::now(); + dev->new_output_data = false; + dev->last_output = now; } } } diff --git a/rpcs3/Input/xinput_pad_handler.h b/rpcs3/Input/xinput_pad_handler.h index f401090181..7c4d7a814e 100644 --- a/rpcs3/Input/xinput_pad_handler.h +++ b/rpcs3/Input/xinput_pad_handler.h @@ -98,8 +98,6 @@ class xinput_pad_handler final : public PadHandlerBase struct XInputDevice : public PadDevice { u32 deviceNumber{ 0 }; - bool newVibrateData{ true }; - steady_clock::time_point last_vibration; bool is_scp_device{ false }; DWORD state{ ERROR_NOT_CONNECTED }; // holds internal controller state change SCP_EXTN state_scp{};