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 "Emu/Io/pad_config.h"
#include <limits>
LOG_CHANNEL(ds4_log, "DS4");
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)
{
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]);
@ -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
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)
{
ds4_log.error("GetCalibrationData: Failure: sens_denom == 0");
return false;
ds4_log.error("GetCalibrationData: Invalid accelerometer calibration data for axis %d, disabling calibration.", i);
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)
{
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)
{
const s16 rawValue = read_s16(&buf[calibOffset]);
const s16 calValue = apply_calibration(rawValue, device->calib_data[i]);
buf[calibOffset++] = (static_cast<u16>(calValue) >> 0) & 0xFF;
buf[calibOffset++] = (static_cast<u16>(calValue) >> 8) & 0xFF;
const s16 raw_value = read_s16(&buf[calib_offset]);
const s16 cal_value = apply_calibration(raw_value, device->calib_data[i]);
buf[calib_offset++] = (static_cast<u16>(cal_value) >> 0) & 0xFF;
buf[calib_offset++] = (static_cast<u16>(cal_value) >> 8) & 0xFF;
}
}

View file

@ -2,6 +2,8 @@
#include "dualsense_pad_handler.h"
#include "Emu/Io/pad_config.h"
#include <limits>
LOG_CHANNEL(dualsense_log, "DualSense");
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",
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]);
@ -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
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)
{
dualsense_log.error("get_calibration_data: Failure: sens_denom == 0");
return false;
dualsense_log.error("GetCalibrationData: Invalid accelerometer calibration data for axis %d, disabling calibration.", i);
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
{
s16 bias;
s32 sens_numer;
s32 sens_denom;
s16 bias = 0;
s32 sens_numer = 0;
s32 sens_denom = 0;
};
enum CalibIndex
@ -87,12 +87,12 @@ protected:
virtual int send_output_report(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 quot = calibData.sens_numer / calibData.sens_denom;
const s32 rem = calibData.sens_numer % calibData.sens_denom;
const s32 output = (quot * biased) + ((rem * biased) / calibData.sens_denom);
const s32 biased = raw_value - calib_data.bias;
const s32 quot = calib_data.sens_numer / calib_data.sens_denom;
const s32 rem = calib_data.sens_numer % calib_data.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}));
}