Update HID pad driver architecture

== DETAILS

The current HID implementation assumes a very low-level USB library
is being used. This causes a problem on Wii U, because the Cafe OS
only exposes a high-level interface.

To get these functions exposed to the HID pad drivers, I had to make
three changes:

1. I added the legacy "send_control" function to the HID driver
   interface
2. I modified the signature of pad_connection_pad_init() to send the
   driver pointer instead of the function pointer
3. I updated the HID pad drivers to keep the pointer to the driver
   instead of the function pointer, and updated the calls into the
   send_control function as appropriate
4. I updated the HID drivers to use the new pad init signature

== TESTING
Untested, in theory it should work without a hitch because at this
point all I've done is abstract things a little. I still need to
update the HID pad drivers to use the Wii U-specific calls as
appropriate.
This commit is contained in:
gblues 2017-12-12 22:55:10 -08:00 committed by twinaphex
parent d0adbd194e
commit 5b37ced196
19 changed files with 53 additions and 61 deletions

View File

@ -30,7 +30,7 @@ struct hidpad_nesusb_data
uint32_t buttons; uint32_t buttons;
}; };
static void* hidpad_nesusb_init(void *data, uint32_t slot, send_control_t ptr) static void* hidpad_nesusb_init(void *data, uint32_t slot, hid_driver_t *driver)
{ {
struct pad_connection* connection = (struct pad_connection*)data; struct pad_connection* connection = (struct pad_connection*)data;
struct hidpad_nesusb_data* device = (struct hidpad_nesusb_data*) struct hidpad_nesusb_data* device = (struct hidpad_nesusb_data*)

View File

@ -30,7 +30,7 @@ struct hidpad_ps2adapter_data
uint32_t buttons; uint32_t buttons;
}; };
static void* hidpad_ps2adapter_init(void *data, uint32_t slot, send_control_t ptr) static void* hidpad_ps2adapter_init(void *data, uint32_t slot, hid_driver_t *driver)
{ {
struct pad_connection* connection = (struct pad_connection*)data; struct pad_connection* connection = (struct pad_connection*)data;
struct hidpad_ps2adapter_data* device = (struct hidpad_ps2adapter_data*) struct hidpad_ps2adapter_data* device = (struct hidpad_ps2adapter_data*)

View File

@ -25,7 +25,7 @@
struct hidpad_ps3_data struct hidpad_ps3_data
{ {
struct pad_connection* connection; struct pad_connection* connection;
send_control_t send_control; hid_driver_t *driver;
uint8_t data[512]; uint8_t data[512];
uint32_t slot; uint32_t slot;
uint32_t buttons; uint32_t buttons;
@ -54,13 +54,13 @@ static void hidpad_ps3_send_control(struct hidpad_ps3_data* device)
report_buffer[6] = device->motors[0] >> 8; report_buffer[6] = device->motors[0] >> 8;
#ifdef HAVE_WIIUSB_HID #ifdef HAVE_WIIUSB_HID
report_buffer[1] = 0x03; /* send control message type */ report_buffer[1] = 0x03; /* send control message type */
device->send_control(device->connection, &report_buffer[1], sizeof(report_buffer)-1); device->driver->send_control(device->connection, &report_buffer[1], sizeof(report_buffer)-1);
#else #else
device->send_control(device->connection, report_buffer, sizeof(report_buffer)); device->driver->send_control(device->connection, report_buffer, sizeof(report_buffer));
#endif #endif
} }
static void* hidpad_ps3_init(void *data, uint32_t slot, send_control_t ptr) static void* hidpad_ps3_init(void *data, uint32_t slot, hid_driver_t *driver)
{ {
#ifdef HAVE_WIIUSB_HID #ifdef HAVE_WIIUSB_HID
/* Special command to enable Sixaxis, first byte defines the message type */ /* Special command to enable Sixaxis, first byte defines the message type */
@ -82,12 +82,12 @@ static void* hidpad_ps3_init(void *data, uint32_t slot, send_control_t ptr)
return NULL; return NULL;
} }
device->connection = connection; device->connection = connection;
device->slot = slot; device->slot = slot;
device->send_control = ptr; device->driver = driver;
#if defined(IOS) || defined(HAVE_WIIUSB_HID) #if defined(IOS) || defined(HAVE_WIIUSB_HID)
device->send_control(device->connection, magic_data, sizeof(magic_data)); device->driver->send_control(device->connection, magic_data, sizeof(magic_data));
#endif #endif
#ifndef HAVE_WIIUSB_HID #ifndef HAVE_WIIUSB_HID

View File

@ -98,7 +98,7 @@ struct ps4
struct hidpad_ps4_data struct hidpad_ps4_data
{ {
struct pad_connection* connection; struct pad_connection* connection;
send_control_t send_control; hid_driver_t *driver;
struct ps4 data; struct ps4 data;
uint32_t slot; uint32_t slot;
bool have_led; bool have_led;
@ -119,11 +119,11 @@ static void hidpad_ps4_send_control(struct hidpad_ps4_data* device)
report_buffer[11] = rgb[(device->slot % 4)][2]; report_buffer[11] = rgb[(device->slot % 4)][2];
#endif #endif
device->send_control(device->connection, device->driver->send_control(device->connection,
report_buffer, sizeof(report_buffer)); report_buffer, sizeof(report_buffer));
} }
static void* hidpad_ps4_init(void *data, uint32_t slot, send_control_t ptr) static void* hidpad_ps4_init(void *data, uint32_t slot, hid_driver_t *driver)
{ {
#if 0 #if 0
uint8_t magic_data[0x25]; uint8_t magic_data[0x25];
@ -138,14 +138,14 @@ static void* hidpad_ps4_init(void *data, uint32_t slot, send_control_t ptr)
if (!connection) if (!connection)
goto error; goto error;
device->connection = connection; device->connection = connection;
device->slot = slot; device->slot = slot;
device->send_control = ptr; device->driver = driver;
#if 0 #if 0
/* TODO - unsure of this */ /* TODO - unsure of this */
/* This is needed to get full input packet over bluetooth. */ /* This is needed to get full input packet over bluetooth. */
device->send_control(device->connection, magic_data, 0x2); device->driver->send_control(device->connection, magic_data, 0x2);
(void)magic_data; (void)magic_data;
#endif #endif

View File

@ -30,7 +30,7 @@ struct hidpad_psxadapter_data
uint32_t buttons; uint32_t buttons;
}; };
static void* hidpad_psxadapter_init(void *data, uint32_t slot, send_control_t ptr) static void* hidpad_psxadapter_init(void *data, uint32_t slot, hid_driver_t *driver)
{ {
struct pad_connection* connection = (struct pad_connection*)data; struct pad_connection* connection = (struct pad_connection*)data;
struct hidpad_psxadapter_data* device = (struct hidpad_psxadapter_data*) struct hidpad_psxadapter_data* device = (struct hidpad_psxadapter_data*)

View File

@ -31,7 +31,7 @@ struct hidpad_snesusb_data
uint32_t buttons; uint32_t buttons;
}; };
static void* hidpad_snesusb_init(void *data, uint32_t slot, send_control_t ptr) static void* hidpad_snesusb_init(void *data, uint32_t slot, hid_driver_t *driver)
{ {
struct pad_connection* connection = (struct pad_connection*)data; struct pad_connection* connection = (struct pad_connection*)data;
struct hidpad_snesusb_data* device = (struct hidpad_snesusb_data*) struct hidpad_snesusb_data* device = (struct hidpad_snesusb_data*)

View File

@ -145,7 +145,7 @@ typedef struct connect_wii_wiimote_t
int unid; int unid;
struct pad_connection* connection; struct pad_connection* connection;
send_control_t send_control; hid_driver_t *driver;
/* Various state flags. */ /* Various state flags. */
uint32_t state; uint32_t state;
@ -195,7 +195,7 @@ static int wiimote_send(struct connect_wii_wiimote_t* wm,
printf("\n"); printf("\n");
#endif #endif
wm->send_control(wm->connection, buf, len + 2); wm->driver->send_control(wm->connection, buf, len + 2);
return 1; return 1;
} }
@ -616,7 +616,7 @@ static void hidpad_wii_deinit(void *data)
} }
static void* hidpad_wii_init(void *data, uint32_t slot, static void* hidpad_wii_init(void *data, uint32_t slot,
send_control_t ptr) hid_driver_t *driver)
{ {
struct pad_connection *connection = (struct pad_connection*)data; struct pad_connection *connection = (struct pad_connection*)data;
struct connect_wii_wiimote_t *device = (struct connect_wii_wiimote_t*) struct connect_wii_wiimote_t *device = (struct connect_wii_wiimote_t*)
@ -628,11 +628,11 @@ static void* hidpad_wii_init(void *data, uint32_t slot,
if (!connection) if (!connection)
goto error; goto error;
device->connection = connection; device->connection = connection;
device->unid = slot; device->unid = slot;
device->state = WIIMOTE_STATE_CONNECTED; device->state = WIIMOTE_STATE_CONNECTED;
device->exp.type = EXP_NONE; device->exp.type = EXP_NONE;
device->send_control = ptr; device->driver = driver;
wiimote_handshake(device, -1, NULL, -1); wiimote_handshake(device, -1, NULL, -1);

View File

@ -25,13 +25,13 @@
struct hidpad_wiiugca_data struct hidpad_wiiugca_data
{ {
struct pad_connection* connection; struct pad_connection* connection;
send_control_t send_control; hid_driver_t *driver;
uint8_t data[64]; uint8_t data[64];
uint32_t slot; uint32_t slot;
uint32_t buttons; uint32_t buttons;
}; };
static void* hidpad_wiiugca_init(void *data, uint32_t slot, send_control_t ptr) static void* hidpad_wiiugca_init(void *data, uint32_t slot, hid_driver_t *driver)
{ {
static uint8_t magic_data[] = {0x01, 0x13}; /* Special command to enable reading */ static uint8_t magic_data[] = {0x01, 0x13}; /* Special command to enable reading */
struct pad_connection* connection = (struct pad_connection*)data; struct pad_connection* connection = (struct pad_connection*)data;
@ -47,10 +47,11 @@ static void* hidpad_wiiugca_init(void *data, uint32_t slot, send_control_t ptr)
return NULL; return NULL;
} }
device->connection = connection; device->connection = connection;
device->slot = slot; device->slot = slot;
device->send_control = ptr; device->driver = driver;
device->send_control(device->connection, magic_data, sizeof(magic_data));
device->driver->send_control(device->connection, magic_data, sizeof(magic_data));
return device; return device;
} }

View File

@ -62,7 +62,7 @@ struct wiiupro_calib
struct hidpad_wiiupro_data struct hidpad_wiiupro_data
{ {
struct pad_connection* connection; struct pad_connection* connection;
send_control_t send_control; hid_driver_t *driver;
struct wiiupro data; struct wiiupro data;
uint32_t slot; uint32_t slot;
bool have_led; bool have_led;
@ -75,12 +75,12 @@ static void hidpad_wiiupro_send_control(struct hidpad_wiiupro_data* device)
{ {
/* 0x12 = Set data report; 0x34 = All buttons and analogs */ /* 0x12 = Set data report; 0x34 = All buttons and analogs */
static uint8_t report_buffer[4] = { 0xA2, 0x12, 0x00, 0x34 }; static uint8_t report_buffer[4] = { 0xA2, 0x12, 0x00, 0x34 };
device->send_control(device->connection, device->driver->send_control(device->connection,
report_buffer, sizeof(report_buffer)); report_buffer, sizeof(report_buffer));
} }
static void* hidpad_wiiupro_init(void *data, static void* hidpad_wiiupro_init(void *data,
uint32_t slot, send_control_t ptr) uint32_t slot, hid_driver_t *driver)
{ {
struct pad_connection* connection = (struct pad_connection*)data; struct pad_connection* connection = (struct pad_connection*)data;
struct hidpad_wiiupro_data* device = (struct hidpad_wiiupro_data*) struct hidpad_wiiupro_data* device = (struct hidpad_wiiupro_data*)
@ -94,9 +94,9 @@ static void* hidpad_wiiupro_init(void *data,
if (!connection) if (!connection)
goto error; goto error;
device->connection = connection; device->connection = connection;
device->slot = slot; device->slot = slot;
device->send_control = ptr; device->driver = driver;
calib_data->calib_round = 0; calib_data->calib_round = 0;
/* Without this, the digital buttons won't be reported. */ /* Without this, the digital buttons won't be reported. */

View File

@ -64,7 +64,7 @@ joypad_connection_t *pad_connection_init(unsigned pads)
int32_t pad_connection_pad_init(joypad_connection_t *joyconn, int32_t pad_connection_pad_init(joypad_connection_t *joyconn,
const char *name, uint16_t vid, uint16_t pid, const char *name, uint16_t vid, uint16_t pid,
void *data, send_control_t ptr) void *data, hid_driver_t *driver)
{ {
static const struct static const struct
@ -120,7 +120,7 @@ int32_t pad_connection_pad_init(joypad_connection_t *joyconn,
if (name_match || (pad_map[i].vid == vid && pad_map[i].pid == pid)) if (name_match || (pad_map[i].vid == vid && pad_map[i].pid == pid))
{ {
s->iface = pad_map[i].iface; s->iface = pad_map[i].iface;
s->data = s->iface->init(data, pad, ptr); s->data = s->iface->init(data, pad, driver);
s->connected = true; s->connected = true;
#if 0 #if 0
RARCH_LOG("%s found \n", pad_map[i].name); RARCH_LOG("%s found \n", pad_map[i].name);

View File

@ -23,7 +23,7 @@
#include <libretro.h> #include <libretro.h>
#include <retro_miscellaneous.h> #include <retro_miscellaneous.h>
typedef void (*send_control_t)(void *data, uint8_t *buf, size_t size); #include "../input_driver.h"
struct joypad_connection struct joypad_connection
{ {
@ -34,7 +34,7 @@ struct joypad_connection
typedef struct pad_connection_interface typedef struct pad_connection_interface
{ {
void* (*init)(void *data, uint32_t slot, send_control_t ptr); void* (*init)(void *data, uint32_t slot, hid_driver_t *driver);
void (*deinit)(void* device); void (*deinit)(void* device);
void (*packet_handler)(void* device, uint8_t *packet, uint16_t size); void (*packet_handler)(void* device, uint8_t *packet, uint16_t size);
void (*set_rumble)(void* device, enum retro_rumble_effect effect, void (*set_rumble)(void* device, enum retro_rumble_effect effect,
@ -58,7 +58,7 @@ extern pad_connection_interface_t pad_connection_psxadapter;
int32_t pad_connection_pad_init(joypad_connection_t *joyconn, int32_t pad_connection_pad_init(joypad_connection_t *joyconn,
const char* name, uint16_t vid, uint16_t pid, const char* name, uint16_t vid, uint16_t pid,
void *data, send_control_t ptr); void *data, hid_driver_t *driver);
joypad_connection_t *pad_connection_init(unsigned pads); joypad_connection_t *pad_connection_init(unsigned pads);

View File

@ -127,7 +127,7 @@ static void wiiu_input_poll(void *data)
if(wiiu->joypad) if(wiiu->joypad)
wiiu->joypad->poll(); wiiu->joypad->poll();
if(wiiu->hid_joypad) if(wiiu->hid_joypad)
wiiu->hid_joypad->poll(); wiiu->hid_joypad->poll(hid_driver_get_data());
} }
static bool wiiu_key_pressed(int key) static bool wiiu_key_pressed(int key)

View File

@ -1210,7 +1210,7 @@ static void btpad_packet_handler(uint8_t packet_type,
RARCH_LOG("[BTpad]: Got %.200s.\n", (char*)&packet[9]); RARCH_LOG("[BTpad]: Got %.200s.\n", (char*)&packet[9]);
connection->slot = pad_connection_pad_init(&slots[connection->slot], connection->slot = pad_connection_pad_init(&slots[connection->slot],
(char*)packet + 9, 0, 0, connection, &btpad_connection_send_control); (char*)packet + 9, 0, 0, connection, &btstack_hid);
connection->state = BTPAD_CONNECTED; connection->state = BTPAD_CONNECTED;
} }
break; break;

View File

@ -510,7 +510,7 @@ static void iohidmanager_hid_device_add(void *data, IOReturn result,
adapter->slot = pad_connection_pad_init(hid->slots, adapter->slot = pad_connection_pad_init(hid->slots,
adapter->name, dev_vid, dev_pid, adapter, adapter->name, dev_vid, dev_pid, adapter,
&iohidmanager_hid_device_send_control); &iohidmanager_hid);
if (adapter->slot == -1) if (adapter->slot == -1)
goto error; goto error;

View File

@ -308,7 +308,7 @@ static int add_adapter(void *data, struct libusb_device *dev)
adapter->slot = pad_connection_pad_init(hid->slots, adapter->slot = pad_connection_pad_init(hid->slots,
device_name, desc.idVendor, desc.idProduct, device_name, desc.idVendor, desc.idProduct,
adapter, &libusb_hid_device_send_control); adapter, &libusb_hid);
if (adapter->slot == -1) if (adapter->slot == -1)
goto error; goto error;

View File

@ -258,13 +258,6 @@ static int32_t wiiu_attach_callback(HIDClient *client, HIDDevice *device, uint32
} }
static int32_t wiiu_hid_pad_init(joypad_connection_t *joyconn,
const char *name, uint16_t vid, uint16_t pid, void *data,
send_control_t ptr) {
int pad = pad_connection_find_vacant_pad_max(joyconn, MAX_HID_PADS);
return pad_connection_pad_init_with_slot(joyconn, name, vid, pid,
data, ptr, pad);
}
static void wiiu_hid_detach(wiiu_hid_t *hid, wiiu_attach_event *event) { static void wiiu_hid_detach(wiiu_hid_t *hid, wiiu_attach_event *event) {
} }
@ -280,9 +273,9 @@ static void wiiu_hid_attach(wiiu_hid_t *hid, wiiu_attach_event *event) {
adapter->hid = hid; adapter->hid = hid;
adapter->handle = event->handle; adapter->handle = event->handle;
adapter->slot = wiiu_hid_pad_init(hid->connections, adapter->slot = pad_connection_pad_init(hid->connections,
"hid", event->vendor_id, event->product_id, adapter, "hid", event->vendor_id, event->product_id, adapter,
&wiiu_hid_device_send_control); &wiiu_hid);
if(adapter->slot < 0) { if(adapter->slot < 0) {
RARCH_ERR("[hid]: No available slots.\n"); RARCH_ERR("[hid]: No available slots.\n");

View File

@ -81,9 +81,6 @@ static int wiiu_hid_polling_thread(int argc, const char **argv);
static int32_t wiiu_attach_callback(HIDClient *client, HIDDevice *device, uint32_t attach); static int32_t wiiu_attach_callback(HIDClient *client, HIDDevice *device, uint32_t attach);
static wiiu_attach_event *synchronized_get_events_list(void); static wiiu_attach_event *synchronized_get_events_list(void);
static void wiiu_handle_attach_events(wiiu_hid_t *hid, wiiu_attach_event *list); static void wiiu_handle_attach_events(wiiu_hid_t *hid, wiiu_attach_event *list);
static int32_t wiiu_hid_pad_init(joypad_connection_t *joyconn,
const char *name, uint16_t vid, uint16_t pid, void *data,
send_control_t ptr);
static void wiiu_hid_attach(wiiu_hid_t *hid, wiiu_attach_event *event); static void wiiu_hid_attach(wiiu_hid_t *hid, wiiu_attach_event *event);
static void wiiu_hid_detach(wiiu_hid_t *hid, wiiu_attach_event *event); static void wiiu_hid_detach(wiiu_hid_t *hid, wiiu_attach_event *event);
static void synchronized_add_to_adapters_list(struct wiiu_adapter *adapter); static void synchronized_add_to_adapters_list(struct wiiu_adapter *adapter);

View File

@ -322,7 +322,7 @@ static int wiiusb_hid_add_adapter(void *data, usb_device_entry *dev)
* control name until we get its interface */ * control name until we get its interface */
adapter->slot = pad_connection_pad_init(hid->connections, adapter->slot = pad_connection_pad_init(hid->connections,
"hid", desc.idVendor, desc.idProduct, "hid", desc.idVendor, desc.idProduct,
adapter, &wiiusb_hid_device_send_control); adapter, &wiiusb_hid);
if (adapter->slot == -1) if (adapter->slot == -1)
goto error; goto error;

View File

@ -193,6 +193,7 @@ struct hid_driver
bool (*set_rumble)(void *, unsigned, enum retro_rumble_effect, uint16_t); bool (*set_rumble)(void *, unsigned, enum retro_rumble_effect, uint16_t);
const char *(*name)(void *, unsigned); const char *(*name)(void *, unsigned);
const char *ident; const char *ident;
void (*send_control)(void *data, uint8_t *buf, size_t size);
int32_t (*set_report)(void *, uint8_t, uint8_t, void *, uint32_t); int32_t (*set_report)(void *, uint8_t, uint8_t, void *, uint32_t);
int32_t (*set_idle)(void *, uint8_t, uint8_t); int32_t (*set_idle)(void *, uint8_t, uint8_t);
int32_t (*set_protocol)(void *, uint8_t, uint8_t); int32_t (*set_protocol)(void *, uint8_t, uint8_t);