Repository navigation
[Request] Add features byte info for DS4_OUTPUT_REPORT in DS4_REQUEST_NOTIFICATION struct #80
Description
Is your feature request related to a problem? Please describe.
Virtual DS4 rumble and lightbar passthru support has been a problem for a while but I have not had time to really look into it beforehand; I don't use the feature myself and I had removed support for it in DS4Windows at one point before mika-n added the routine back in the code. The feedback data returned by games can really differ and causes distinguishing between the type of event that the data represents virtually impossible. My main test games that provide native DS4 controller support are The Witcher 3 and Streets of Rage 4.
Currently, DS4Windows tries to make an effort to determine whether an event should be considered a rumble event, lightbar event, or both. The workaround was mainly made using test feedback data given while playing The Witcher 3. Even before this current batch of tests, the data seemed to indicate that The Witcher 3 sent separate output reports for rumble events and lightbar events. The DS4 feedback notification delegate in DS4Windows works on that assumption so it tends to work fine for The Witcher 3; it is likely still not accurate but good enough to not cause major problems. Current tests show that the initial hypothesis is true and The Witcher 3 will change the HID output report features byte (byte 0x01) depending on whether the data represents a rumble event (set to 0x01), a lightbar event (set to 0x02), or both (set to 0x03); a value of 0x03 seems to be used most often for resetting both the rumble motors and lightbar.
However, Streets of Rage 4 seems to include both rumble and lightbar data in the same report and uses a value of 0x07 for the features byte. Flag 0x04 is used to enable flash support for the lightbar although it looks like the game does not set any flash data in the output report buffer. The current DS4 feedback workaround does not really work at all for Streets of Rage 4 and can cause infinite rumble to occur at times.
Location of the DS4 feedback delegate in the current code.
Describe the solution you'd like
In order to be able to properly distinguish whether a feedback event should be considered a rumble event, lightbar event, or possibly both, the features byte from the main HID output report buffer (byte 0x01) needs to be provided by ViGEmBus through the ViGEmClient. As it is now, that byte is skipped by ViGEmBus and starts copying report data starting at byte 0x04 (Right Light rumble).
Describe alternatives you've considered
A workaround has been available in DS4Windows for a while. It only works relatively fine in The Witcher 3. The feedback processing workaround fails completely in Streets of Rage 4 when using its native DS4 controller support.
Additional context
I wanted to provide some test data I gathered from Trace events using TraceView Plus. Unfortunately, it looks like TraceView Plus cannot just output the filtered messages to an output file. It still includes all received messages from a session and the process of making the XML file takes several minutes and my current file is around 448 MB. Instead, I can only provide a small snippet of the last group of sample messages shown in a screenshot. The data was gathered while playing The Witcher 3 for a few minutes using its native DS4 controller support.
As you can see, the data differs depending on the flags set in the features byte.
Not sure if it will be relevant but here is the code snippet I inserted into ViGEmBus to log those messages. The code was added to the EmulationTargetDS4::UsbBulkOrInterruptTransfer method in the Ds4Pdo.cpp file.
PUCHAR rawOutputBuffer = static_cast<PUCHAR>(pTransfer->TransferBuffer);
TraceEvents(TRACE_LEVEL_INFORMATION,
TRACE_DS4,
"TestBytes: %02X,%02X,%02X,%02X,%02X,%02X,%02X,%02X\n",
rawOutputBuffer[1],
rawOutputBuffer[4],
rawOutputBuffer[5],
rawOutputBuffer[6],
rawOutputBuffer[7],
rawOutputBuffer[8],
rawOutputBuffer[9],
rawOutputBuffer[10]);

Activity
nefarius commentedon Feb 26, 2021
Sounds to me like it would be beneficial to simply returning the entire output report unmodified to the SDK and let the user of the API decode the bits relevant to them. Thanks for the explanation, I'll come up with an additional extended notification callback to support this case.
tamodolo commentedon Jul 30, 2021
Any update on this? This feature is highly desired.
nefarius commentedon Jul 31, 2021
No. New features for ViGEmBus are on hold until the opportunity opens up again that I find the resources to work on it.
nefarius commentedon Aug 6, 2022
Feature is in the works in this branch.
nefarius commentedon Aug 6, 2022
Implementation done, starting tests...
nefarius commentedon Aug 6, 2022
Familiar sightings 😎
nefarius commentedon Aug 7, 2022
.NET API done too.
Gianlucas94 commentedon Aug 7, 2022
I'm happy to see that you could implement that. Thanks
nefarius commentedon Aug 7, 2022
Latest driver beta is required for this to work. C and dotnet SDK updates have been pushed. Backwards compatible is preserved.
nefarius commentedon Aug 8, 2022
It's encouraged to use the new function instead of the DS4 notification callback. Both can exist in parallel though, no data is lost if you use both or either of them but the obvious advantage of the new function is that you get the unmodified raw data buffer and can decide to do whatever you need with it.
nefarius commentedon Aug 12, 2022
Added
vigem_target_ds4_await_output_report_timeoutto C/C++ SDK:nefarius commentedon Aug 12, 2022
Added
IEnumerable<byte> AwaitRawOutputReport(int timeout, out bool timedOut)toIDualShock4Controllerin .NET SDK.