mirror of
https://github.com/libretro/RetroArch
synced 2025-01-30 03:32:46 +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:
parent
41ce8853d7
commit
0100d58ffb
@ -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"
|
||||
};
|
||||
|
@ -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"
|
||||
};
|
||||
|
@ -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
|
||||
*/
|
||||
};
|
||||
|
@ -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
|
||||
}
|
||||
|
@ -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 */
|
||||
|
@ -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
|
||||
{
|
||||
|
@ -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
|
||||
{
|
||||
|
@ -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
|
||||
|
@ -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
|
||||
{
|
||||
|
@ -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
|
||||
{
|
||||
|
@ -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;
|
||||
|
@ -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;
|
||||
|
@ -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;
|
||||
|
@ -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));
|
||||
}
|
||||
|
||||
|
@ -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;
|
||||
|
63
input/include/hid_driver.h
Normal file
63
input/include/hid_driver.h
Normal 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
24
input/include/hid_types.h
Normal 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__ */
|
@ -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.
|
||||
|
@ -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
|
||||
|
||||
|
@ -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;
|
||||
};
|
||||
|
@ -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;
|
||||
|
@ -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)
|
||||
|
@ -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);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -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
|
||||
};
|
||||
|
@ -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,
|
||||
};
|
||||
|
||||
|
@ -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
|
||||
|
@ -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;
|
||||
|
||||
|
Loading…
x
Reference in New Issue
Block a user