Skip to content

Commit

Permalink
Properly remove Adaptive Trigger force feedback when impulse vibratio…
Browse files Browse the repository at this point in the history
…n stops
  • Loading branch information
Kaldaien committed Nov 30, 2024
1 parent e1a65a6 commit d599fd9
Show file tree
Hide file tree
Showing 5 changed files with 106 additions and 26 deletions.
6 changes: 5 additions & 1 deletion CHANGELOG.txt
Original file line number Diff line number Diff line change
@@ -1,4 +1,8 @@
24.11.30.2
24.11.30.3
==========
+ Properly remove Adaptive Trigger force feedback when impulse vibration stops

24.11.30.2
==========
+ Implement PlayStation Adaptive Trigger support for DualSense controllers
connected using Bluetooth.
Expand Down
52 changes: 52 additions & 0 deletions depends/src/DirectXTex/DirectXTex_Desktop_2015.suppress
Original file line number Diff line number Diff line change
@@ -0,0 +1,52 @@
<?xml version="1.0" standalone="yes"?>
<NewDataSet>
<xs:schema id="NewDataSet" xmlns="" xmlns:xs="http://www.w3.org/2001/XMLSchema" xmlns:msdata="urn:schemas-microsoft-com:xml-msdata">
<xs:element name="NewDataSet" msdata:IsDataSet="true" msdata:UseCurrentLocale="true">
<xs:complexType>
<xs:choice minOccurs="0" maxOccurs="unbounded">
<xs:element name="SuppressVersion">
<xs:complexType>
<xs:sequence>
<xs:element name="CurrentVersion" type="xs:int" minOccurs="0" />
<xs:element name="IsPrimary" type="xs:boolean" minOccurs="0" />
</xs:sequence>
</xs:complexType>
</xs:element>
<xs:element name="DirectXTex" msdata:CaseSensitive="False">
<xs:complexType>
<xs:sequence>
<xs:element name="FileName" type="xs:string" default="" />
<xs:element name="ErrorCode" type="xs:string" default="" />
<xs:element name="Message" type="xs:string" default="" />
<xs:element name="CodePrev" type="xs:unsignedInt" default="0" />
<xs:element name="CodeCurrent" type="xs:unsignedInt" default="0" />
<xs:element name="CodeNext" type="xs:unsignedInt" default="0" />
</xs:sequence>
</xs:complexType>
</xs:element>
</xs:choice>
</xs:complexType>
<xs:unique name="Constraint1" msdata:PrimaryKey="true">
<xs:selector xpath=".//DirectXTex" />
<xs:field xpath="FileName" />
<xs:field xpath="ErrorCode" />
<xs:field xpath="Message" />
<xs:field xpath="CodePrev" />
<xs:field xpath="CodeCurrent" />
<xs:field xpath="CodeNext" />
</xs:unique>
</xs:element>
</xs:schema>
<SuppressVersion>
<CurrentVersion>3</CurrentVersion>
<IsPrimary>false</IsPrimary>
</SuppressVersion>
<DirectXTex>
<FileName>debug_utils.h</FileName>
<ErrorCode>V802</ErrorCode>
<Message>On _-bit platform, structure size can be reduced from _ to _ bytes by rearranging the fields according to their sizes in decreasing order.</Message>
<CodePrev>1907953360</CodePrev>
<CodeCurrent>123</CodeCurrent>
<CodeNext>14801337</CodeNext>
</DirectXTex>
</NewDataSet>
4 changes: 2 additions & 2 deletions include/SpecialK/DLL_VERSION.H
Original file line number Diff line number Diff line change
Expand Up @@ -3,8 +3,8 @@
#define SK_YEAR 24
#define SK_MONTH 11
#define SK_DATE 30
#define SK_REV_N 2
#define SK_REV 2
#define SK_REV_N 3
#define SK_REV 3

#ifndef _A2
#define _A2(a) #a
Expand Down
4 changes: 3 additions & 1 deletion include/SpecialK/input/input.h
Original file line number Diff line number Diff line change
Expand Up @@ -1044,6 +1044,8 @@ struct SK_HID_PlayStationDevice
struct {
volatile ULONG left;
volatile ULONG right;
ULONG last_left;
ULONG last_right;
} trigger;

