Skip to content

Commit

Permalink
Reduce latency on HID output reports (i.e. rumble, lighting changes, …
Browse files Browse the repository at this point in the history
…etc.)
  • Loading branch information
Kaldaien committed Dec 17, 2024
1 parent 9502d58 commit d9bbbbf
Show file tree
Hide file tree
Showing 7 changed files with 45 additions and 14 deletions.
7 changes: 6 additions & 1 deletion CHANGELOG.txt
Original file line number Diff line number Diff line change
@@ -1,4 +1,9 @@
24.12.17.1
24.12.17.2
==========
+ Reduce latency on HID output reports (i.e. rumble, lighting changes, etc.)
for DualShock 4 and DualSense{Edge} controllers.

24.12.17.1
==========
+ Revert ResizeTarget optimization from 24.12.15.4, because it only works as
intended in D3D11 games.
Expand Down
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 12
#define SK_DATE 17
#define SK_REV_N 1
#define SK_REV 1
#define SK_REV_N 2
#define SK_REV 2

#ifndef _A2
#define _A2(a) #a
Expand Down
3 changes: 3 additions & 0 deletions include/SpecialK/input/input.h
Original file line number Diff line number Diff line change
Expand Up @@ -962,6 +962,9 @@ struct SK_HID_PlayStationDevice
USHORT vid = 0x0;
USHORT pid = 0x0;

volatile UINT output_requests = 0;
volatile UINT input_requests = 0;

// Interpretation of reports using HID APIs
PHIDP_PREPARSED_DATA pPreparsedData = nullptr;

Expand Down
2 changes: 2 additions & 0 deletions src/input/game_input.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1049,6 +1049,8 @@ SK_IGameInputDevice::SetRumbleState (GameInputRumbleParams const *params) noexce
static_cast <USHORT> (std::min (65535UL, static_cast <ULONG> (std::clamp (params_.rightTrigger, 0.0f, 1.0f) * 65536.0f))),
65535ui16
);

pNewestInputDevice->write_output_report ();
}
}
}
Expand Down
20 changes: 15 additions & 5 deletions src/input/hid_reports/playstation.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -60,9 +60,8 @@ struct SK_HID_DualSense_GetHWAddr // 0x09 : USB
// indication that the device was removed is one of these error codes...
bool SK_HID_IsDisconnectedError (DWORD dwError)
{
return dwError == ERROR_INVALID_HANDLE ||
dwError == ERROR_NO_SUCH_DEVICE ||
dwError == ERROR_DEVICE_NOT_CONNECTED;
return dwError == ERROR_INVALID_HANDLE;// ||
//dwError == ERROR_DEVICE_NOT_CONNECTED;
}

SK_HID_PlayStationDevice::SK_HID_PlayStationDevice (HANDLE file)
Expand Down Expand Up @@ -1126,8 +1125,11 @@ SK_HID_PlayStationDevice::request_input_report (void)
WriteRelease (&bNeedOutput, TRUE);
}

InterlockedIncrement (&input_requests);

if (hInputEvent == nullptr)
{ hInputEvent =
{ std::scoped_lock _initlock(*xinput.lock_report);
hInputEvent =
SK_CreateEvent ( nullptr, TRUE, TRUE,
SK_FormatStringW (L"[SK] HID Input Report %p", hDeviceFile).c_str ());

Expand Down Expand Up @@ -1290,7 +1292,7 @@ SK_HID_PlayStationDevice::request_input_report (void)
// Input Report Waiting
if (dwWaitState == (WAIT_OBJECT_0 + 1))
{
std::scoped_lock __(*pDevice->xinput.lock_report);
std::scoped_lock __(*pDevice->xinput.lock_report);

DWORD dwBytesTransferred = 0;

Expand Down Expand Up @@ -2602,8 +2604,12 @@ SK_HID_PlayStationDevice::write_output_report (bool force)
return false;
}

InterlockedIncrement (&output_requests);

if (hOutputEnqueued == nullptr)
{
std::scoped_lock _initlock(*xinput.lock_report);

hOutputEnqueued =
SK_CreateEvent (nullptr, TRUE, TRUE, nullptr);

Expand Down Expand Up @@ -3332,8 +3338,12 @@ SK_HID_PlayStationDevice::write_output_report (bool force)
return false;
}

InterlockedIncrement (&output_requests);

if (hOutputEnqueued == nullptr)
{
std::scoped_lock _initlock(*xinput.lock_report);

hOutputEnqueued =
SK_CreateEvent (nullptr, TRUE, TRUE, nullptr);

Expand Down
8 changes: 8 additions & 0 deletions src/input/windows.gaming.input.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -671,6 +671,12 @@ WGI_Gamepad_put_Vibration_Override (ABI::Windows::Gaming::Input::IGamepad
// control panel.
SK_WGI_READ (SK_WGI_Backend, sk_input_dev_type::Gamepad);

if (config.input.gamepad.disable_rumble)
{
SK_XInput_ZeroHaptics (0);
return S_OK;
}

bool bRedirected = false;

SK_HID_PlayStationDevice *pNewestInputDevice = nullptr;
Expand Down Expand Up @@ -700,6 +706,8 @@ WGI_Gamepad_put_Vibration_Override (ABI::Windows::Gaming::Input::IGamepad
65535ui16
);

pNewestInputDevice->write_output_report ();

bRedirected = true;
}

Expand Down
15 changes: 9 additions & 6 deletions src/input/xinput_core.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -148,14 +148,17 @@ struct SK_XInputContext

if (! InterlockedCompareExchange (&haptic_warned [dwUserIndex], 1, 0))
{
SK_LOG0 ( ( L"WARNING: Recursive haptic feedback loop detected on XInput controller %lu!",
dwUserIndex ),
L" Input " );
if (! config.input.gamepad.xinput.emulate)
{
SK_LOG0 ( ( L"WARNING: Recursive haptic feedback loop detected on XInput controller %lu!",
dwUserIndex ),
L" Input " );

SK_ImGui_Warning (L"Problematic third-party XInput software detected (infinite haptic feedback loop), disabling vibration."
L"\n\n\tRestart your game to restore vibration support.");
SK_ImGui_Warning (L"Problematic third-party XInput software detected (infinite haptic feedback loop), disabling vibration."
L"\n\n\tRestart your game to restore vibration support.");

config.input.gamepad.xinput.hook_setstate = false;
config.input.gamepad.xinput.hook_setstate = false;
}
}

return true;
Expand Down

0 comments on commit d9bbbbf

Please sign in to comment.