1
0
mirror of https://github.com/libretro/RetroArch synced 2024-07-05 09:48:42 +00:00

WIP: evolve driver implementation

== DETAILS

I've created the concept of a hid_driver_instance_t which is basically
a central place to store the hid pad driver, hid subsystem driver,
the pad list, and the instance data for the above in a central location.

The HID pad device drivers can use it to perform HID operations in a
generic manner.

This is more-or-less a pause point so I can catch up with upstream.

== TESTING

Haven't tested this yet. Compiles without warnings though!
This commit is contained in:
gblues 2018-02-21 22:57:28 -08:00
parent 41ce8853d7
commit 0100d58ffb
27 changed files with 471 additions and 132 deletions

View File

@ -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"
};

View File

@ -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"
};

View File

@ -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
*/
};

View File

@ -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
}

View File

@ -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 */

View File

@ -21,10 +21,7 @@
#include <boolean.h>
#include "joypad_connection.h"
#include "../input_defines.h"
#ifdef WIIU
#include <wiiu/syshid.h>
#endif
#include "../common/hid/hid_device_driver.h"
struct hidpad_ps3_data
{

View File

@ -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
{

View File

@ -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

View File

@ -21,6 +21,7 @@
#include <boolean.h>
#include "joypad_connection.h"
#include "../input_defines.h"
#include "../common/hid/hid_device_driver.h"
struct hidpad_wiiugca_data
{

View File

@ -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
{

View File

@ -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;

View File

@ -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;

View File

@ -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;

View File

@ -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));
}

View File

@ -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;

View File

@ -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 <http://www.gnu.org/licenses/>.
*/
#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__ */

24
input/include/hid_types.h Normal file
View File

@ -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 <http://www.gnu.org/licenses/>.
*/
#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__ */

View File

@ -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.

View File

@ -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

View File

@ -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;
};

View File

@ -1,15 +1,6 @@
#pragma once
#include <wiiu/types.h>
/*
* 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;

View File

@ -15,6 +15,8 @@
*/
#include <wiiu/pad_driver.h>
#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)

View File

@ -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);
}
}

View File

@ -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
};

View File

@ -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,
};

View File

@ -18,6 +18,7 @@
#define __WIIU_HID__H
#include <wiiu/pad_driver.h>
#include "../../input/include/hid_driver.h"
#define DEVICE_UNUSED 0
#define DEVICE_USED 1

View File

@ -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;