volatile ULONG max_val = 0;
Expand All @@ -1052,7 +1054,7 @@ struct SK_HID_PlayStationDevice
// some kind of attempt to set a new value... otherwise, it
// will tend to vibrate infinitely.
static constexpr auto MAX_TTL_IN_MSECS = 1000UL;
} _vibration = { 0, 0, 0, 0, 0, 0 };
} _vibration = { 0, 0, 0, 0, 0, 0, 0, 0 };

void setRGB (BYTE red, BYTE green, BYTE blue) {
_color.r = red;
Expand Down
66 changes: 44 additions & 22 deletions src/input/hid_reports/playstation.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -2626,19 +2626,26 @@ SK_HID_PlayStationDevice::write_output_report (bool force)
SK_HID_DualSense_SetStateData* output =
(SK_HID_DualSense_SetStateData *)&pOutputRaw [1];

const ULONG dwRightMotor = ReadULongAcquire (&pDevice->_vibration.right);
const ULONG dwLeftMotor = ReadULongAcquire (&pDevice->_vibration.left);
const ULONG dwRightMotor = ReadULongAcquire (&pDevice->_vibration.right);
const ULONG dwLeftMotor = ReadULongAcquire (&pDevice->_vibration.left);
const ULONG dwRightTrigger = ReadULongAcquire (&pDevice->_vibration.trigger.right);
const ULONG dwLeftTrigger = ReadULongAcquire (&pDevice->_vibration.trigger.left);

const ULONG last_trigger_r = pDevice->_vibration.trigger.last_right;
const ULONG last_trigger_l = pDevice->_vibration.trigger.last_left;

const bool bRumble =
(dwRightMotor != 0 ||
dwLeftMotor != 0) || (ReadULongAcquire (&pDevice->_vibration.trigger.left) != 0
|| ReadULongAcquire (&pDevice->_vibration.trigger.right) != 0);
dwLeftMotor != 0) || (dwLeftTrigger != 0
|| dwRightTrigger != 0);

// 500 msec grace period before allowing controller to use native haptics
output->UseRumbleNotHaptics = bRumble ||
(ReadULongAcquire (&pDevice->_vibration.last_set) > SK::ControlPanel::current_time - 500UL);
(ReadULongAcquire (&pDevice->_vibration.last_set) > SK::ControlPanel::current_time - 500UL)
|| last_trigger_r != 0
|| last_trigger_l != 0;

if (bRumble)
if (bRumble || (last_trigger_r != 0 || last_trigger_l != 0))
{
WriteULongRelease (&pDevice->_vibration.last_set, SK::ControlPanel::current_time);
output->AllowMotorPowerLevel = true;
Expand Down Expand Up @@ -2674,31 +2681,35 @@ SK_HID_PlayStationDevice::write_output_report (bool force)
{ 0x06, 15, 63, 0, 0, 0, 0, 0, 0, 0, 0 },
};

if (bRumble)
if (bRumble || (last_trigger_r != 0 || last_trigger_l != 0))
{
if (pDevice->_vibration.trigger.left != 0)
if (dwLeftTrigger != 0)
{ output->AllowLeftTriggerFFB = true;
const auto trigger_effect = 2;
memcpy (output->LeftTriggerFFB, effects [trigger_effect], sizeof (effects [trigger_effect]));
output->LeftTriggerFFB [2] =
static_cast <uint8_t> (std::clamp (
static_cast <float> (pDevice->_vibration.trigger.left) *
static_cast <float> (dwLeftTrigger) *
config.input.gamepad.impulse_strength_l, 0.0f, 1.0f) );
} else { output->AllowLeftTriggerFFB = true;
pDevice->_vibration.trigger.last_left = dwLeftTrigger;
} else { output->AllowLeftTriggerFFB = true;
const auto trigger_effect = 0;
memcpy (output->LeftTriggerFFB, effects [trigger_effect], sizeof (effects [trigger_effect]));
pDevice->_vibration.trigger.last_left = dwLeftTrigger;
}
if (pDevice->_vibration.trigger.right != 0)
if (dwRightTrigger != 0)
{ output->AllowRightTriggerFFB = true;
const auto trigger_effect = 2;
memcpy (output->RightTriggerFFB, effects [trigger_effect], sizeof (effects [trigger_effect]));
output->RightTriggerFFB [2] =
static_cast <uint8_t> (std::clamp (
static_cast <float> (pDevice->_vibration.trigger.right) *
static_cast <float> (dwRightTrigger) *
config.input.gamepad.impulse_strength_r, 0.0f, 1.0f) );
pDevice->_vibration.trigger.last_right = dwRightTrigger;
} else { output->AllowRightTriggerFFB = true;
const auto trigger_effect = 0;
memcpy (output->RightTriggerFFB, effects [trigger_effect], sizeof (effects [trigger_effect]));
pDevice->_vibration.trigger.last_right = dwRightTrigger;
}
}

