input: invalidate ds4/dualsense calibration instead of disabling the controller

This commit is contained in:
Megamouse 2024-06-26 20:48:52 +02:00
parent b251d81065
commit 78cb7963fb
3 changed files with 31 additions and 21 deletions

View File

@ -2,6 +2,8 @@
#include "ds4_pad_handler.h" #include "ds4_pad_handler.h"
#include "Emu/Io/pad_config.h" #include "Emu/Io/pad_config.h"
#include <limits>
LOG_CHANNEL(ds4_log, "DS4"); LOG_CHANNEL(ds4_log, "DS4");
constexpr id_pair SONY_DS4_ID_0 = {0x054C, 0x0BA0}; // Dongle constexpr id_pair SONY_DS4_ID_0 = {0x054C, 0x0BA0}; // Dongle
@ -427,7 +429,6 @@ bool ds4_pad_handler::GetCalibrationData(DS4Device* ds4Dev) const
pitchNeg >= 0 || yawNeg >= 0 || rollNeg >= 0) pitchNeg >= 0 || yawNeg >= 0 || rollNeg >= 0)
{ {
ds4_log.error("GetCalibrationData: calibration data check failed! pitchPlus=%d, pitchNeg=%d, rollPlus=%d, rollNeg=%d, yawPlus=%d, yawNeg=%d", pitchPlus, pitchNeg, rollPlus, rollNeg, yawPlus, yawNeg); ds4_log.error("GetCalibrationData: calibration data check failed! pitchPlus=%d, pitchNeg=%d, rollPlus=%d, rollNeg=%d, yawPlus=%d, yawNeg=%d", pitchPlus, pitchNeg, rollPlus, rollNeg, yawPlus, yawNeg);
return false;
} }
const s32 gyroSpeedScale = read_s16(&buf[19]) + read_s16(&buf[21]); const s32 gyroSpeedScale = read_s16(&buf[19]) + read_s16(&buf[21]);
@ -465,12 +466,16 @@ bool ds4_pad_handler::GetCalibrationData(DS4Device* ds4Dev) const
// Make sure data 'looks' valid, dongle will report invalid calibration data with no controller connected // Make sure data 'looks' valid, dongle will report invalid calibration data with no controller connected
for (const auto& data : ds4Dev->calib_data) for (size_t i = 0; i < ds4Dev->calib_data.size(); i++)
{ {
CalibData& data = ds4Dev->calib_data[i];
if (data.sens_denom == 0) if (data.sens_denom == 0)
{ {
ds4_log.error("GetCalibrationData: Failure: sens_denom == 0"); ds4_log.error("GetCalibrationData: Invalid accelerometer calibration data for axis %d, disabling calibration.", i);
return false; data.bias = 0;
data.sens_numer = 4 * DS4_ACC_RES_PER_G;
data.sens_denom = std::numeric_limits<s16>::max();
} }
} }
@ -693,13 +698,13 @@ ds4_pad_handler::DataStatus ds4_pad_handler::get_data(DS4Device* device)
if (device->has_calib_data) if (device->has_calib_data)
{ {
int calibOffset = offset + offsetof(ds4_input_report_common, gyro); int calib_offset = offset + offsetof(ds4_input_report_common, gyro);
for (int i = 0; i < CalibIndex::COUNT; ++i) for (int i = 0; i < CalibIndex::COUNT; ++i)
{ {
const s16 rawValue = read_s16(&buf[calibOffset]); const s16 raw_value = read_s16(&buf[calib_offset]);
const s16 calValue = apply_calibration(rawValue, device->calib_data[i]); const s16 cal_value = apply_calibration(raw_value, device->calib_data[i]);
buf[calibOffset++] = (static_cast<u16>(calValue) >> 0) & 0xFF; buf[calib_offset++] = (static_cast<u16>(cal_value) >> 0) & 0xFF;
buf[calibOffset++] = (static_cast<u16>(calValue) >> 8) & 0xFF; buf[calib_offset++] = (static_cast<u16>(cal_value) >> 8) & 0xFF;
} }
} }

