Instead of having the waveforms combined. This better matches what
Windows.Gaming.Input and Windows.Devices.Haptics are exposing, with one
SimpleHapticsController for each motor.
This will also simplify the declaration of left/right trigger motors.
Signed-off-by: Rémi Bernon <rbernon(a)codeweavers.com>
---
dlls/winebus.sys/hid.c | 89 +++++++++++++++++++++++++++++++--
dlls/winebus.sys/unix_private.h | 12 +++++
2 files changed, 98 insertions(+), 3 deletions(-)
diff --git a/dlls/winebus.sys/hid.c b/dlls/winebus.sys/hid.c
index 3e83a05cdf6..46336716a70 100644
--- a/dlls/winebus.sys/hid.c
+++ b/dlls/winebus.sys/hid.c
@@ -337,6 +337,11 @@ struct hid_haptics_waveform
BYTE manual_trigger;
BYTE repeat_count;
};
+struct hid_haptics_intensity
+{
+ UINT16 rumble_intensity;
+ UINT16 buzz_intensity;
+};
#include "poppack.h"
BOOL hid_device_add_haptics(struct unix_device *iface)
@@ -344,7 +349,8 @@ BOOL hid_device_add_haptics(struct unix_device *iface)
struct hid_report_descriptor *desc = &iface->hid_report_descriptor;
const BYTE haptics_features_report = ++desc->next_report_id[HidP_Feature];
const BYTE haptics_waveform_report = ++desc->next_report_id[HidP_Output];
- const BYTE haptics_template[] =
+ const BYTE haptics_intensity_report = ++desc->next_report_id[HidP_Output];
+ const BYTE waveforms_template[] =
{
USAGE_PAGE(2, HID_USAGE_PAGE_HAPTICS),
USAGE(1, HID_USAGE_HAPTICS_SIMPLE_CONTROLLER),
@@ -404,16 +410,75 @@ BOOL hid_device_add_haptics(struct unix_device *iface)
OUTPUT(1, Data|Var|Abs),
END_COLLECTION,
};
+ const BYTE haptics_template[] =
+ {
+ USAGE_PAGE(2, HID_USAGE_PAGE_HAPTICS),
+ USAGE(1, HID_USAGE_HAPTICS_SIMPLE_CONTROLLER),
+ COLLECTION(1, Logical),
+ REPORT_ID(1, haptics_features_report),
+
+ USAGE(1, HID_USAGE_HAPTICS_WAVEFORM_LIST),
+ COLLECTION(1, NamedArray),
+ USAGE(4, (HID_USAGE_PAGE_ORDINAL<<16)|3),
+ REPORT_SIZE(1, 16),
+ REPORT_COUNT(1, 1),
+ FEATURE(1, Data|Var|Abs|Null),
+ END_COLLECTION,
+
+ USAGE(1, HID_USAGE_HAPTICS_DURATION_LIST),
+ COLLECTION(1, NamedArray),
+ USAGE(4, (HID_USAGE_PAGE_ORDINAL<<16)|3),
+ REPORT_SIZE(1, 16),
+ REPORT_COUNT(1, 1),
+ FEATURE(1, Data|Var|Abs|Null),
+ END_COLLECTION,
+
+ USAGE(1, HID_USAGE_HAPTICS_WAVEFORM_CUTOFF_TIME),
+ UNIT(2, 0x1001), /* seconds */
+ UNIT_EXPONENT(1, -3), /* 10^-3 */
+ LOGICAL_MINIMUM(4, 0x00000000),
+ LOGICAL_MAXIMUM(4, 0x7fffffff),
+ REPORT_SIZE(1, 32),
+ REPORT_COUNT(1, 1),
+ FEATURE(1, Data|Var|Abs),
+ /* reset global items */
+ UNIT(1, 0), /* None */
+ UNIT_EXPONENT(1, 0),
+
+ REPORT_ID(1, haptics_intensity_report),
+ USAGE(1, HID_USAGE_HAPTICS_INTENSITY),
+ LOGICAL_MINIMUM(4, 0x00000000),
+ LOGICAL_MAXIMUM(4, 0x0000ffff),
+ REPORT_SIZE(1, 16),
+ REPORT_COUNT(1, 1),
+ OUTPUT(1, Data|Var|Abs),
+ END_COLLECTION,
+ };
iface->hid_haptics.features_report = haptics_features_report;
iface->hid_haptics.waveform_report = haptics_waveform_report;
+ iface->hid_haptics.intensity_report = haptics_intensity_report;
iface->hid_haptics.features.waveform_list[0] = HID_USAGE_HAPTICS_WAVEFORM_RUMBLE;
iface->hid_haptics.features.waveform_list[1] = HID_USAGE_HAPTICS_WAVEFORM_BUZZ;
iface->hid_haptics.features.duration_list[0] = 0;
iface->hid_haptics.features.duration_list[1] = 0;
iface->hid_haptics.features.waveform_cutoff_time_ms = 1000;
+ iface->hid_haptics.features.rumble.waveform = HID_USAGE_HAPTICS_WAVEFORM_RUMBLE;
+ iface->hid_haptics.features.rumble.duration = 0;
+ iface->hid_haptics.features.rumble.cutoff_time_ms = 1000;
+ iface->hid_haptics.features.buzz.waveform = HID_USAGE_HAPTICS_WAVEFORM_BUZZ;
+ iface->hid_haptics.features.buzz.duration = 0;
+ iface->hid_haptics.features.buzz.cutoff_time_ms = 1000;
- return hid_report_descriptor_append(desc, haptics_template, sizeof(haptics_template));
+ if (!hid_report_descriptor_append(desc, waveforms_template, sizeof(waveforms_template)))
+ return FALSE;
+
+ if (!hid_report_descriptor_append(desc, haptics_template, sizeof(haptics_template)))
+ return FALSE;
+ if (!hid_report_descriptor_append(desc, haptics_template, sizeof(haptics_template)))
+ return FALSE;
+
+ return TRUE;
}
#include "pshpack1.h"
@@ -1072,7 +1137,23 @@ static void hid_device_set_output_report(struct unix_device *iface, HID_XFER_PAC
struct hid_physical *physical = &iface->hid_physical;
struct hid_haptics *haptics = &iface->hid_haptics;
- if (packet->reportId == haptics->waveform_report)
+ if (packet->reportId == haptics->intensity_report)
+ {
+ struct hid_haptics_intensity *report = (struct hid_haptics_intensity *)(packet->reportBuffer + 1);
+ ULONG duration_ms;
+
+ io->Information = sizeof(*report) + 1;
+ assert(packet->reportBufferLen == io->Information);
+
+ if (!report->rumble_intensity && !report->buzz_intensity)
+ io->Status = iface->hid_vtbl->haptics_stop(iface);
+ else
+ {
+ duration_ms = min(haptics->features.rumble.cutoff_time_ms, haptics->features.buzz.cutoff_time_ms);
+ io->Status = iface->hid_vtbl->haptics_start(iface, duration_ms, report->rumble_intensity, report->buzz_intensity);
+ }
+ }
+ else if (packet->reportId == haptics->waveform_report)
{
struct hid_haptics_waveform *report = (struct hid_haptics_waveform *)(packet->reportBuffer + 1);
UINT16 *rumble_intensity = haptics->waveform_intensity + HAPTICS_WAVEFORM_RUMBLE_ORDINAL;
@@ -1307,6 +1388,8 @@ static void hid_device_set_feature_report(struct unix_device *iface, HID_XFER_PA
assert(packet->reportBufferLen == io->Information);
haptics->features.waveform_cutoff_time_ms = features->waveform_cutoff_time_ms;
+ haptics->features.rumble.cutoff_time_ms = features->rumble.cutoff_time_ms;
+ haptics->features.buzz.cutoff_time_ms = features->buzz.cutoff_time_ms;
io->Status = STATUS_SUCCESS;
}
else
diff --git a/dlls/winebus.sys/unix_private.h b/dlls/winebus.sys/unix_private.h
index 553631e40fb..081e57dc53d 100644
--- a/dlls/winebus.sys/unix_private.h
+++ b/dlls/winebus.sys/unix_private.h
@@ -138,12 +138,23 @@ enum haptics_waveform_ordinal
HAPTICS_WAVEFORM_LAST_ORDINAL = HAPTICS_WAVEFORM_BUZZ_ORDINAL,
};
+#include "pshpack1.h"
+struct hid_haptics_feature
+{
+ WORD waveform;
+ WORD duration;
+ UINT cutoff_time_ms;
+};
+
struct hid_haptics_features
{
WORD waveform_list[HAPTICS_WAVEFORM_LAST_ORDINAL - HAPTICS_WAVEFORM_FIRST_ORDINAL + 1];
WORD duration_list[HAPTICS_WAVEFORM_LAST_ORDINAL - HAPTICS_WAVEFORM_FIRST_ORDINAL + 1];
UINT waveform_cutoff_time_ms;
+ struct hid_haptics_feature rumble;
+ struct hid_haptics_feature buzz;
};
+#include "poppack.h"
struct hid_haptics
{
@@ -151,6 +162,7 @@ struct hid_haptics
UINT16 waveform_intensity[HAPTICS_WAVEFORM_LAST_ORDINAL + 1];
BYTE features_report;
BYTE waveform_report;
+ BYTE intensity_report;
};
/* must match the order and number of usages in the
--
2.35.1