Можно попробовать
fakemote, если добавить свой VIP&PID и скомпилировать. Заменить:
static const struct device_id_t compatible[] = {
{SONY_VID, 0x05c4},
{SONY_VID, 0x09cc},
на (в данном случае):
static const struct device_id_t compatible[] = {
{SONY_VID, 0x05c4},
{SONY_VID, 0x09cc},
{0x0C12, 0x0E17},
Если изменять код эмулятора, то, как я понял, для базовой поддержки кнопок (без стиков, вибрации, LED и т. п.) достаточно по аналогии с
https://github.com/niuus/Snes9xRX/blob/1c70e2486af14990fe61ae3b4c9a2c540a75ee83/source/utils/hornet.c немного изменить код, можно даже сам hornet.c изменить. В RetroArch и другом софте есть конфиги для устройств, значит в hornet.c нужно изменить VID&PID и какие байты отвечают за кнопки. В этом же эмуляторе retrode.c почти как hornet.c, вместо реализации конфигов. Конкретно заменить:
#define HORNET_VID 0x054C
#define HORNET_PID 0x05C4
jp = 0;
jp |= (buf[4] == 0x00) ? PAD_BUTTON_UP : 0;
jp |= (buf[4] == 0xFF) ? PAD_BUTTON_DOWN : 0;
jp |= (buf[3] == 0x00) ? PAD_BUTTON_LEFT : 0;
jp |= (buf[3] == 0xFF) ? PAD_BUTTON_RIGHT : 0;
jp |= ((buf[5] & 0x2F) == 0x2F) ? PAD_BUTTON_A : 0;
jp |= ((buf[5] & 0x1F) == 0x1F) ? PAD_BUTTON_B : 0;
jp |= ((buf[6] & 0x01) == 0x01) ? PAD_BUTTON_X : 0;
jp |= ((buf[5] & 0x8F) == 0x8F) ? PAD_BUTTON_Y : 0;
jp |= ((buf[6] & 0x04) == 0x04) ? PAD_TRIGGER_L : 0;
jp |= ((buf[6] & 0x08) == 0x08) ? PAD_TRIGGER_R : 0;
jp |= ((buf[6] & 0x20) == 0x20) ? PAD_BUTTON_START : 0;
jp |= ((buf[6] & 0x10) == 0x10) ? PAD_TRIGGER_Z : 0; // Hornet select button maps to Z
jp |= ((buf[6] & 0x02) == 0x02) ? PAD_BUTTON_Y : 0; // Hornet button 6 maps to Y
jp |= ((buf[5] & 0x4F) == 0x4F) ? PAD_BUTTON_B : 0; // Hornet button 3 maps to B
Какие кнопки отвечают за что есть, например в
fakemote/blob/main/source/usb_driver_ds4.c или
https://www.psdevwiki.com/ps4/DS4-USB#Data_Format. Должно получиться как-то так:
jp = 0;
jp |= ((buf[5] & 0x0F) == 0x00) ? PAD_BUTTON_UP : 0;
jp |= ((buf[5] & 0x0F) == 0x01) ? PAD_BUTTON_UP | PAD_BUTTON_RIGHT : 0;
jp |= ((buf[5] & 0x0F) == 0x02) ? PAD_BUTTON_RIGHT : 0;
jp |= ((buf[5] & 0x0F) == 0x03) ? PAD_BUTTON_DOWN | PAD_BUTTON_RIGHT : 0;
jp |= ((buf[5] & 0x0F) == 0x04) ? PAD_BUTTON_DOWN : 0;
jp |= ((buf[5] & 0x0F) == 0x05) ? PAD_BUTTON_DOWN | PAD_BUTTON_LEFT : 0;
jp |= ((buf[5] & 0x0F) == 0x06) ? PAD_BUTTON_LEFT : 0;
jp |= ((buf[5] & 0x0F) == 0x07) ? PAD_BUTTON_UP | PAD_BUTTON_LEFT : 0;
jp |= ((buf[5] & 0x10) == 0x10) ? PAD_BUTTON_Y : 0; // Square
jp |= ((buf[5] & 0x20) == 0x20) ? PAD_BUTTON_B : 0; // Cross
jp |= ((buf[5] & 0x40) == 0x40) ? PAD_BUTTON_A : 0; // Circle
jp |= ((buf[5] & 0x80) == 0x80) ? PAD_BUTTON_X : 0; // Triangle
jp |= ((buf[6] & 0x01) == 0x01) ? PAD_TRIGGER_L : 0; // L1
jp |= ((buf[6] & 0x02) == 0x02) ? PAD_TRIGGER_R : 0; // R1
jp |= ((buf[6] & 0x20) == 0x20) ? PAD_BUTTON_START : 0; // Options
jp |= ((buf[6] & 0x10) == 0x10) ? PAD_TRIGGER_Z : 0; // Share
В buf наверно индекс на 1 меньше, если Report ID нет, тогда buf[5] заменить на buf[4], а buf[6] на buf[5].