diff --git a/input/common/hid/device_ds3.c b/input/common/hid/device_ds3.c index 9af43ac1c6..569d4d7f79 100644 --- a/input/common/hid/device_ds3.c +++ b/input/common/hid/device_ds3.c @@ -16,12 +16,38 @@ #include "hid_device_driver.h" +struct ds3_instance { + hid_driver_t *driver; + void *handle; +}; + +static void *ds3_init(hid_driver_instance_t *hid_driver) +{ + return NULL; +} + +static void ds3_free(void *data) +{ + struct ds3_instance *instance = (struct ds3_instance *)data; + if(!instance) + return; + + free(instance); +} + +static void ds3_handle_packet(void *data, uint8_t *buffer, size_t size) +{ +} + static bool ds3_detect(uint16_t vendor_id, uint16_t product_id) { return vendor_id == VID_SONY && product_id == PID_SONY_DS3; } hid_device_t ds3_hid_device = { + ds3_init, + ds3_free, + ds3_handle_packet, ds3_detect, "Sony DualShock 3" }; diff --git a/input/common/hid/device_ds4.c b/input/common/hid/device_ds4.c index 7c90ebaf0a..6c8b77ac2f 100644 --- a/input/common/hid/device_ds4.c +++ b/input/common/hid/device_ds4.c @@ -16,12 +16,38 @@ #include "hid_device_driver.h" +struct ds4_instance { + hid_driver_t *driver; + void *handle; +}; + +static void *ds4_init(hid_driver_instance_t *hid_driver) +{ + return NULL; +} + +static void ds4_free(void *data) +{ + struct ds4_instance *instance = (struct ds4_instance *)data; + if(!instance) + return; + + free(instance); +} + +static void ds4_handle_packet(void *data, uint8_t *buffer, size_t size) +{ +} + static bool ds4_detect(uint16_t vendor_id, uint16_t product_id) { return vendor_id == VID_SONY && product_id == PID_SONY_DS4; } hid_device_t ds4_hid_device = { + ds4_init, + ds4_free, + ds4_handle_packet, ds4_detect, "Sony DualShock 4" }; diff --git a/input/common/hid/device_wiiu_gca.c b/input/common/hid/device_wiiu_gca.c index ec68aa897d..211f67dfbb 100644 --- a/input/common/hid/device_wiiu_gca.c +++ b/input/common/hid/device_wiiu_gca.c @@ -16,11 +16,123 @@ #include "hid_device_driver.h" +#ifdef WII +static uint8_t activation_packet[] = { 0x01, 0x13 }; +#else +static uint8_t activation_packet[] = { 0x13 }; +#endif + +#define GCA_PORT_INITIALIZING 0x00 +#define GCA_PORT_EMPTY 0x04 +#define GCA_PORT_CONNECTED 0x14 + +typedef struct wiiu_gca_instance { + hid_driver_instance_t *driver; + uint8_t device_state[37]; + joypad_connection_t *pads[4]; +} wiiu_gca_instance_t; + +static void update_pad_state(wiiu_gca_instance_t *instance); +static joypad_connection_t *register_pad(wiiu_gca_instance_t *instance); + +extern pad_connection_interface_t wiiu_gca_pad_connection; + +static void *wiiu_gca_init(hid_driver_instance_t *driver) +{ + wiiu_gca_instance_t *instance = calloc(1, sizeof(wiiu_gca_instance_t)); + memset(instance, 0, sizeof(wiiu_gca_instance_t)); + instance->driver = driver; + + driver->hid_driver->send_control(driver->hid_data, activation_packet, sizeof(activation_packet)); + driver->hid_driver->read(driver->hid_data, instance->device_state, sizeof(instance->device_state)); + + return instance; +} + +static void wiiu_gca_free(void *data) { + wiiu_gca_instance_t *instance = (wiiu_gca_instance_t *)data; + if(instance) { + free(instance); + } +} + +static void wiiu_gca_handle_packet(void *data, uint8_t *buffer, size_t size) +{ + wiiu_gca_instance_t *instance = (wiiu_gca_instance_t *)data; + if(!instance) + return; + + if(size > sizeof(instance->device_state)) + return; + + memcpy(instance->device_state, buffer, size); + update_pad_state(instance); +} + +static void update_pad_state(wiiu_gca_instance_t *instance) +{ + int i, pad; + + /* process each pad */ + for(i = 1; i < 37; i += 9) + { + pad = i / 9; + switch(instance->device_state[i]) + { + case GCA_PORT_INITIALIZING: + case GCA_PORT_EMPTY: + if(instance->pads[pad] != NULL) + { + /* TODO: free pad */ + instance->pads[pad] = NULL; + } + break; + case GCA_PORT_CONNECTED: + if(instance->pads[pad] == NULL) + { + instance->pads[pad] = register_pad(instance); + } + } + } +} + +static joypad_connection_t *register_pad(wiiu_gca_instance_t *instance) { + int slot; + joypad_connection_t *result; + + slot = pad_connection_find_vacant_pad(instance->driver->pad_connection_list); + if(slot < 0) + return NULL; + + result = &(instance->driver->pad_connection_list[slot]); + result->iface = &wiiu_gca_pad_connection; + result->data = result->iface->init(instance, slot, instance->driver->hid_driver); + result->connected = true; + input_pad_connect(slot, instance->driver->pad_driver); + + return result; +} + static bool wiiu_gca_detect(uint16_t vendor_id, uint16_t product_id) { return vendor_id == VID_NINTENDO && product_id == PID_NINTENDO_GCA; } hid_device_t wiiu_gca_hid_device = { + wiiu_gca_init, + wiiu_gca_free, + wiiu_gca_handle_packet, wiiu_gca_detect, "Wii U Gamecube Adapter" }; + +pad_connection_interface_t wiiu_gca_pad_connection = { +/* + wiiu_gca_pad_init, + wiiu_gca_pad_deinit, + wiiu_gca_packet_handler, + wiiu_gca_set_rumble, + wiiu_gca_get_buttons, + wiiu_gca_get_axis, + wiiu_gca_get_name +*/ +}; diff --git a/input/common/hid/hid_device_driver.c b/input/common/hid/hid_device_driver.c index 0f049ca728..a3b861bf4d 100644 --- a/input/common/hid/hid_device_driver.c +++ b/input/common/hid/hid_device_driver.c @@ -16,6 +16,8 @@ #include "hid_device_driver.h" +hid_driver_instance_t hid_instance = {0}; + hid_device_t *hid_device_list[] = { &wiiu_gca_hid_device, &ds3_hid_device, @@ -34,3 +36,102 @@ hid_device_t *hid_device_driver_lookup(uint16_t vendor_id, uint16_t product_id) return NULL; } +void hid_pad_connect(hid_driver_instance_t *instance, int pad) +{ + if(!instance || !instance->pad_driver) + return; + + input_pad_connect(pad, instance->pad_driver); +} + +/** + * Fill in instance with data from initialized hid subsystem. + * + * @argument instance the hid_driver_instance_t struct to fill in + * @argument hid_driver the HID driver to initialize + * @argument pad_driver the gamepad driver to handle HID pads detected by the HID driver. + * + * @returns true if init is successful, false otherwise. + */ +bool hid_init(hid_driver_instance_t *instance, + hid_driver_t *hid_driver, + input_device_driver_t *pad_driver, + unsigned slots) +{ + if(!instance || !hid_driver || !pad_driver || slots > MAX_USERS) + return false; + + instance->hid_data = hid_driver->init(instance); + if(!instance->hid_data) + return false; + + instance->pad_connection_list = pad_connection_init(slots); + if(!instance->pad_connection_list) + { + hid_driver->free(instance->hid_data); + instance->hid_data = NULL; + return false; + } + + instance->max_slot = slots; + instance->hid_driver = hid_driver; + instance->pad_driver = pad_driver; + + return true; +} + +/** + * Tear down the HID system set up by hid_init() + * + * @argument instance the hid_driver_instance_t to tear down. + */ +void hid_deinit(hid_driver_instance_t *instance) +{ + if(!instance) + return; + + pad_connection_destroy(instance->pad_connection_list); + + if(instance->hid_driver && instance->hid_data) + { + instance->hid_driver->free(instance->hid_data); + } + + memset(instance, 0, sizeof(hid_driver_instance_t)); +} + +static void hid_device_log_buffer(uint8_t *data, uint32_t len) +{ +#if 0 + int i, offset; + int padding = len % 0x0F; + uint8_t buf[16]; + + RARCH_LOG("%d bytes read:\n", len); + + for(i = 0, offset = 0; i < len; i++) + { + buf[offset] = data[i]; + offset++; + if(offset == 16) + { + offset = 0; + RARCH_LOG("%02x%02x%02x%02x%02x%02x%02x%02x %02x%02x%02x%02x%02x%02x%02x%02x\n", + buf[0], buf[1], buf[2], buf[3], buf[4], buf[5], buf[6], buf[7], + buf[8], buf[9], buf[10], buf[11], buf[12], buf[13], buf[14], buf[15]); + } + } + + if(padding) + { + for(i = padding; i < 16; i++) + buf[i] = 0xff; + + RARCH_LOG("%02x%02x%02x%02x%02x%02x%02x%02x %02x%02x%02x%02x%02x%02x%02x%02x\n", + buf[0], buf[1], buf[2], buf[3], buf[4], buf[5], buf[6], buf[7], + buf[8], buf[9], buf[10], buf[11], buf[12], buf[13], buf[14], buf[15]); + } + + RARCH_LOG("=================================\n"); + #endif +} diff --git a/input/common/hid/hid_device_driver.h b/input/common/hid/hid_device_driver.h index a3259aee52..8bb371f70e 100644 --- a/input/common/hid/hid_device_driver.h +++ b/input/common/hid/hid_device_driver.h @@ -19,8 +19,12 @@ #include "../../input_driver.h" #include "../../connect/joypad_connection.h" +#include "../../include/hid_driver.h" typedef struct hid_device { + void *(*init)(hid_driver_instance_t *driver); + void (*free)(void *data); + void (*handle_packet)(void *data, uint8_t *buffer, size_t size); bool (*detect)(uint16_t vid, uint16_t pid); const char *name; } hid_device_t; @@ -28,7 +32,12 @@ typedef struct hid_device { extern hid_device_t wiiu_gca_hid_device; extern hid_device_t ds3_hid_device; extern hid_device_t ds4_hid_device; +extern hid_driver_instance_t hid_instance; hid_device_t *hid_device_driver_lookup(uint16_t vendor_id, uint16_t product_id); +void hid_pad_connect(hid_driver_instance_t *instance, int pad); +bool hid_init(hid_driver_instance_t *instance, hid_driver_t *hid_driver, input_device_driver_t *pad_driver, unsigned slots); +void hid_deinit(hid_driver_instance_t *instance); + #endif /* HID_DEVICE_DRIVER__H */ diff --git a/input/connect/connect_ps3.c b/input/connect/connect_ps3.c index 61269a9e88..f77235cf80 100644 --- a/input/connect/connect_ps3.c +++ b/input/connect/connect_ps3.c @@ -21,10 +21,7 @@ #include #include "joypad_connection.h" #include "../input_defines.h" - -#ifdef WIIU -#include -#endif +#include "../common/hid/hid_device_driver.h" struct hidpad_ps3_data { diff --git a/input/connect/connect_ps4.c b/input/connect/connect_ps4.c index 0356a91537..f011bd3ab8 100644 --- a/input/connect/connect_ps4.c +++ b/input/connect/connect_ps4.c @@ -25,6 +25,7 @@ #include "joypad_connection.h" #include "../input_defines.h" #include "../../driver.h" +#include "../common/hid/hid_device_driver.h" enum connect_ps4_dpad_states { diff --git a/input/connect/connect_wii.c b/input/connect/connect_wii.c index f02e1735be..74865862aa 100644 --- a/input/connect/connect_wii.c +++ b/input/connect/connect_wii.c @@ -26,6 +26,7 @@ #include "joypad_connection.h" #include "../input_defines.h" +#include "../common/hid/hid_device_driver.h" /* wiimote state flags*/ #define WIIMOTE_STATE_DEV_FOUND 0x0001 diff --git a/input/connect/connect_wiiugca.c b/input/connect/connect_wiiugca.c index 7e49969fd2..3803488797 100644 --- a/input/connect/connect_wiiugca.c +++ b/input/connect/connect_wiiugca.c @@ -21,6 +21,7 @@ #include #include "joypad_connection.h" #include "../input_defines.h" +#include "../common/hid/hid_device_driver.h" struct hidpad_wiiugca_data { diff --git a/input/connect/connect_wiiupro.c b/input/connect/connect_wiiupro.c index 836f17856e..d2ad16a968 100644 --- a/input/connect/connect_wiiupro.c +++ b/input/connect/connect_wiiupro.c @@ -23,6 +23,7 @@ #include "joypad_connection.h" #include "../input_defines.h" #include "../../driver.h" +#include "../common/hid/hid_device_driver.h" struct wiiupro_buttons { diff --git a/input/drivers_hid/btstack_hid.c b/input/drivers_hid/btstack_hid.c index 1d277484aa..68f20ea666 100644 --- a/input/drivers_hid/btstack_hid.c +++ b/input/drivers_hid/btstack_hid.c @@ -1439,14 +1439,17 @@ static void btstack_hid_free(const void *data) free(hid); } -static void *btstack_hid_init(void) +static void *btstack_hid_init(joypad_connection_t *connections) { btstack_hid_t *hid = (btstack_hid_t*)calloc(1, sizeof(btstack_hid_t)); if (!hid) goto error; - hid->slots = pad_connection_init(MAX_USERS); + if(connections == NULL) + connections = pad_connection_init(MAX_USERS); + + hid->slots = connections; if (!hid->slots) goto error; diff --git a/input/drivers_hid/iohidmanager_hid.c b/input/drivers_hid/iohidmanager_hid.c index 9ad99ebe2f..ad60d4c969 100644 --- a/input/drivers_hid/iohidmanager_hid.c +++ b/input/drivers_hid/iohidmanager_hid.c @@ -854,14 +854,18 @@ static int iohidmanager_hid_manager_set_device_matching( return 0; } -static void *iohidmanager_hid_init(void) +static void *iohidmanager_hid_init(joypad_connection_t *connections) { iohidmanager_hid_t *hid_apple = (iohidmanager_hid_t*) calloc(1, sizeof(*hid_apple)); if (!hid_apple) goto error; - hid_apple->slots = pad_connection_init(MAX_USERS); + + if (connections == NULL) + connections = pad_connection_init(MAX_USERS); + + hid_apple->slots = connections; if (!hid_apple->slots) goto error; diff --git a/input/drivers_hid/libusb_hid.c b/input/drivers_hid/libusb_hid.c index 44580359fa..f06adb5366 100644 --- a/input/drivers_hid/libusb_hid.c +++ b/input/drivers_hid/libusb_hid.c @@ -546,7 +546,7 @@ static void poll_thread(void *data) } } -static void *libusb_hid_init(void) +static void *libusb_hid_init(joypad_connection_t *connections) { unsigned i, count; int ret; @@ -578,7 +578,10 @@ static void *libusb_hid_init(void) hid->can_hotplug = 0; #endif - hid->slots = pad_connection_init(MAX_USERS); + if (connections == NULL) + connections = pad_connection_init(MAX_USERS); + + hid->slots = connections; if (!hid->slots) goto error; diff --git a/input/drivers_hid/null_hid.c b/input/drivers_hid/null_hid.c index 70a34d4bf8..e7cf00b580 100644 --- a/input/drivers_hid/null_hid.c +++ b/input/drivers_hid/null_hid.c @@ -18,6 +18,7 @@ #include "../input_defines.h" #include "../input_driver.h" +#include "../include/hid_driver.h" typedef struct null_hid { @@ -75,8 +76,10 @@ static int16_t null_hid_joypad_axis(void *data, unsigned port, uint32_t joyaxis) return 0; } -static void *null_hid_init(void) +static void *null_hid_init(hid_driver_instance_t *instance) { + (void)instance; + return (null_hid_t*)calloc(1, sizeof(null_hid_t)); } diff --git a/input/drivers_hid/wiiusb_hid.c b/input/drivers_hid/wiiusb_hid.c index 397f0a0a64..6e3a768bca 100644 --- a/input/drivers_hid/wiiusb_hid.c +++ b/input/drivers_hid/wiiusb_hid.c @@ -574,15 +574,15 @@ static void wiiusb_hid_free(const void *data) free(hid); } -static void *wiiusb_hid_init(void) +static void *wiiusb_hid_init(joypad_connection_t *connections) { - joypad_connection_t *connections = NULL; wiiusb_hid_t *hid = (wiiusb_hid_t*)calloc(1, sizeof(*hid)); if (!hid) goto error; - connections = pad_connection_init(MAX_USERS); + if(connections == NULL) + connections = pad_connection_init(MAX_USERS); if (!connections) goto error; diff --git a/input/include/hid_driver.h b/input/include/hid_driver.h new file mode 100644 index 0000000000..37ae190a51 --- /dev/null +++ b/input/include/hid_driver.h @@ -0,0 +1,63 @@ +/* RetroArch - A frontend for libretro. + * Copyright (C) 2010-2014 - Hans-Kristian Arntzen + * Copyright (C) 2011-2017 - Daniel De Matteis + * Copyright (C) 2016-2017 - Andrés Suárez + * + * RetroArch is free software: you can redistribute it and/or modify it under the terms + * of the GNU General Public License as published by the Free Software Found- + * ation, either version 3 of the License, or (at your option) any later version. + * + * RetroArch is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; + * without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR + * PURPOSE. See the GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License along with RetroArch. + * If not, see . + */ + +#ifndef HID_DRIVER_H__ +#define HID_DRIVER_H__ + +#include "../connect/joypad_connection.h" +#include "../input_driver.h" + +/* what is 1? */ +#define HID_REPORT_OUTPUT 2 +#define HID_REPORT_FEATURE 3 +/* are there more? */ + +/* + * This is the interface for the HID subsystem. + * + * The handle parameter is the pointer returned by init() and stores the implementation + * state data for the HID driver. + */ + +struct hid_driver +{ + void *(*init)(hid_driver_instance_t *); + bool (*query_pad)(void *handle, unsigned pad); + void (*free)(const void *handle); + bool (*button)(void *handle, unsigned pad, uint16_t button); + void (*get_buttons)(void *handle, unsigned pad, retro_bits_t *state); + int16_t (*axis)(void *handle, unsigned pad, uint32_t axis); + void (*poll)(void *handle); + bool (*set_rumble)(void *handle, unsigned pad, enum retro_rumble_effect effect, uint16_t); + const char *(*name)(void *handle, unsigned pad); + const char *ident; + void (*send_control)(void *handle, uint8_t *buf, size_t size); + int32_t (*set_report)(void *handle, uint8_t, uint8_t, void *data, uint32_t size); + int32_t (*set_idle)(void *handle, uint8_t amount); + int32_t (*set_protocol)(void *handle, uint8_t protocol); + int32_t (*read)(void *handle, void *buf, size_t size); +}; + +struct hid_driver_instance { + hid_driver_t *hid_driver; + void *hid_data; + input_device_driver_t *pad_driver; + joypad_connection_t *pad_connection_list; + unsigned max_slot; +}; + +#endif /* HID_DRIVER_H__ */ diff --git a/input/include/hid_types.h b/input/include/hid_types.h new file mode 100644 index 0000000000..28734e9dd8 --- /dev/null +++ b/input/include/hid_types.h @@ -0,0 +1,24 @@ +/* RetroArch - A frontend for libretro. + * Copyright (C) 2010-2014 - Hans-Kristian Arntzen + * Copyright (C) 2011-2017 - Daniel De Matteis + * Copyright (C) 2016-2017 - Andrés Suárez + * + * RetroArch is free software: you can redistribute it and/or modify it under the terms + * of the GNU General Public License as published by the Free Software Found- + * ation, either version 3 of the License, or (at your option) any later version. + * + * RetroArch is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; + * without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR + * PURPOSE. See the GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License along with RetroArch. + * If not, see . + */ + +#ifndef HID_TYPES_H__ +#define HID_TYPES_H__ + +typedef struct hid_driver hid_driver_t; +typedef struct hid_driver_instance hid_driver_instance_t; + +#endif /* HID_TYPES_H__ */ diff --git a/input/input_driver.c b/input/input_driver.c index 14ed1c17a9..882d33ca1b 100644 --- a/input/input_driver.c +++ b/input/input_driver.c @@ -1782,6 +1782,19 @@ bool input_mouse_button_raw(unsigned port, unsigned id) return false; } +void input_pad_connect(unsigned port, input_device_driver_t *driver) +{ + if(port >= MAX_USERS || !driver) + { + RARCH_ERR("[input]: input_pad_connect: bad parameters\n"); + return; + } + + if(!input_autoconfigure_connect(driver->name(port), NULL, driver->ident, + port, 0, 0)) + input_config_set_device_name(port, driver->name(port)); +} + /** * input_conv_analog_id_to_bind_id: * @idx : Analog key index. diff --git a/input/input_driver.h b/input/input_driver.h index 2ef47c7d24..b366413893 100644 --- a/input/input_driver.h +++ b/input/input_driver.h @@ -35,13 +35,12 @@ #include "input_defines.h" #include "../msg_hash.h" +#include "include/hid_types.h" RETRO_BEGIN_DECLS typedef struct rarch_joypad_driver input_device_driver_t; -typedef struct hid_driver hid_driver_t; - /* Keyboard line reader. Handles textual input in a direct fashion. */ typedef struct input_keyboard_line input_keyboard_line_t; @@ -181,25 +180,6 @@ struct rarch_joypad_driver const char *ident; }; -struct hid_driver -{ - void *(*init)(void); - bool (*query_pad)(void *, unsigned); - void (*free)(const void *); - bool (*button)(void *, unsigned, uint16_t); - void (*get_buttons)(void *, unsigned, retro_bits_t *); - int16_t (*axis)(void *, unsigned, uint32_t); - void (*poll)(void *); - bool (*set_rumble)(void *, unsigned, enum retro_rumble_effect, uint16_t); - const char *(*name)(void *, unsigned); - 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_idle)(void *, uint8_t); - int32_t (*set_protocol)(void *, uint8_t); - -}; - /** * input_driver_find_handle: * @index : index of driver to get handle to. @@ -591,6 +571,15 @@ bool input_joypad_button_raw(const input_device_driver_t *driver, bool input_joypad_hat_raw(const input_device_driver_t *driver, unsigned joypad, unsigned hat_dir, unsigned hat); +/** + * input_pad_connect: + * @port : Joystick number. + * @driver : handle for joypad driver handling joystick's input + * + * Registers a newly connected pad with RetroArch. + **/ +void input_pad_connect(unsigned port, input_device_driver_t *driver); + /** * input_mouse_button_raw: * @port : Mouse number. @@ -848,7 +837,6 @@ extern hid_driver_t iohidmanager_hid; extern hid_driver_t btstack_hid; extern hid_driver_t libusb_hid; extern hid_driver_t wiiusb_hid; -extern hid_driver_t wiiu_hid; extern hid_driver_t null_hid; #endif diff --git a/wiiu/include/wiiu/pad_driver.h b/wiiu/include/wiiu/pad_driver.h index 8a93798de7..067bc34d67 100644 --- a/wiiu/include/wiiu/pad_driver.h +++ b/wiiu/include/wiiu/pad_driver.h @@ -32,8 +32,8 @@ #include "../../input/input_driver.h" #include "../../input/common/hid/hid_device_driver.h" -#include "../../input/connect/joypad_connection.h" #include "../../tasks/tasks_internal.h" +#include "../../input/connect/joypad_connection.h" #include "../../retroarch.h" #include "../../verbosity.h" #include "../../command.h" @@ -119,8 +119,8 @@ struct _wiiu_pad_functions { typedef struct wiiu_hid { /* used to register for HID notifications */ HIDClient *client; - /* list of HID pads */ - joypad_connection_t *connections; + /* pointer to HID driver state */ + hid_driver_instance_t *driver; /* size of connections list */ unsigned connections_size; /* thread state data for HID polling thread */ @@ -135,13 +135,14 @@ typedef struct wiiu_adapter wiiu_adapter_t; struct wiiu_adapter { wiiu_adapter_t *next; + hid_device_t *driver; + void *driver_handle; wiiu_hid_t *hid; uint8_t state; uint8_t *rx_buffer; int32_t rx_size; uint8_t *tx_buffer; int32_t tx_size; - int32_t slot; uint32_t handle; uint8_t interface_index; }; diff --git a/wiiu/include/wiiu/syshid.h b/wiiu/include/wiiu/syshid.h index 1f55718dd9..664e52eef6 100644 --- a/wiiu/include/wiiu/syshid.h +++ b/wiiu/include/wiiu/syshid.h @@ -1,15 +1,6 @@ #pragma once #include -/* - * Report types for the report_type parameter in HIDSetReport() - */ - -/* what is 1? */ -#define HID_REPORT_OUTPUT 2 -#define HID_REPORT_FEATURE 3 -/* are there more? */ - typedef struct { uint32_t handle; diff --git a/wiiu/input/hidpad_driver.c b/wiiu/input/hidpad_driver.c index 5cae6d710f..272bd2e7c0 100644 --- a/wiiu/input/hidpad_driver.c +++ b/wiiu/input/hidpad_driver.c @@ -15,6 +15,8 @@ */ #include +#include "../../input/include/hid_driver.h" +#include "../../input/common/hid/hid_device_driver.h" static bool hidpad_init(void *data); static bool hidpad_query_pad(unsigned pad); @@ -27,51 +29,25 @@ static const char *hidpad_name(unsigned pad); static bool ready = false; -static wiiu_hid_t *hid_data; -static hid_driver_t *hid_driver; - static unsigned to_slot(unsigned pad) { return pad - (WIIU_WIIMOTE_CHANNELS+1); } -const void *get_hid_data(void) +static bool init_hid_driver(void) { - return hid_data; -} - -static hid_driver_t *init_hid_driver(void) -{ - joypad_connection_t *connections = NULL; unsigned connections_size = MAX_USERS - (WIIU_WIIMOTE_CHANNELS+1); - hid_data = (wiiu_hid_t *)wiiu_hid.init(); - connections = pad_connection_init(connections_size); + memset(&hid_instance, 0, sizeof(hid_instance)); - if (!hid_data || !connections) - goto error; - - hid_data->connections = connections; - hid_data->connections_size = connections_size; - return &wiiu_hid; - -error: - if (connections) - free(connections); - if (hid_data) - { - wiiu_hid.free(hid_data); - hid_data = NULL; - } - return NULL; + return hid_init(&hid_instance, &wiiu_hid, &hidpad_driver, connections_size); } static bool hidpad_init(void *data) { (void *)data; - hid_driver = init_hid_driver(); - if (!hid_driver) + if(!init_hid_driver()) { RARCH_ERR("Failed to initialize HID driver.\n"); return false; @@ -92,16 +68,7 @@ static void hidpad_destroy(void) { ready = false; - if(hid_driver) { - hid_driver->free(hid_data); - hid_data = NULL; - hid_driver = NULL; - } - - if(hid_data) { - free(hid_data); - hid_data = NULL; - } + hid_deinit(&hid_instance); } static bool hidpad_button(unsigned pad, uint16_t button) diff --git a/wiiu/input/kpad_driver.c b/wiiu/input/kpad_driver.c index 48a7f428c3..51d203cec0 100644 --- a/wiiu/input/kpad_driver.c +++ b/wiiu/input/kpad_driver.c @@ -117,7 +117,7 @@ static void kpad_register(unsigned channel, uint8_t device_type) if (wiimotes[channel].type != device_type) { wiimotes[channel].type = device_type; - pad_functions.connect(to_retro_pad(channel), &kpad_driver); + input_pad_connect(to_retro_pad(channel), &kpad_driver); } } diff --git a/wiiu/input/pad_functions.c b/wiiu/input/pad_functions.c index fe352e5da4..132bffa146 100644 --- a/wiiu/input/pad_functions.c +++ b/wiiu/input/pad_functions.c @@ -88,16 +88,8 @@ void wiiu_pad_read_axis_data(uint32_t axis, axis_data *data) } } -void wiiu_pad_connect(unsigned pad, input_device_driver_t *driver) -{ - if(!input_autoconfigure_connect(driver->name(pad), NULL, driver->ident, - pad, VID_NONE, PID_NONE)) - input_config_set_device_name(pad, driver->name(pad)); -} - wiiu_pad_functions_t pad_functions = { wiiu_pad_get_axis_value, wiiu_pad_set_axis_value, wiiu_pad_read_axis_data, - wiiu_pad_connect }; diff --git a/wiiu/input/wiiu_hid.c b/wiiu/input/wiiu_hid.c index f2656a4cbb..cb09db3346 100644 --- a/wiiu/input/wiiu_hid.c +++ b/wiiu/input/wiiu_hid.c @@ -19,13 +19,15 @@ static wiiu_event_list events; static wiiu_adapter_list adapters; +static void log_buffer(uint8_t *data, uint32_t len); + static bool wiiu_hid_joypad_query(void *data, unsigned slot) { wiiu_hid_t *hid = (wiiu_hid_t *)data; - if (!hid) + if (!hid || !hid->driver) return false; - return slot < hid->connections_size; + return slot < hid->driver->max_slot; } static const char *wiiu_hid_joypad_name(void *data, unsigned slot) @@ -35,7 +37,7 @@ static const char *wiiu_hid_joypad_name(void *data, unsigned slot) wiiu_hid_t *hid = (wiiu_hid_t *)data; - return hid->connections[slot].iface->get_name(data); + return hid->driver->pad_connection_list[slot].iface->get_name(data); } static void wiiu_hid_joypad_get_buttons(void *data, unsigned port, retro_bits_t *state) @@ -75,7 +77,7 @@ static int16_t wiiu_hid_joypad_axis(void *data, unsigned port, uint32_t joyaxis) return 0; } -static void *wiiu_hid_init(void) +static void *wiiu_hid_init(hid_driver_instance_t *driver) { RARCH_LOG("[hid]: initializing HID subsystem\n"); wiiu_hid_t *hid = new_hid(); @@ -84,6 +86,8 @@ static void *wiiu_hid_init(void) if (!hid || !client) goto error; + hid->driver = driver; + wiiu_hid_init_lists(); start_polling_thread(hid); if (!hid->polling_thread) @@ -98,6 +102,7 @@ static void *wiiu_hid_init(void) error: RARCH_LOG("[hid]: initialization failed. cleaning up.\n"); + stop_polling_thread(hid); delete_hid(hid); delete_hidclient(client); @@ -197,6 +202,26 @@ static int32_t wiiu_hid_set_protocol(void *data, uint8_t protocol) NULL, NULL); } +static int32_t wiiu_hid_read(void *data, void *buffer, size_t size) +{ + wiiu_adapter_t *adapter = (wiiu_adapter_t *)data; + + if(!adapter) + return -1; + + if(size > adapter->rx_size) + return -1; + +#if 1 + int32_t result = HIDRead(adapter->handle, buffer, size, NULL, NULL); + log_buffer(buffer, size); + return result; +#else + return HIDRead(adapter->handle, buffer, size, NULL, NULL); +#endif +} + + static void start_polling_thread(wiiu_hid_t *hid) { OSThreadAttributes attributes = OS_THREAD_ATTRIB_AFFINITY_CPU2; @@ -357,23 +382,12 @@ static void wiiu_hid_attach(wiiu_hid_t *hid, wiiu_attach_event *event) } adapter->hid = hid; - adapter->slot = pad_connection_pad_init(hid->connections, - "hid", event->vendor_id, event->product_id, adapter, - &wiiu_hid); + adapter->driver = event->driver; - if(adapter->slot < 0) - { - RARCH_ERR("[hid]: No available slots.\n"); - goto error; - } - - RARCH_LOG("[hid]: got slot %d\n", adapter->slot); - - if(!pad_connection_has_interface(hid->connections, adapter->slot)) - { - RARCH_ERR("[hid]: Interface not found for HID device with vid=0x%04x pid=0x%04x\n", - event->vendor_id, event->product_id); - goto error; + adapter->driver_handle = adapter->driver->init(hid->driver); + if(adapter->driver_handle == NULL) { + RARCH_ERR("[hid]: Failed to initialize driver: %s\n", + adapter->driver->name); } RARCH_LOG("[hid]: adding to adapter list\n"); @@ -446,16 +460,6 @@ static void log_buffer(uint8_t *data, uint32_t len) } -static void wiiu_hid_do_read(wiiu_adapter_t *adapter, - uint8_t *data, uint32_t length) -{ -#if 0 - log_buffer(data, length); -#endif - - /* TODO: get this data to the connect_xxx driver somehow. */ -} - static void wiiu_hid_read_loop_callback(uint32_t handle, int32_t error, uint8_t *buffer, uint32_t buffer_size, void *userdata) { @@ -468,12 +472,13 @@ static void wiiu_hid_read_loop_callback(uint32_t handle, int32_t error, if(adapter->hid->polling_thread_quit) { - RARCH_LOG("Shutting down read loop for slot %d\n", adapter->slot); + RARCH_LOG("Shutting down read loop for device: %s\n", + adapter->driver->name); adapter->state = ADAPTER_STATE_DONE; return; } - wiiu_hid_do_read(adapter, buffer, buffer_size); + adapter->driver->handle_packet(adapter->driver_handle, buffer, buffer_size); adapter->state = ADAPTER_STATE_READING; HIDRead(adapter->handle, adapter->rx_buffer, adapter->rx_size, @@ -644,6 +649,11 @@ static void delete_adapter(wiiu_adapter_t *adapter) free(adapter->tx_buffer); adapter->tx_buffer = NULL; } + if(adapter->driver && adapter->driver_handle) { + adapter->driver->free(adapter->driver_handle); + adapter->driver_handle = NULL; + adapter->driver = NULL; + } free(adapter); } @@ -707,6 +717,7 @@ hid_driver_t wiiu_hid = { wiiu_hid_send_control, wiiu_hid_set_report, wiiu_hid_set_idle, - wiiu_hid_set_protocol + wiiu_hid_set_protocol, + wiiu_hid_read, }; diff --git a/wiiu/input/wiiu_hid.h b/wiiu/input/wiiu_hid.h index 1c2ede6f73..b1ce59a6c3 100644 --- a/wiiu/input/wiiu_hid.h +++ b/wiiu/input/wiiu_hid.h @@ -18,6 +18,7 @@ #define __WIIU_HID__H #include +#include "../../input/include/hid_driver.h" #define DEVICE_UNUSED 0 #define DEVICE_USED 1 diff --git a/wiiu/input/wpad_driver.c b/wiiu/input/wpad_driver.c index b707c63cb5..786f883cda 100644 --- a/wiiu/input/wpad_driver.c +++ b/wiiu/input/wpad_driver.c @@ -184,7 +184,7 @@ static void wpad_poll(void) static bool wpad_init(void *data) { - pad_functions.connect(PAD_GAMEPAD, &wpad_driver); + input_pad_connect(PAD_GAMEPAD, &wpad_driver); wpad_poll(); ready = true;