Геймпадная сила обратной связи (вибрация) на окнах с использованием исходного ввода

В настоящее время я пишу кросс-платформенную библиотеку на C, которая включает поддержку геймпада. Коммуникация геймпада в окнах обрабатывается как сырым входом, так и xinput, в зависимости от конкретного геймпада.

В то время как xinput упрощает обратную связь по силе обратной связи на контроллерах xbox360, я не нашел способа сделать это, используя исходный ввод. У меня есть некоторые геймпады, которые могут дать силовую обратную связь, но я не могу найти способ сделать это с помощью сырого ввода. Есть ли способ сделать это?

Я предпочитаю не использовать directinput api, поскольку он не рекомендуется и не рекомендуется Microsoft.

Edit:

Так как я реализовал геймпады для большей части, возможно, я могу немного сузить вопрос. Я подозреваю, что количество громовых двигателей в геймпаде можно найти, читая NumberOutputValueCaps структуры HIDP_CAPS. Это дает правильный результат для всех моих тестовых геймпадов.

Я использую funtcion HidP_GetUsageValue для чтения значений оси, что отлично работает. Теперь я подозреваю, что вызов HidP_SetUsageValue должен позволить мне изменить это выходное значение, включив двигатель грохота. Однако вызов этой функции завершается неудачно. Должна ли эта функция работать с моторами?

+3
источник поделиться
1 ответ

HidP_SetUsageValue() только модифицирует буфер отчетов - вам нужно сначала подготовить буфер соответствующего размера (это может быть причиной отказа функции, входные отчеты и выходные отчеты не обязательно будут одинакового размера), а затем отправить его к устройству, прежде чем он будет иметь какой-либо эффект. MSDN предлагает вам использовать HidD_SetOutputReport() для этой цели, но мне повезло с WriteFile(), следуя образцу кода: https://code.msdn.microsoft.com/windowshardware/HClient-HID-Sample-4ec99697/sourcecode?fileId=51262&pathId=340791466

Этот фрагмент (основанный на драйвере Linux) позволяет мне управлять моторами и светодиодами на DualShock 4:

const char *path = /* from GetRawInputDeviceInfo(RIDI_DEVICENAME) */;
HANDLE hid_device = CreateFile(path, GENERIC_READ | GENERIC_WRITE,
                               FILE_SHARE_READ | FILE_SHARE_WRITE, NULL,
                               OPEN_EXISTING, 0, NULL);
assert(hid_device != INVALID_HANDLE_VALUE);
uint8_t buf[32];
memset(buf, 0, sizeof(buf));
buf[0] = 0x05;
buf[1] = 0xFF;
buf[4] = right_motor_strength;  // 0-255
buf[5] = left_motor_strength;   // 0-255
buf[6] = led_red_level;         // 0-255
buf[7] = led_green_level;       // 0-255
buf[8] = led_blue_level;        // 0-255
DWORD bytes_written;
assert(WriteFile(hid_device, buf, sizeof(buf), &bytes_written, NULL));
assert(bytes_written == 32);

(EDIT: фиксированные смещения буфера)

+5
источник

Посмотрите другие вопросы по меткам или Задайте вопрос