Proton
Proton copied to clipboard
DualSense advanced features compatibility
DualSense feature compatibility
EDIT: the patches at discussed in this thread have now been merged in Proton Experimental; they allow using DualSense-specific features (Adaptive triggers, speaker, VCM-based haptics) in at least:
- Final Fantasy XIV Online
- Final Fantasy 7 Remake Intergrade (the game does not make use of the speaker, and only makes light use of the other features)
- Ghostwire: Tokyo (note that the game does not appear to use the speaker, unlike the PS5 version)
- Deathloop (for the speaker to be used, XAudio2 needs to be disabled, see https://github.com/ValveSoftware/Proton/issues/5900#issuecomment-1180859190)
- Returnal™
- Season: A Letter to the Future
- Horizon: Forbidden West
- The Last of Us™ Part 1
All features require the DualSense to be plugged through USB before starting the game and Steam Input to be disabled for Playstation controllers (or simply Steam Input being disabled for the specific game). I have not found hid-playstation to cause any issue (apart from registering additional events on the touchpad which could interfere in some games).
Technical details
All DualSense features are implemented directly in the game application, with no additional driver. However, the games' implementation rely on low-level APIs that may not be implemented in Wine or details that may be different on a typical Linux environment.
Adaptive triggers work through custom HID reports, so this will work out of the box as long as Steam Input is disabled.
Speaker and advanced haptics rely on a 4-channel audio device, and the difficulties lie in games finding and selecting that audio output. Various games use various means to do it, but from what I have seen, it mainly boils down to one or more of these:
- have the audio device name contain “Wireless Controller” (FF14 and FF7R do that)
- get the BaseContainerID from the HID device and select the first MMDevice with the same ContainerID (Ghostwire: Tokyo, Deathloop)
- get the BaseContainerID from the HID device and use SetupDi to find an audio device with the same BaseContainerID (Deathloop does that for the speaker if XAudio2 is available)
I have written a sample test application to sum up these findings and test Wine/Proton against those behaviors without requiring the games: https://github.com/ClearlyClaire/dualsense-games-compat-check
EDIT: this post is only of historical interest, recent versions of Wine and Proton name the audio device appropriately, and no renaming is needed on the system side
I made some progress with it, it seems like it's mainly a naming issue indeed. Renaming the device from the default “DualSense wireless controller (PS5)” to “Wireless Controller” lets Final Fantasy XIV Online enable the speakers and output interface sounds through them. Haptics feedback does not seem to work, though, but I'm not sure why.
For the record, I changed the device name through the following command:
pacmd 'update-sink-proplist alsa_output.usb-Sony_Interactive_Entertainment_Wireless_Controller-00.analog-surround-40 device.description="Wireless Controller" device.product.name="Wireless Controller"'
EDIT: alternatively, using ALSA for audio in FF XIV's prefix also lets it use the speakers (protontricks 312060 sound=alsa)
EDIT2: it seems that at least when using pulseaudio, FFXIV outputs the interface sounds and only the interface sounds on all 4 channels. This also occurs with a module-null-sink with device.description="Wireless Controller" device.product.name="Wireless Controller"
Triggers only work through USB on Windows, your controller is wired right? I'm very interested to know if Proton can pass the triggers over.
Yes, I'm trying all of these features wired, and I'm not aware of any game providing support for any of these features over bluetooth. As said earlier, the only game I have been able to try so far is FF XIV Online, and as far as I understand, the Triggers are only used for a handful quests late in the game and I'm not anywhere close to that, so I have not been able to test that. But considering the game consistently resets the Adaptive Triggers settings, I think this would work fine.
Triggers only work through USB on Windows, your controller is wired right? I'm very interested to know if Proton can pass the triggers over.
Wrong. Try this and see for yourself: triggers can be configured even via bluetooth
Triggers only work through USB on Windows, your controller is wired right? I'm very interested to know if Proton can pass the triggers over.
Wrong. Try this and see for yourself: triggers can be configured even via bluetooth
I should say that zero games currently pass them over bluetooth, every single one demands usb atm.
Triggers only work through USB on Windows, your controller is wired right? I'm very interested to know if Proton can pass the triggers over.
Wrong. Try this and see for yourself: triggers can be configured even via bluetooth
I should say that zero games currently pass them over bluetooth, every single one demands usb atm.
Faking USB connection even in bluetooth mode?
Faking USB connection even in bluetooth mode?
I am not sure how feasible that is (though doing that only for the main HID device should be doable), but my understanding is that current userland drivers shipped in games use an audio device (as exposed by the system) for VCM-based haptics, microphone and speakers. Over USB, the audio uses a standard protocol and will be recognized out of the box, but over bluetooth, this uses a completely different custom protocol that needs to be implemented.
Either way, I initially created this topic to understand and track support in games that offer official compatibility, not to discuss ways to extend that compatibility to connection methods not natively supported by those games.
Faking USB connection even in bluetooth mode?
I am not sure how feasible that is (though doing that only for the main HID device should be doable), but my understanding is that current userland drivers shipped in games use an audio device (as exposed by the system) for VCM-based haptics, microphone and speakers. Over USB, the audio uses a standard protocol and will be recognized out of the box, but over bluetooth, this uses a completely different custom protocol that needs to be implemented.
Either way, I initially created this topic to understand and track support in games that offer official compatibility, not to discuss ways to extend that compatibility to connection methods not natively supported by those games.
Roger that. That being said: sony should update its HID-Playstation driver to include VCM-based haptics support + microphone over bluetooth, since that's the only limit (as far as I know).
Although that is off-topic, I have started exploring the possibility of exposing a bluetooth-connected DualSense to Windows games as if it were connected through USB. This seems possible, but involves translating reports between USB and Bluetooth as they are slightly different.
I wrote this sample program, it's very rough and incomplete ~~and actually doesn't get you any of the advanced DualSense feature because it does not forward/translate feature requests from the host to the controller (the feature request I'm seeing FFXIV use over USB is different from those used by trigger-control and hid-playstation, so I'm unsure how to translate it)~~, but demonstrates that at least Final Fantasy XIV is happy to connect to a “fake” HID device. It is also happy to output UI sounds to a dummy “Wireless Controller” sound device when using the “fake” HID device.
EDIT: updated to translate 0x2 USB output reports to 0x31 Bluetooth reports, which does let FFXIV reset the Adaptive Trigger settings
I finally managed to get haptic feedback working! For some reason, winepulse.drv will use the capabilities of the default audio device for reporting the internal supported capabilities for any subsequent stream. This means to get haptic feedback, you need to set the Wireless Controller to be your default output device when starting the game, and you can then switch the device to something else.
EDIT: more precisely, if the default output only supports stereo, all AudioClient_GetMixFormat calls made by the game will return formats with nChannels: 2; dwChannelMask: 00000003. I am not sure where exactly the fault lies though.
Hope Valve can look into this and streamline it all.
Edited the first post with the list of quirks I ran into and the workarounds I have found, including an udev rule to make sure the audio device automatically gets the proper name when the DualSense is plugged. I think the AudioClient_GetMixFormat is a Proton/wine bug but I'm not familiar enough with the code to get much further.
Edited the first post with the list of quirks I ran into and the workarounds I have found, including an
udevrule to make sure the audio device automatically gets the proper name when the DualSense is plugged. I think theAudioClient_GetMixFormatis a Proton/wine bug but I'm not familiar enough with the code to get much further.
Death Stranding is also a game where adaptive triggers work by default but no haptic feedback. renaming and setting it as default device also does not work :/
- Wireless Controller
This may be something patchable in wine:
/dlls/hidclass.sys/device.c
/* Sony controllers */
{ .id = L"VID_054C&PID_05C4", .product = L"Wireless Controller" },
{ .id = L"VID_054C&PID_09CC", .product = L"Wireless Controller" },
{ .id = L"VID_054C&PID_0BA0", .product = L"Wireless Controller" },
{ .id = L"VID_054C&PID_0CE6", .product = L"Wireless Controller" },
I guess we need to know what these controllers actually show up named as. We know the PS5 controller (054c, 0ce6) comes up as "DualSense wireless controller (PS5)" -- maybe a quick check into the kernel code will tell us what the others register as.
-edit-
When the controller is plugged in it comes up as DualSense wireless controller (PS5)" but when it connects via bluetooth it comes up as "Wireless Controller"
Running into the an issue with FF7 on Linux, because it shows up as "Wireless controller" and not Dualsense, rumble fails to function, its very, very annoying. I guess it needs to be named the exact same as it is on Windows in kernel for it to function, is that what you're getting at @GloriousEggroll?
- Wireless Controller
This may be something patchable in wine:
/dlls/hidclass.sys/device.c
/* Sony controllers */ { .id = L"VID_054C&PID_05C4", .product = L"Wireless Controller" }, { .id = L"VID_054C&PID_09CC", .product = L"Wireless Controller" }, { .id = L"VID_054C&PID_0BA0", .product = L"Wireless Controller" }, { .id = L"VID_054C&PID_0CE6", .product = L"Wireless Controller" },I guess we need to know what these controllers actually show up named as. We know the PS5 controller (054c, 0ce6) comes up as "DualSense wireless controller (PS5)" -- maybe a quick check into the kernel code will tell us what the others register as.
I'm not sure what you mean. Do you suggest changing how it is exposed within wine from “Wireless Controller” to something else? The games expect “Wireless Controller” for both the HID device and the audio device. The issue here is the audio device in wine not being called that.
Death Stranding is also a game where adaptive triggers work by default but no haptic feedback. renaming and setting it as default device also does not work :/
Same issue :/ The game does open the audio device, though, but does not seem to output anything to it. I will investigate. EDIT: no idea why the game doesn't output anything to the “Wireless Controller” audio device after opening it.
Rumble in FF7 remake works just fine with my DS4, even uses the proper icons compared to the DS5, yet both report to the game as "wireless controller". I guess whatever is preventing haptics on linux is still at play, maybe it isnt the name thing?
Yeah, I can confirm that all the observations I made until now hold true for FF7R: in order to open the audio device properly, it needs it to be called “Wireless Controller” and it needs to be started with a 4-channel default audio device… but unlike with FFXIV this isn't enough to have any kind of rumble.
Likely unrelated, but note that Steam has just been updated with:
- Show firmware update dialog for DualSense(tm) Wireless Controllers on Windows
- Enable improved rumble emulation on DualSense(tm) Wireless Controllers with updated firmware
Replying to https://github.com/ValveSoftware/Proton/issues/5900#issuecomment-1159357657
Really funny timing but this just seems to be them intergrating Sonys firmware update program into steam, which is super neat albeit windows only (Despite adding settings to the linux client)
With spiderman coming out I assume sony is gonna take a second look at their pc drivers, maybe make this stuff work wirelessly out of the box.
I find it very odd that adaptive triggers work ootb on Linux through proton (At least thats what was said here, cant confirm myself) along with the speaker sync rumble, but any game that attempts to use the native DS5 rumble api just, doesn't.
I find it very odd that adaptive triggers work ootb on Linux through proton (At least thats what was said here, cant confirm myself) along with the speaker sync rumble, but any game that attempts to use the native DS5 rumble api just, doesn't.
Adaptive triggers is relatively simple, it's just output reports on an HID device which is properly exposed. VCM-based haptic feedback also requires access to the audio device. It works on FFXIV once you've dealt with the quirks I have listed. Not sure why that isn't enough for FF7R or Death Stranding though. What do you call “speaker sync rumble”?
I find it very odd that adaptive triggers work ootb on Linux through proton (At least thats what was said here, cant confirm myself) along with the speaker sync rumble, but any game that attempts to use the native DS5 rumble api just, doesn't.
Adaptive triggers is relatively simple, it's just output reports on an HID device which is properly exposed. VCM-based haptic feedback also requires access to the audio device. It works on FFXIV once you've dealt with the quirks I have listed. Not sure why that isn't enough for FF7R or Death Stranding though. What do you call “speaker sync rumble”?
Your DS5 should appear in your speaker list, along with its mic, its primary purpose is to have audio go to the controller and your normal listening device to vibrate in sync with the sounds.
Your DS5 should appear in your speaker list, along with its mic, its primary purpose is to have audio go to the controller and your normal listening device to vibrate in sync with the sounds.
Ah, going through that audio device is precisely how the “native DS5 rumble api” works over USB. First two channels are for jack/speaker and the last two for rumble. Games such as FFXIV and FF7R open that device and FFXIV outputs interface sounds (if enabled) and rumble (for steps, mount effects etc.) through it. The trick is that Windows games with DualSense support find this device based on its name, which is not the expected one by default on linux.
@GloriousEggroll my understanding is that to address that in Wine itself, the device name should be overridden in https://github.com/ValveSoftware/wine/blob/a7618abea5ffeb3bfb1e69c0dbcdc1008bd88163/dlls/winepulse.drv/pulse.c#L550 or similar.
Though as stated earlier, this does not appear to be enough to get haptic feedback working in all games.
EDIT: I have identified a difference between FFXIV and FF7R, in that unlike FFXIV which uses 4-channel output, FF7R may attempt to output rumble data as single-channel audio, though I am still not sure why nothing seems to be actually sent to the device:
6114.311:0144:trace:pulse:AudioClient_IsFormatSupported (0000000000704250)->(0, 0000000000809F6C, 00000000004E6E28) 6114.311:0144:trace:pulse:dump_fmt wFormatTag: 0x3 (WAVE_FORMAT_IEEE_FLOAT) 6114.311:0144:trace:pulse:dump_fmt nChannels: 1 6114.311:0144:trace:pulse:dump_fmt nSamplesPerSec: 48000 6114.311:0144:trace:pulse:dump_fmt nAvgBytesPerSec: 192000 6114.311:0144:trace:pulse:dump_fmt nBlockAlign: 4 6114.311:0144:trace:pulse:dump_fmt wBitsPerSample: 32 6114.311:0144:trace:pulse:dump_fmt cbSize: 0 6114.311:0144:trace:pulse:AudioClient_IsFormatSupported returning: 00000000 0000000000000000
EDIT: my mistake, haptic feedback not working on Ghostwire: Tokyo, even disabling pulseaudio still produces the same effect, still interesting in comparison to other games like Death Stranding where it doesn't vibrate at all.
original comment: ~~Interesting find i just had with Ghostwire: Tokyo, with no steam input, when pressing R2 to charge an attack or L2 to grab a core you get both adaptive triggers and haptic feedback, feels awesome, and a very subtle feedback when you collect ether.~~
Apart from that the controller is dead... vibration works when using steam input, just as a xbox controller would vibrate... edit: and a broken adaptive trigger "breaking eggshell" effect with no haptic feedback.
Interesting find i just had with Ghostwire: Tokyo, with no steam input, when pressing R2 to charge an attack or L2 to grab a core you get both adaptive triggers and haptic feedback, feels awesome, and a very subtle feedback when you collect ether.
Apart from that the controller is dead... vibration works when using steam input, just as a xbox controller would vibrate...
Can you open pavumeter on your DualSense audio output and see what it shows when performing those actions? Does it show anything at all? If so, are the 4 channels used the same way? It's a pretty wild guess, but I wonder if this could be a mixing issue, e.g. the game using a 1-channel audio stream that doesn't get properly mixed for “basic” vibrations, and more deliberately using the 4 channels to better effect (e.g. FFXIV outputs to all channels presumably because it also uses the speaker).
EDIT: see my last comment above
Replying to https://github.com/ValveSoftware/Proton/issues/5900#issuecomment-1159370452
~~can't get it to work, damn. if it just run pacmd list-sinks it shows RUNNING status when passing audio to the dualsense, no surprises there, it shows idle if not doing anything, ok... but it shows SUSPENDED when running the game, it doesnt report anything... i could be wrong and perhaps its just vibration, but it doesn't feel like traditional vibration at all. going to try again tomorrow, perhaps its a pulseaudio bug.~~
Double-check that device.description = "Wireless Controller" otherwise the game won't pick it up! Otherwise I don't know.
I'm digging into winepulse.drv to see if I can make sense of it. So far I understand the 4-channel VS 2-channel issue as winepulse.drv not reporting different formats for each sink/input, but just for the default sink/input. It simply doesn't detect or store the rest. For the issue of nothing being played despite the audio device being open, I have no clue so far.
@GloriousEggroll I'm not sure this is the best place to do that, but the audio naming stuff in Wine itself could be done this way for the PulseAudio backend:
diff --git a/dlls/winepulse.drv/pulse.c b/dlls/winepulse.drv/pulse.c
index 60b1c7126dc..ec9a81ab148 100644
--- a/dlls/winepulse.drv/pulse.c
+++ b/dlls/winepulse.drv/pulse.c
@@ -521,6 +521,15 @@ static void fill_device_info(PhysDevice *dev, pa_proplist *p)
if ((buffer = pa_proplist_gets(p, PA_PROP_DEVICE_PRODUCT_ID)))
dev->product_id = strtol(buffer, NULL, 16);
+
+ // Games with DualSense support need the audio device to be called "Wireless Controller"
+ if (dev->vendor_id == 0x054c && dev->product_id == 0x0ce6) {
+ WCHAR *new_name = get_device_name("Wireless Controller", NULL);
+ if (new_name) {
+ free(dev->name);
+ dev->name = new_name;
+ }
+ }
}
static void pulse_add_device(struct list *list, pa_proplist *proplist, int index, EndpointFormFactor form,
The GetMixFormat thing is significantly more involved as we have to pass the values from pulse.c to mmdevdrv.c somehow, and there seem to be no readily-available interface to do that. Or I guess we could do something similar to pulse_probe_settings
The FF7R issue seem to be related to GetMixFormat as well, as after a few calls this returns nChannels: 2 for the Wireless Controller as well. I'm going to work on that next.
EDIT: an alternative, slightly more generic way (as in, it would work with other audio backends) to do the same (enforce the “Wireless Controller” name) could be done in MMDevice_Create to overwrite the DEVPKEY_Device_FriendlyName key
The FF7R issue seem to be related to
GetMixFormatas well, as after a few calls this returnsnChannels: 2for the Wireless Controller as well. I'm going to work on that next.
I have implemented per-device GetMixFormat (in an extremely rough way, lacking many sanity checks), and it works! Beware that not everything has rumble in FF7R, e.g. hitting enemies has rumble, but not hitting crates.
AudioClient_GetMixFormat proof of concept patch
diff --git a/dlls/winepulse.drv/mmdevdrv.c b/dlls/winepulse.drv/mmdevdrv.c
index 66e83b5c475..49178aece77 100644
--- a/dlls/winepulse.drv/mmdevdrv.c
+++ b/dlls/winepulse.drv/mmdevdrv.c
@@ -1149,7 +1149,16 @@ static HRESULT WINAPI AudioClient_GetMixFormat(IAudioClient3 *iface,
if (!pwfx)
return E_POINTER;
- *pwfx = clone_format(&pulse_config.modes[This->dataflow == eCapture].format.Format);
+ if (This->pulse_name[0]) {
+ struct get_device_mix_format_params params;
+ params.render = This->dataflow == eRender;
+ params.pulse_name = This->pulse_name;
+ pulse_call(get_device_mix_format, ¶ms);
+ *pwfx = clone_format(¶ms.fmt.Format);
+ } else {
+ *pwfx = clone_format(&pulse_config.modes[This->dataflow == eCapture].format.Format);
+ }
+
if (!*pwfx)
return E_OUTOFMEMORY;
dump_fmt(*pwfx);
diff --git a/dlls/winepulse.drv/pulse.c b/dlls/winepulse.drv/pulse.c
index 6418179fb03..d0666542988 100644
--- a/dlls/winepulse.drv/pulse.c
+++ b/dlls/winepulse.drv/pulse.c
@@ -89,6 +89,8 @@ typedef struct _PhysDevice {
EndpointFormFactor form;
DWORD channel_mask;
UINT index;
+ pa_sample_spec ss;
+ pa_channel_map map;
char pulse_name[0];
} PhysDevice;
@@ -532,7 +534,7 @@ static void fill_device_info(PhysDevice *dev, pa_proplist *p)
}
}
-static void pulse_add_device(struct list *list, pa_proplist *proplist, int index, EndpointFormFactor form,
+static void pulse_add_device(struct list *list, pa_sample_spec *ss, pa_channel_map *map, pa_proplist *proplist, int index, EndpointFormFactor form,
DWORD channel_mask, const char *pulse_name, const char *desc)
{
DWORD len = strlen(pulse_name);
@@ -545,6 +547,13 @@ static void pulse_add_device(struct list *list, pa_proplist *proplist, int index
free(dev);
return;
}
+
+ if (map)
+ memcpy(&dev->map, map, sizeof(pa_channel_map));
+
+ if (ss)
+ memcpy(&dev->ss, ss, sizeof(pa_sample_spec));
+
dev->form = form;
dev->index = index;
dev->channel_mask = channel_mask;
@@ -571,14 +580,14 @@ static void pulse_phys_speakers_cb(pa_context *c, const pa_sink_info *i, int eol
if (speaker)
LIST_ENTRY(speaker, PhysDevice, entry)->channel_mask |= channel_mask;
- pulse_add_device(&g_phys_speakers, i->proplist, i->index, Speakers, channel_mask, i->name, i->description);
+ pulse_add_device(&g_phys_speakers, &i->sample_spec, &i->channel_map, i->proplist, i->index, Speakers, channel_mask, i->name, i->description);
}
static void pulse_phys_sources_cb(pa_context *c, const pa_source_info *i, int eol, void *userdata)
{
if (!i || !i->name || !i->name[0])
return;
- pulse_add_device(&g_phys_sources, i->proplist, i->index,
+ pulse_add_device(&g_phys_sources, &i->sample_spec, &i->channel_map, i->proplist, i->index,
(i->monitor_of_sink == PA_INVALID_INDEX) ? Microphone : LineLevel, 0, i->name, i->description);
}
@@ -694,6 +703,7 @@ static void pulse_probe_settings(int render, WAVEFORMATEXTENSIBLE *fmt) {
PA_STREAM_START_CORKED|PA_STREAM_FIX_RATE|PA_STREAM_FIX_CHANNELS|PA_STREAM_EARLY_REQUESTS|PA_STREAM_VARIABLE_RATE, NULL, NULL);
else
ret = pa_stream_connect_record(stream, NULL, &attr, PA_STREAM_START_CORKED|PA_STREAM_FIX_RATE|PA_STREAM_FIX_CHANNELS|PA_STREAM_EARLY_REQUESTS);
+
if (ret >= 0) {
while (pa_mainloop_iterate(pulse_ml, 1, &ret) >= 0 &&
pa_stream_get_state(stream) == PA_STREAM_CREATING)
@@ -737,12 +747,48 @@ static void pulse_probe_settings(int render, WAVEFORMATEXTENSIBLE *fmt) {
fmt->Samples.wValidBitsPerSample = wfx->wBitsPerSample;
else
fmt->Samples.wValidBitsPerSample = 24;
+
if (ss.format == PA_SAMPLE_FLOAT32LE)
fmt->SubFormat = KSDATAFORMAT_SUBTYPE_IEEE_FLOAT;
else
fmt->SubFormat = KSDATAFORMAT_SUBTYPE_PCM;
}
+static NTSTATUS pulse_get_device_mix_format(void *args)
+{
+ struct get_device_mix_format_params *params = args;
+ WAVEFORMATEXTENSIBLE *fmt = ¶ms->fmt;
+ WAVEFORMATEX *wfx = &fmt->Format;
+ int ret;
+
+ struct list *list = params->render ? &g_phys_speakers : &g_phys_sources;
+ PhysDevice *dev;
+
+ LIST_FOR_EACH_ENTRY(dev, list, PhysDevice, entry) {
+ if (strcmp(params->pulse_name, dev->pulse_name))
+ continue;
+
+ wfx->wFormatTag = WAVE_FORMAT_EXTENSIBLE;
+ wfx->cbSize = sizeof(WAVEFORMATEXTENSIBLE) - sizeof(WAVEFORMATEX);
+
+ convert_channel_map(&dev->map, fmt);
+
+ wfx->wBitsPerSample = 8 * pa_sample_size_of_format(dev->ss.format);
+ wfx->nSamplesPerSec = dev->ss.rate;
+ wfx->nBlockAlign = wfx->nChannels * wfx->wBitsPerSample / 8;
+ wfx->nAvgBytesPerSec = wfx->nSamplesPerSec * wfx->nBlockAlign;
+
+ if (dev->ss.format != PA_SAMPLE_S24_32LE)
+ fmt->Samples.wValidBitsPerSample = wfx->wBitsPerSample;
+ else
+ fmt->Samples.wValidBitsPerSample = 24;
+
+ return STATUS_SUCCESS;
+ }
+
+ return STATUS_SUCCESS;
+}
+
/* some poorly-behaved applications call audio functions during DllMain, so we
* have to do as much as possible without creating a new thread. this function
* sets up a synchronous connection to verify the server is running and query
@@ -800,8 +846,8 @@ static NTSTATUS pulse_test_connect(void *args)
list_init(&g_phys_speakers);
list_init(&g_phys_sources);
- pulse_add_device(&g_phys_speakers, NULL, 0, Speakers, 0, "", "PulseAudio");
- pulse_add_device(&g_phys_sources, NULL, 0, Microphone, 0, "", "PulseAudio");
+ pulse_add_device(&g_phys_speakers, NULL, NULL, NULL, 0, Speakers, 0, "", "PulseAudio");
+ pulse_add_device(&g_phys_sources, NULL, NULL, NULL, 0, Microphone, 0, "", "PulseAudio");
o = pa_context_get_sink_info_list(pulse_ctx, &pulse_phys_speakers_cb, NULL);
if (o) {
@@ -2342,4 +2388,5 @@ const unixlib_entry_t __wine_unix_call_funcs[] =
pulse_test_connect,
pulse_is_started,
pulse_get_prop_value,
+ pulse_get_device_mix_format,
};
diff --git a/dlls/winepulse.drv/unixlib.h b/dlls/winepulse.drv/unixlib.h
index 4f6d856ac79..1f396da381a 100644
--- a/dlls/winepulse.drv/unixlib.h
+++ b/dlls/winepulse.drv/unixlib.h
@@ -159,6 +159,13 @@ struct get_current_padding_params
UINT32 *padding;
};
+struct get_device_mix_format_params
+{
+ const char *pulse_name;
+ BOOL render;
+ WAVEFORMATEXTENSIBLE fmt;
+};
+
struct get_next_packet_size_params
{
struct pulse_stream *stream;
@@ -260,4 +267,5 @@ enum unix_funcs
test_connect,
is_started,
get_prop_value,
+ get_device_mix_format,
};
EDIT: my mistake, haptic feedback not working on Ghostwire: Tokyo, even disabling pulseaudio still produces the same effect, still interesting in comparison to other games like Death Stranding where it doesn't vibrate at all.
I guess the motors in the triggers can do a vibration effect themselves. I've got VCM-based haptic feedback to work in both FF7R and FFXIV, so I think this would work with Death Stranding and Ghostwire: Tokyo too. If you can, try rebuilding Proton with the two patches to wine I provided above (one to name the controller audio device “Wireless Controller” inside of wine, and the other to expose device-specific format so that the game picks up 4-channel audio).