mirror of
https://github.com/libretro/RetroArch
synced 2025-02-28 12:40:23 +00:00
Start fleshing out wiiu_hid driver
== DETAILS - Added entrypoints into `input/connect/joypad_connection.c` to allow a max value to be passed in, instead of using single macro value - Created a hand-off between the HID attach handler and the worker thread - Created a pad initializer in `wiiu_hid.c` leveraging the new functionality added to `joypad_connection.c` == TESTING Compiles cleanly. At best, doesn't do anything. Might crash--not ready to test quite yet.
This commit is contained in:
parent
e98b006715
commit
5804233ca8
@ -24,13 +24,18 @@
|
||||
#include "joypad_connection.h"
|
||||
|
||||
int pad_connection_find_vacant_pad(joypad_connection_t *joyconn)
|
||||
{
|
||||
return pad_connection_find_vacant_pad_max(joyconn, MAX_USERS);
|
||||
}
|
||||
|
||||
int pad_connection_find_vacant_pad_max(joypad_connection_t *joyconn, unsigned max)
|
||||
{
|
||||
unsigned i;
|
||||
|
||||
if (!joyconn)
|
||||
return -1;
|
||||
|
||||
for (i = 0; i < MAX_USERS; i++)
|
||||
for (i = 0; i < max; i++)
|
||||
{
|
||||
joypad_connection_t *conn = &joyconn[i];
|
||||
|
||||
@ -66,6 +71,16 @@ int32_t pad_connection_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(joyconn);
|
||||
return pad_connection_pad_init_with_slot(joyconn, name,
|
||||
vid, pid, data, ptr, pad);
|
||||
}
|
||||
|
||||
int32_t pad_connection_pad_init_with_slot(joypad_connection_t *joyconn,
|
||||
const char *name, uint16_t vid, uint16_t pid,
|
||||
void *data, send_control_t ptr, int slot)
|
||||
{
|
||||
|
||||
static const struct
|
||||
{
|
||||
const char* name;
|
||||
@ -88,12 +103,11 @@ int32_t pad_connection_pad_init(joypad_connection_t *joyconn,
|
||||
{ 0, 0}
|
||||
};
|
||||
joypad_connection_t *s = NULL;
|
||||
int pad = pad_connection_find_vacant_pad(joyconn);
|
||||
|
||||
if (pad == -1)
|
||||
if (slot == -1)
|
||||
return -1;
|
||||
|
||||
s = &joyconn[pad];
|
||||
s = &joyconn[slot];
|
||||
|
||||
if (s)
|
||||
{
|
||||
@ -119,7 +133,7 @@ int32_t pad_connection_pad_init(joypad_connection_t *joyconn,
|
||||
if (name_match || (pad_map[i].vid == vid && pad_map[i].pid == pid))
|
||||
{
|
||||
s->iface = pad_map[i].iface;
|
||||
s->data = s->iface->init(data, pad, ptr);
|
||||
s->data = s->iface->init(data, slot, ptr);
|
||||
s->connected = true;
|
||||
#if 0
|
||||
RARCH_LOG("%s found \n", pad_map[i].name);
|
||||
@ -144,7 +158,7 @@ int32_t pad_connection_pad_init(joypad_connection_t *joyconn,
|
||||
}
|
||||
}
|
||||
|
||||
return pad;
|
||||
return slot;
|
||||
}
|
||||
|
||||
void pad_connection_pad_deinit(joypad_connection_t *joyconn, uint32_t pad)
|
||||
|
@ -59,6 +59,9 @@ extern pad_connection_interface_t pad_connection_psxadapter;
|
||||
int32_t pad_connection_pad_init(joypad_connection_t *joyconn,
|
||||
const char* name, uint16_t vid, uint16_t pid,
|
||||
void *data, send_control_t ptr);
|
||||
int32_t pad_connection_pad_init_with_slot(joypad_connection_t *joyconn,
|
||||
const char* name, uint16_t vid, uint16_t pid,
|
||||
void *data, send_control_t ptr, int slot);
|
||||
|
||||
joypad_connection_t *pad_connection_init(unsigned pads);
|
||||
|
||||
@ -83,6 +86,7 @@ bool pad_connection_has_interface(joypad_connection_t *joyconn,
|
||||
unsigned idx);
|
||||
|
||||
int pad_connection_find_vacant_pad(joypad_connection_t *joyconn);
|
||||
int pad_connection_find_vacant_pad_max(joypad_connection_t *joyconn, unsigned max);
|
||||
|
||||
bool pad_connection_rumble(joypad_connection_t *s,
|
||||
unsigned pad, enum retro_rumble_effect effect, uint16_t strength);
|
||||
|
@ -20,32 +20,9 @@
|
||||
#include <wiiu/os.h>
|
||||
#include <wiiu/syshid.h>
|
||||
|
||||
#include "../input_defines.h"
|
||||
#include "../input_driver.h"
|
||||
#include "../../verbosity.h"
|
||||
#include "wiiu_hid.h"
|
||||
|
||||
#define DEVICE_UNUSED 0
|
||||
#define DEVICE_USED 1
|
||||
|
||||
typedef struct wiiu_hid
|
||||
{
|
||||
HIDClient *client;
|
||||
OSThread *polling_thread;
|
||||
void *polling_thread_stack;
|
||||
volatile bool polling_thread_quit;
|
||||
} wiiu_hid_t;
|
||||
|
||||
void *alloc_zeroed(size_t alignment, size_t size);
|
||||
static OSThread *new_thread(void);
|
||||
static wiiu_hid_t *new_hid(void);
|
||||
static void delete_hid(wiiu_hid_t *hid);
|
||||
static void delete_hidclient(HIDClient *client);
|
||||
static HIDClient *new_hidclient(void);
|
||||
|
||||
static void start_polling_thread(wiiu_hid_t *hid);
|
||||
static void stop_polling_thread(wiiu_hid_t *hid);
|
||||
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 wiiu_event_list events;
|
||||
|
||||
static bool wiiu_hid_joypad_query(void *data, unsigned pad)
|
||||
{
|
||||
@ -100,16 +77,17 @@ static int16_t wiiu_hid_joypad_axis(void *data, unsigned port, uint32_t joyaxis)
|
||||
static void *wiiu_hid_init(void)
|
||||
{
|
||||
RARCH_LOG("[hid]: wiiu_hid: init\n");
|
||||
// HIDSetup();
|
||||
wiiu_hid_t *hid = new_hid();
|
||||
HIDClient *client = new_hidclient();
|
||||
if(!hid || !client) {
|
||||
joypad_connection_t *connections = pad_connection_init(MAX_HID_PADS);
|
||||
|
||||
if(!hid || !client || !connections) {
|
||||
goto error;
|
||||
}
|
||||
|
||||
RARCH_LOG("[hid]: hid: 0x%x\n", hid);
|
||||
RARCH_LOG("[hid]: client: 0x%x\n", client);
|
||||
hid->connections = connections;
|
||||
|
||||
wiiu_hid_init_event_list();
|
||||
start_polling_thread(hid);
|
||||
if(!hid->polling_thread)
|
||||
goto error;
|
||||
@ -118,11 +96,13 @@ static void *wiiu_hid_init(void)
|
||||
HIDAddClient(client, wiiu_attach_callback);
|
||||
hid->client = client;
|
||||
|
||||
RARCH_LOG("[hid]: init success");
|
||||
RARCH_LOG("[hid]: init success\n");
|
||||
return hid;
|
||||
|
||||
error:
|
||||
RARCH_LOG("[hid]: initialization failed. cleaning up.\n");
|
||||
if(connections)
|
||||
free(connections);
|
||||
stop_polling_thread(hid);
|
||||
delete_hid(hid);
|
||||
delete_hidclient(client);
|
||||
@ -137,8 +117,15 @@ static void wiiu_hid_free(void *data)
|
||||
stop_polling_thread(hid);
|
||||
delete_hidclient(hid->client);
|
||||
delete_hid(hid);
|
||||
if(events.list) {
|
||||
wiiu_attach_event *event;
|
||||
while( (event = events.list) != NULL) {
|
||||
events.list = event->next;
|
||||
delete_attach_event(event);
|
||||
}
|
||||
memset(&events, 0, sizeof(events));
|
||||
}
|
||||
}
|
||||
//HIDTeardown();
|
||||
}
|
||||
|
||||
static void wiiu_hid_poll(void *data)
|
||||
@ -146,6 +133,15 @@ static void wiiu_hid_poll(void *data)
|
||||
(void)data;
|
||||
}
|
||||
|
||||
static void wiiu_hid_device_send_control(void *data,
|
||||
uint8_t *buffer,
|
||||
size_t buffer_size) {
|
||||
struct wiiu_adapter *adapter = (struct wiiu_adapter *)data;
|
||||
|
||||
if(!adapter)
|
||||
return;
|
||||
}
|
||||
|
||||
static void start_polling_thread(wiiu_hid_t *hid) {
|
||||
RARCH_LOG("[hid]: starting polling thread.\n");
|
||||
OSThreadAttributes attributes = OS_THREAD_ATTRIB_AFFINITY_CPU2;
|
||||
@ -203,7 +199,7 @@ static void stop_polling_thread(wiiu_hid_t *hid) {
|
||||
hid->polling_thread_stack = NULL;
|
||||
}
|
||||
|
||||
void log_device(HIDDevice *device) {
|
||||
static void log_device(HIDDevice *device) {
|
||||
if(!device) {
|
||||
RARCH_LOG("NULL device.\n");
|
||||
}
|
||||
@ -219,27 +215,113 @@ void log_device(HIDDevice *device) {
|
||||
RARCH_LOG(" max_packet_size_tx: %d\n", device->max_packet_size_tx);
|
||||
}
|
||||
|
||||
static void synchronized_add_event(wiiu_attach_event *event) {
|
||||
OSFastMutex_Lock(&(events.lock));
|
||||
event->next = events.list;
|
||||
events.list = event;
|
||||
OSFastMutex_Unlock(&(events.lock));
|
||||
}
|
||||
|
||||
static wiiu_attach_event *synchronized_get_events_list(void) {
|
||||
wiiu_attach_event *list;
|
||||
OSFastMutex_Lock(&(events.lock));
|
||||
list = events.list;
|
||||
events.list = NULL;
|
||||
OSFastMutex_Unlock(&(events.lock));
|
||||
|
||||
return list;
|
||||
}
|
||||
|
||||
static void synchronized_add_to_adapters_list(struct wiiu_adapter *adapter) {
|
||||
}
|
||||
|
||||
static int32_t wiiu_attach_callback(HIDClient *client, HIDDevice *device, uint32_t attach) {
|
||||
wiiu_attach_event *event;
|
||||
log_device(device);
|
||||
switch(attach) {
|
||||
case HID_DEVICE_ATTACH:
|
||||
RARCH_LOG("USB device attach event\n");
|
||||
break;
|
||||
case HID_DEVICE_DETACH:
|
||||
RARCH_LOG("USB device detach event\n");
|
||||
break;
|
||||
event = new_attach_event(device);
|
||||
if(!event)
|
||||
goto error;
|
||||
|
||||
event->type = attach;
|
||||
synchronized_add_event(event);
|
||||
return DEVICE_USED;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
log_device(device);
|
||||
|
||||
error:
|
||||
delete_attach_event(event);
|
||||
return DEVICE_UNUSED;
|
||||
}
|
||||
|
||||
|
||||
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_attach(wiiu_hid_t *hid, wiiu_attach_event *event) {
|
||||
struct wiiu_adapter *adapter = new_adapter();
|
||||
|
||||
if(!adapter) {
|
||||
RARCH_ERR("[hid]: Failed to allocate adapter.\n");
|
||||
goto error;
|
||||
}
|
||||
|
||||
adapter->hid = hid;
|
||||
adapter->handle = event->handle;
|
||||
adapter->slot = wiiu_hid_pad_init(hid->connections,
|
||||
"hid", event->vendor_id, event->product_id, adapter,
|
||||
&wiiu_hid_device_send_control);
|
||||
|
||||
if(adapter->slot < 0) {
|
||||
RARCH_ERR("[hid]: No available slots.\n");
|
||||
goto error;
|
||||
}
|
||||
|
||||
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;
|
||||
}
|
||||
|
||||
synchronized_add_to_adapters_list(adapter);
|
||||
return;
|
||||
|
||||
error:
|
||||
delete_adapter(adapter);
|
||||
}
|
||||
|
||||
static void wiiu_handle_attach_events(wiiu_hid_t *hid, wiiu_attach_event *list) {
|
||||
wiiu_attach_event *event;
|
||||
if(!hid || !list)
|
||||
return;
|
||||
|
||||
for(event = list; event != NULL; event = event->next) {
|
||||
if(event->type == HID_DEVICE_ATTACH) {
|
||||
wiiu_hid_attach(hid, event);
|
||||
} else {
|
||||
wiiu_hid_detach(hid, event);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static int wiiu_hid_polling_thread(int argc, const char **argv) {
|
||||
wiiu_hid_t *hid = (wiiu_hid_t *)argv;
|
||||
int i = 0;
|
||||
RARCH_LOG("[hid]: polling thread is starting\n");
|
||||
while(!hid->polling_thread_quit) {
|
||||
wiiu_handle_attach_events(hid, synchronized_get_events_list());
|
||||
usleep(10000);
|
||||
i += 10000;
|
||||
if(i >= (1000 * 1000 * 3)) {
|
||||
@ -259,6 +341,12 @@ static OSThread *new_thread(void) {
|
||||
return t;
|
||||
}
|
||||
|
||||
static void wiiu_hid_init_event_list(void) {
|
||||
RARCH_LOG("[hid]: Initializing events list\n");
|
||||
memset(&events, 0, sizeof(events));
|
||||
OSFastMutex_Init(&(events.lock), "attach_events");
|
||||
}
|
||||
|
||||
static wiiu_hid_t *new_hid(void) {
|
||||
RARCH_LOG("[hid]: new_hid()\n");
|
||||
return alloc_zeroed(4, sizeof(wiiu_hid_t));
|
||||
@ -281,6 +369,42 @@ static void delete_hidclient(HIDClient *client) {
|
||||
free(client);
|
||||
}
|
||||
|
||||
static struct wiiu_adapter *new_adapter(void) {
|
||||
RARCH_LOG("[hid]: new_adapter()\n");
|
||||
return alloc_zeroed(4, sizeof(struct wiiu_adapter));
|
||||
}
|
||||
|
||||
static void delete_adapter(struct wiiu_adapter *adapter) {
|
||||
RARCH_LOG("[hid]: delete_adapter()\n");
|
||||
if(adapter)
|
||||
free(adapter);
|
||||
}
|
||||
|
||||
static wiiu_attach_event *new_attach_event(HIDDevice *device) {
|
||||
if(!device)
|
||||
return NULL;
|
||||
|
||||
wiiu_attach_event *event = alloc_zeroed(4, sizeof(wiiu_attach_event));
|
||||
if(!event)
|
||||
return NULL;
|
||||
event->handle = device->handle;
|
||||
event->vendor_id = device->vid;
|
||||
event->product_id = device->vid;
|
||||
event->interface_index = device->interface_index;
|
||||
event->is_keyboard = (device->sub_class == 1 && device->protocol == 1);
|
||||
event->is_mouse = (device->sub_class == 1 && device->protocol == 2);
|
||||
event->max_packet_size_rx = device->max_packet_size_rx;
|
||||
event->max_packet_size_tx = device->max_packet_size_tx;
|
||||
|
||||
return event;
|
||||
}
|
||||
|
||||
static void delete_attach_event(wiiu_attach_event *event) {
|
||||
if(event)
|
||||
free(event);
|
||||
}
|
||||
|
||||
|
||||
void *alloc_zeroed(size_t alignment, size_t size) {
|
||||
void *result = memalign(alignment, size);
|
||||
if(result) {
|
||||
|
92
input/drivers_hid/wiiu_hid.h
Normal file
92
input/drivers_hid/wiiu_hid.h
Normal file
@ -0,0 +1,92 @@
|
||||
/* RetroArch - A frontend for libretro.
|
||||
* Copyright (C) 2013-2014 - Jason Fetters
|
||||
* Copyright (C) 2011-2017 - Daniel De Matteis
|
||||
*
|
||||
* 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 __WIIU_HID__H
|
||||
#define __WIIU_HID__H
|
||||
#include "../connect/joypad_connection.h"
|
||||
#include "../input_defines.h"
|
||||
#include "../input_driver.h"
|
||||
#include "../../verbosity.h"
|
||||
|
||||
#define DEVICE_UNUSED 0
|
||||
#define DEVICE_USED 1
|
||||
|
||||
#define MAX_HID_PADS 5
|
||||
|
||||
typedef struct wiiu_hid
|
||||
{
|
||||
HIDClient *client;
|
||||
joypad_connection_t *connections;
|
||||
OSThread *polling_thread;
|
||||
void *polling_thread_stack;
|
||||
volatile bool polling_thread_quit;
|
||||
} wiiu_hid_t;
|
||||
|
||||
struct wiiu_adapter {
|
||||
wiiu_hid_t *hid;
|
||||
int32_t slot;
|
||||
uint32_t handle;
|
||||
};
|
||||
|
||||
typedef struct wiiu_attach wiiu_attach_event;
|
||||
|
||||
struct wiiu_attach {
|
||||
wiiu_attach_event *next;
|
||||
uint32_t type;
|
||||
uint32_t handle;
|
||||
uint16_t vendor_id;
|
||||
uint16_t product_id;
|
||||
uint8_t interface_index;
|
||||
uint8_t is_keyboard;
|
||||
uint8_t is_mouse;
|
||||
uint16_t max_packet_size_rx;
|
||||
uint16_t max_packet_size_tx;
|
||||
};
|
||||
|
||||
typedef struct _wiiu_event_list wiiu_event_list;
|
||||
|
||||
struct _wiiu_event_list {
|
||||
OSFastMutex lock;
|
||||
wiiu_attach_event *list;
|
||||
};
|
||||
|
||||
static void *alloc_zeroed(size_t alignment, size_t size);
|
||||
static OSThread *new_thread(void);
|
||||
static wiiu_hid_t *new_hid(void);
|
||||
static void delete_hid(wiiu_hid_t *hid);
|
||||
static void delete_hidclient(HIDClient *client);
|
||||
static HIDClient *new_hidclient(void);
|
||||
static struct wiiu_adapter *new_adapter(void);
|
||||
static void delete_adapter(struct wiiu_adapter *adapter);
|
||||
static wiiu_attach_event *new_attach_event(HIDDevice *device);
|
||||
static void delete_attach_event(wiiu_attach_event *);
|
||||
|
||||
static void wiiu_hid_init_event_list(void);
|
||||
static void start_polling_thread(wiiu_hid_t *hid);
|
||||
static void stop_polling_thread(wiiu_hid_t *hid);
|
||||
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 wiiu_attach_event *synchronized_get_events_list(void);
|
||||
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_detach(wiiu_hid_t *hid, wiiu_attach_event *event);
|
||||
static void synchronized_add_to_adapters_list(struct wiiu_adapter *adapter);
|
||||
static void synchronized_add_event(wiiu_attach_event *event);
|
||||
|
||||
#endif // __WIIU_HID__H
|
Loading…
x
Reference in New Issue
Block a user