View File

@ -2,6 +2,8 @@
#include "dualsense_pad_handler.h" #include "dualsense_pad_handler.h"
#include "Emu/Io/pad_config.h" #include "Emu/Io/pad_config.h"
#include <limits>
LOG_CHANNEL(dualsense_log, "DualSense"); LOG_CHANNEL(dualsense_log, "DualSense");
template <> template <>
@ -462,7 +464,6 @@ bool dualsense_pad_handler::get_calibration_data(DualSenseDevice* dualsense_devi
{ {
dualsense_log.error("get_calibration_data: calibration data check failed! pitch_plus=%d, pitch_minus=%d, roll_plus=%d, roll_minus=%d, yaw_plus=%d, yaw_minus=%d", dualsense_log.error("get_calibration_data: calibration data check failed! pitch_plus=%d, pitch_minus=%d, roll_plus=%d, roll_minus=%d, yaw_plus=%d, yaw_minus=%d",
pitch_plus, pitch_minus, roll_plus, roll_minus, yaw_plus, yaw_minus); pitch_plus, pitch_minus, roll_plus, roll_minus, yaw_plus, yaw_minus);
return false;
} }
const s32 gyro_speed_scale = read_s16(&buf[19]) + read_s16(&buf[21]); const s32 gyro_speed_scale = read_s16(&buf[19]) + read_s16(&buf[21]);
@ -501,12 +502,16 @@ bool dualsense_pad_handler::get_calibration_data(DualSenseDevice* dualsense_devi
// Make sure data 'looks' valid, dongle will report invalid calibration data with no controller connected // Make sure data 'looks' valid, dongle will report invalid calibration data with no controller connected
for (const CalibData& data : dualsense_device->calib_data) for (size_t i = 0; i < dualsense_device->calib_data.size(); i++)
{ {
CalibData& data = dualsense_device->calib_data[i];
if (data.sens_denom == 0) if (data.sens_denom == 0)
{ {
dualsense_log.error("get_calibration_data: Failure: sens_denom == 0"); dualsense_log.error("GetCalibrationData: Invalid accelerometer calibration data for axis %d, disabling calibration.", i);
return false; data.bias = 0;
data.sens_numer = 4 * DUALSENSE_ACC_RES_PER_G;
data.sens_denom = std::numeric_limits<s16>::max();
} }
} }

View File

@ -8,9 +8,9 @@
struct CalibData struct CalibData
{ {
s16 bias; s16 bias = 0;
s32 sens_numer; s32 sens_numer = 0;
s32 sens_denom; s32 sens_denom = 0;
}; };
enum CalibIndex enum CalibIndex
@ -87,12 +87,12 @@ protected:
virtual int send_output_report(Device* device) = 0; virtual int send_output_report(Device* device) = 0;
virtual DataStatus get_data(Device* device) = 0; virtual DataStatus get_data(Device* device) = 0;
static s16 apply_calibration(s32 rawValue, const CalibData& calibData) static s16 apply_calibration(s32 raw_value, const CalibData& calib_data)
{ {
const s32 biased = rawValue - calibData.bias; const s32 biased = raw_value - calib_data.bias;
const s32 quot = calibData.sens_numer / calibData.sens_denom; const s32 quot = calib_data.sens_numer / calib_data.sens_denom;
const s32 rem = calibData.sens_numer % calibData.sens_denom; const s32 rem = calib_data.sens_numer % calib_data.sens_denom;
const s32 output = (quot * biased) + ((rem * biased) / calibData.sens_denom); const s32 output = (quot * biased) + ((rem * biased) / calib_data.sens_denom);
return static_cast<s16>(std::clamp<s32>(output, s16{smin}, s16{smax})); return static_cast<s16>(std::clamp<s32>(output, s16{smin}, s16{smax}));
} }