Expand Down Expand Up @@ -2817,17 +2828,24 @@ SK_HID_PlayStationDevice::write_output_report (bool force)
SK_HID_DualSense_SetStateData* output =
(SK_HID_DualSense_SetStateData *)&bt_data [3];

const ULONG dwRightMotor = ReadULongAcquire (&pDevice->_vibration.right);
const ULONG dwLeftMotor = ReadULongAcquire (&pDevice->_vibration.left);
const ULONG dwRightMotor = ReadULongAcquire (&pDevice->_vibration.right);
const ULONG dwLeftMotor = ReadULongAcquire (&pDevice->_vibration.left);
const ULONG dwRightTrigger = ReadULongAcquire (&pDevice->_vibration.trigger.right);
const ULONG dwLeftTrigger = ReadULongAcquire (&pDevice->_vibration.trigger.left);

const ULONG last_trigger_r = pDevice->_vibration.trigger.last_right;
const ULONG last_trigger_l = pDevice->_vibration.trigger.last_left;

const bool bRumble =
(dwRightMotor != 0 ||
dwLeftMotor != 0) || (ReadULongAcquire (&pDevice->_vibration.trigger.left) != 0
|| ReadULongAcquire (&pDevice->_vibration.trigger.right) != 0);
dwLeftMotor != 0) || (dwRightTrigger != 0
|| dwLeftTrigger != 0);

// 500 msec grace period before allowing controller to use native haptics
output->UseRumbleNotHaptics = bRumble ||
(ReadULongAcquire (&pDevice->_vibration.last_set) > SK::ControlPanel::current_time - 500UL);
(ReadULongAcquire (&pDevice->_vibration.last_set) > SK::ControlPanel::current_time - 500UL)
|| last_trigger_r != 0
|| last_trigger_l != 0;

if (bRumble)
{
Expand All @@ -2842,31 +2860,35 @@ SK_HID_PlayStationDevice::write_output_report (bool force)
{ 0x06, 15, 63, 0, 0, 0, 0, 0, 0, 0, 0 },
};

if (bRumble)
if (bRumble || (last_trigger_r != 0 || last_trigger_l != 0))
{
if (pDevice->_vibration.trigger.left != 0)
if (dwLeftTrigger != 0)
{ output->AllowLeftTriggerFFB = true;
const auto trigger_effect = 2;
memcpy (output->LeftTriggerFFB, effects [trigger_effect], sizeof (effects [trigger_effect]));
output->LeftTriggerFFB [2] =
static_cast <uint8_t> (std::clamp (
static_cast <float> (pDevice->_vibration.trigger.left) *
static_cast <float> (dwLeftTrigger) *
config.input.gamepad.impulse_strength_l, 0.0f, 1.0f) );
pDevice->_vibration.trigger.last_left = dwLeftTrigger;
} else { output->AllowLeftTriggerFFB = true;
const auto trigger_effect = 0;
memcpy (output->LeftTriggerFFB, effects [trigger_effect], sizeof (effects [trigger_effect]));
pDevice->_vibration.trigger.last_left = dwLeftTrigger;
}
if (pDevice->_vibration.trigger.right != 0)
if (dwRightTrigger != 0)
{ output->AllowRightTriggerFFB = true;
const auto trigger_effect = 2;
memcpy (output->RightTriggerFFB, effects [trigger_effect], sizeof (effects [trigger_effect]));
output->RightTriggerFFB [2] =
static_cast <uint8_t> (std::clamp (
static_cast <float> (pDevice->_vibration.trigger.right) *
static_cast <float> (dwRightTrigger) *
config.input.gamepad.impulse_strength_r, 0.0f, 1.0f) );
pDevice->_vibration.trigger.last_right = dwRightTrigger;
} else { output->AllowRightTriggerFFB = true;
const auto trigger_effect = 0;
memcpy (output->RightTriggerFFB, effects [trigger_effect], sizeof (effects [trigger_effect]));
pDevice->_vibration.trigger.last_right = dwRightTrigger;
}
}
output->AllowMuteLight = true;
Expand Down

0 comments on commit d599fd9

Please sign in to comment.