mirror of
https://github.com/libretro/RetroArch.git
synced 2024-11-23 07:59:42 +00:00
(Subsystem) Cleanups
This commit is contained in:
parent
0c1c345541
commit
6728d5a2fa
@ -976,6 +976,7 @@ static void btpad_queue_reset(void)
|
||||
can_run = 1;
|
||||
}
|
||||
|
||||
#if 0
|
||||
static void btpad_queue_btstack_set_power_mode(
|
||||
struct btpad_queue_command *cmd, uint8_t on)
|
||||
{
|
||||
@ -988,6 +989,7 @@ static void btpad_queue_btstack_set_power_mode(
|
||||
btpad_increment_position(&insert_position);
|
||||
btpad_queue_process();
|
||||
}
|
||||
#endif
|
||||
|
||||
static void btpad_set_inquiry_state(bool on)
|
||||
{
|
||||
|
@ -75,7 +75,7 @@ enum IOHIDReportType translate_hid_report_type(
|
||||
}
|
||||
}
|
||||
|
||||
CFComparisonResult iohidmanager_sort_elements(const void *val1, const void *val2, void *context)
|
||||
static CFComparisonResult iohidmanager_sort_elements(const void *val1, const void *val2, void *context)
|
||||
{
|
||||
uint32_t page1 = (uint32_t)IOHIDElementGetUsagePage((IOHIDElementRef)val1);
|
||||
uint32_t page2 = (uint32_t)IOHIDElementGetUsagePage((IOHIDElementRef)val2);
|
||||
@ -155,7 +155,7 @@ static void iohidmanager_hid_joypad_get_buttons(void *data,
|
||||
{
|
||||
iohidmanager_hid_t *hid = (iohidmanager_hid_t*)data;
|
||||
if (hid)
|
||||
return pad_connection_get_buttons(&hid->slots[port], port, state);
|
||||
pad_connection_get_buttons(&hid->slots[port], port, state);
|
||||
else
|
||||
BIT256_CLEAR_ALL_PTR(state);
|
||||
}
|
||||
@ -163,42 +163,40 @@ static void iohidmanager_hid_joypad_get_buttons(void *data,
|
||||
static int16_t iohidmanager_hid_joypad_button(void *data,
|
||||
unsigned port, uint16_t joykey)
|
||||
{
|
||||
unsigned hat_dir;
|
||||
input_bits_t buttons;
|
||||
iohidmanager_hid_t *hid = (iohidmanager_hid_t*)data;
|
||||
|
||||
if (port >= DEFAULT_MAX_PADS)
|
||||
return 0;
|
||||
|
||||
iohidmanager_hid_joypad_get_buttons(data, port, &buttons);
|
||||
|
||||
hat_dir = GET_HAT_DIR(joykey);
|
||||
|
||||
/* Check hat. */
|
||||
if (hat_dir)
|
||||
if (port < DEFAULT_MAX_PADS)
|
||||
{
|
||||
unsigned h = GET_HAT(joykey);
|
||||
if (h >= 1)
|
||||
return 0;
|
||||
unsigned hat_dir;
|
||||
input_bits_t buttons;
|
||||
iohidmanager_hid_joypad_get_buttons(data, port, &buttons);
|
||||
|
||||
switch (hat_dir)
|
||||
/* Check hat. */
|
||||
if ((hat_dir = GET_HAT_DIR(joykey)))
|
||||
{
|
||||
case HAT_LEFT_MASK:
|
||||
return (hid->hats[port][0] < 0);
|
||||
case HAT_RIGHT_MASK:
|
||||
return (hid->hats[port][0] > 0);
|
||||
case HAT_UP_MASK:
|
||||
return (hid->hats[port][1] < 0);
|
||||
case HAT_DOWN_MASK:
|
||||
return (hid->hats[port][1] > 0);
|
||||
default:
|
||||
break;
|
||||
unsigned h = GET_HAT(joykey);
|
||||
if (h >= 1)
|
||||
return 0;
|
||||
|
||||
switch (hat_dir)
|
||||
{
|
||||
case HAT_LEFT_MASK:
|
||||
return (hid->hats[port][0] < 0);
|
||||
case HAT_RIGHT_MASK:
|
||||
return (hid->hats[port][0] > 0);
|
||||
case HAT_UP_MASK:
|
||||
return (hid->hats[port][1] < 0);
|
||||
case HAT_DOWN_MASK:
|
||||
return (hid->hats[port][1] > 0);
|
||||
default:
|
||||
break;
|
||||
}
|
||||
/* hat requested and no hat button down */
|
||||
}
|
||||
/* hat requested and no hat button down */
|
||||
else if (joykey < 32)
|
||||
return ((BIT256_GET(buttons, joykey) != 0)
|
||||
|| ((hid->buttons[port] & (1 << joykey)) != 0));
|
||||
}
|
||||
else if (joykey < 32)
|
||||
return ((BIT256_GET(buttons, joykey) != 0)
|
||||
|| ((hid->buttons[port] & (1 << joykey)) != 0));
|
||||
return 0;
|
||||
}
|
||||
|
||||
@ -300,6 +298,7 @@ static void iohidmanager_hid_device_report(void *data,
|
||||
static void iohidmanager_hid_device_input_callback(void *data, IOReturn result,
|
||||
void* sender, IOHIDValueRef value)
|
||||
{
|
||||
int pushed_button = 0;
|
||||
iohidmanager_hid_t *hid = (iohidmanager_hid_t*)hid_driver_get_data();
|
||||
struct iohidmanager_hid_adapter *adapter = (struct iohidmanager_hid_adapter*)data;
|
||||
IOHIDElementRef element = IOHIDValueGetElement(value);
|
||||
@ -317,8 +316,6 @@ static void iohidmanager_hid_device_input_callback(void *data, IOReturn result,
|
||||
/* Joystick handler.
|
||||
* TODO: Can GamePad work the same? */
|
||||
|
||||
int pushed_button = 0;
|
||||
|
||||
switch (page)
|
||||
{
|
||||
case kHIDPage_GenericDesktop:
|
||||
@ -376,12 +373,12 @@ static void iohidmanager_hid_device_input_callback(void *data, IOReturn result,
|
||||
case 5:
|
||||
/* pos = down+left */
|
||||
hid->hats[adapter->slot][0] = -1;
|
||||
hid->hats[adapter->slot][1] = 1;
|
||||
hid->hats[adapter->slot][1] = 1;
|
||||
break;
|
||||
case 6:
|
||||
/* pos = left */
|
||||
hid->hats[adapter->slot][0] = -1;
|
||||
hid->hats[adapter->slot][1] = 0;
|
||||
hid->hats[adapter->slot][1] = 0;
|
||||
break;
|
||||
case 7:
|
||||
/* pos = up_left */
|
||||
@ -441,11 +438,8 @@ static void iohidmanager_hid_device_input_callback(void *data, IOReturn result,
|
||||
{
|
||||
default:
|
||||
tmp = adapter->axes;
|
||||
|
||||
while (tmp && tmp->cookie != (IOHIDElementCookie)cookie)
|
||||
{
|
||||
tmp = tmp->next;
|
||||
}
|
||||
if (tmp)
|
||||
{
|
||||
if (tmp->cookie == (IOHIDElementCookie)cookie)
|
||||
@ -493,8 +487,8 @@ static void iohidmanager_hid_device_input_callback(void *data, IOReturn result,
|
||||
|
||||
static void iohidmanager_hid_device_remove(IOHIDDeviceRef device, iohidmanager_hid_t* hid)
|
||||
{
|
||||
int i, slot;
|
||||
struct iohidmanager_hid_adapter *adapter = NULL;
|
||||
int i;
|
||||
|
||||
/*loop though the controller ports and find the device with a matching IOHINDeviceRef*/
|
||||
for (i=0; i<MAX_USERS; i++)
|
||||
@ -510,10 +504,12 @@ static void iohidmanager_hid_device_remove(IOHIDDeviceRef device, iohidmanager_h
|
||||
}
|
||||
if (!adapter)
|
||||
{
|
||||
RARCH_LOG("Error removing device %p\n",device, hid);
|
||||
RARCH_DBG("Error removing device %p\n",device, hid);
|
||||
return;
|
||||
}
|
||||
int slot = adapter->slot;
|
||||
|
||||
slot = adapter->slot;
|
||||
|
||||
if (hid && adapter && (adapter->slot < MAX_USERS))
|
||||
{
|
||||
input_autoconfigure_disconnect(adapter->slot, adapter->name);
|
||||
@ -527,21 +523,21 @@ static void iohidmanager_hid_device_remove(IOHIDDeviceRef device, iohidmanager_h
|
||||
if (adapter)
|
||||
{
|
||||
apple_input_rec_t* tmp = NULL;
|
||||
while (adapter->hats != NULL)
|
||||
while (adapter->hats)
|
||||
{
|
||||
tmp = adapter->hats;
|
||||
adapter->hats = adapter->hats->next;
|
||||
free(tmp);
|
||||
}
|
||||
|
||||
while (adapter->axes != NULL)
|
||||
while (adapter->axes)
|
||||
{
|
||||
tmp = adapter->axes;
|
||||
adapter->axes = adapter->axes->next;
|
||||
free(tmp);
|
||||
}
|
||||
|
||||
while (adapter->buttons != NULL)
|
||||
while (adapter->buttons)
|
||||
{
|
||||
tmp = adapter->buttons;
|
||||
adapter->buttons = adapter->buttons->next;
|
||||
@ -585,8 +581,6 @@ static uint32_t iohidmanager_hid_device_get_location_id(IOHIDDeviceRef device)
|
||||
CFSTR(kIOHIDLocationIDKey));
|
||||
}
|
||||
|
||||
|
||||
|
||||
static void iohidmanager_hid_device_get_product_string(
|
||||
IOHIDDeviceRef device, char *buf, size_t len)
|
||||
{
|
||||
@ -617,62 +611,61 @@ static void iohidmanager_hid_device_add_autodetect(unsigned idx,
|
||||
static void iohidmanager_hid_device_add(IOHIDDeviceRef device, iohidmanager_hid_t* hid)
|
||||
{
|
||||
int i;
|
||||
IOReturn ret;
|
||||
CFRange range;
|
||||
CFMutableArrayRef elements;
|
||||
CFArrayRef elements_raw;
|
||||
uint16_t dev_vid, dev_pid;
|
||||
int count;
|
||||
bool found_axis[11] =
|
||||
{ false, false, false, false, false, false, false, false, false, false, false };
|
||||
apple_input_rec_t *tmp = NULL;
|
||||
apple_input_rec_t *tmp_buttons = NULL;
|
||||
apple_input_rec_t *tmp_axes = NULL;
|
||||
struct iohidmanager_hid_adapter *adapter = NULL;
|
||||
|
||||
static const uint32_t axis_use_ids[11] =
|
||||
{
|
||||
kHIDUsage_GD_X,
|
||||
kHIDUsage_GD_Y,
|
||||
kHIDUsage_GD_Rx,
|
||||
kHIDUsage_GD_Ry,
|
||||
kHIDUsage_GD_Z,
|
||||
kHIDUsage_GD_Rz,
|
||||
kHIDUsage_Sim_Rudder,
|
||||
kHIDUsage_Sim_Throttle,
|
||||
kHIDUsage_Sim_Steering,
|
||||
kHIDUsage_Sim_Accelerator,
|
||||
kHIDUsage_Sim_Brake
|
||||
};
|
||||
static const uint32_t axis_use_ids[11] =
|
||||
{
|
||||
kHIDUsage_GD_X,
|
||||
kHIDUsage_GD_Y,
|
||||
kHIDUsage_GD_Rx,
|
||||
kHIDUsage_GD_Ry,
|
||||
kHIDUsage_GD_Z,
|
||||
kHIDUsage_GD_Rz,
|
||||
kHIDUsage_Sim_Rudder,
|
||||
kHIDUsage_Sim_Throttle,
|
||||
kHIDUsage_Sim_Steering,
|
||||
kHIDUsage_Sim_Accelerator,
|
||||
kHIDUsage_Sim_Brake
|
||||
};
|
||||
|
||||
/* check if pad was already registered previously when the application was
|
||||
started (by deterministic method). if so do not re-add the pad */
|
||||
uint32_t deviceLocationId = iohidmanager_hid_device_get_location_id(device);
|
||||
for (i=0; i<MAX_USERS; i++)
|
||||
started (by deterministic method). if so do not re-add the pad */
|
||||
uint32_t device_location_id = iohidmanager_hid_device_get_location_id(device);
|
||||
|
||||
for (i = 0; i < MAX_USERS; i++)
|
||||
{
|
||||
struct iohidmanager_hid_adapter *a = (struct iohidmanager_hid_adapter*)hid->slots[i].data;
|
||||
if (!a)
|
||||
continue;
|
||||
if (a->locationId == deviceLocationId)
|
||||
if (a->locationId == device_location_id)
|
||||
{
|
||||
a->handle = device;
|
||||
/* while we're not re-adding the controller, we are re-assigning the
|
||||
handle so it can be removed properly upon disconnect */
|
||||
/* While we're not re-adding the controller, we are re-assigning the
|
||||
handle so it can be removed properly upon disconnect */
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
IOReturn ret;
|
||||
uint16_t dev_vid, dev_pid;
|
||||
CFArrayRef elements_raw;
|
||||
int count;
|
||||
CFMutableArrayRef elements;
|
||||
CFRange range;
|
||||
bool found_axis[11] =
|
||||
{ false, false, false, false, false, false, false, false, false, false, false };
|
||||
apple_input_rec_t *tmp = NULL;
|
||||
apple_input_rec_t *tmpButtons = NULL;
|
||||
apple_input_rec_t *tmpAxes = NULL;
|
||||
struct iohidmanager_hid_adapter *adapter = (struct iohidmanager_hid_adapter*)
|
||||
calloc(1, sizeof(*adapter));
|
||||
|
||||
if (!adapter)
|
||||
if (!(adapter = (struct iohidmanager_hid_adapter*)calloc(1, sizeof(*adapter))))
|
||||
return;
|
||||
if (!hid)
|
||||
goto error;
|
||||
|
||||
adapter->handle = device;
|
||||
adapter->handle = device;
|
||||
adapter->locationId = deviceLocationId;
|
||||
|
||||
ret = IOHIDDeviceOpen(device, kIOHIDOptionsTypeNone);
|
||||
ret = IOHIDDeviceOpen(device, kIOHIDOptionsTypeNone);
|
||||
|
||||
if (ret != kIOReturnSuccess)
|
||||
goto error;
|
||||
@ -686,8 +679,8 @@ static void iohidmanager_hid_device_add(IOHIDDeviceRef device, iohidmanager_hid_
|
||||
sizeof(adapter->name));
|
||||
#endif
|
||||
|
||||
dev_vid = iohidmanager_hid_device_get_vendor_id (device);
|
||||
dev_pid = iohidmanager_hid_device_get_product_id (device);
|
||||
dev_vid = iohidmanager_hid_device_get_vendor_id (device);
|
||||
dev_pid = iohidmanager_hid_device_get_product_id (device);
|
||||
|
||||
adapter->slot = pad_connection_pad_init(hid->slots,
|
||||
adapter->name, dev_vid, dev_pid, adapter,
|
||||
@ -698,16 +691,14 @@ static void iohidmanager_hid_device_add(IOHIDDeviceRef device, iohidmanager_hid_
|
||||
|
||||
if (string_is_empty(adapter->name))
|
||||
strcpy(adapter->name, "Unknown Controller With No Name");
|
||||
|
||||
if (pad_connection_has_interface(hid->slots, adapter->slot)) {
|
||||
|
||||
if (pad_connection_has_interface(hid->slots, adapter->slot))
|
||||
IOHIDDeviceRegisterInputReportCallback(device,
|
||||
adapter->data, sizeof(adapter->data),
|
||||
iohidmanager_hid_device_report, adapter);
|
||||
}
|
||||
else {
|
||||
else
|
||||
IOHIDDeviceRegisterInputValueCallback(device,
|
||||
iohidmanager_hid_device_input_callback, adapter);
|
||||
}
|
||||
|
||||
/* scan for buttons, axis, hats */
|
||||
elements_raw = IOHIDDeviceCopyMatchingElements(device, NULL, kIOHIDOptionsTypeNone);
|
||||
@ -763,7 +754,6 @@ static void iohidmanager_hid_device_add(IOHIDDeviceRef device, iohidmanager_hid_
|
||||
|
||||
if (i < 11)
|
||||
{
|
||||
|
||||
apple_input_rec_t *axis = (apple_input_rec_t *)malloc(sizeof(apple_input_rec_t));
|
||||
axis->id = i;
|
||||
axis->cookie = (IOHIDElementCookie)cookie;
|
||||
@ -772,10 +762,10 @@ static void iohidmanager_hid_device_add(IOHIDDeviceRef device, iohidmanager_hid_
|
||||
if (iohidmanager_check_for_id(adapter->axes,i))
|
||||
{
|
||||
/* axis ID already exists, save to tmp for appending later */
|
||||
if (tmpAxes)
|
||||
iohidmanager_append_record(tmpAxes, axis);
|
||||
if (tmp_axes)
|
||||
iohidmanager_append_record(tmp_axes, axis);
|
||||
else
|
||||
tmpAxes = axis;
|
||||
tmp_axes = axis;
|
||||
}
|
||||
else
|
||||
{
|
||||
@ -812,10 +802,10 @@ static void iohidmanager_hid_device_add(IOHIDDeviceRef device, iohidmanager_hid_
|
||||
break;
|
||||
|
||||
case kHIDPage_Simulation:
|
||||
switch (use)
|
||||
{
|
||||
default:
|
||||
{
|
||||
switch (use)
|
||||
{
|
||||
default:
|
||||
{
|
||||
uint32_t i = 0;
|
||||
|
||||
while (i < 11 && axis_use_ids[i] != use)
|
||||
@ -831,10 +821,10 @@ static void iohidmanager_hid_device_add(IOHIDDeviceRef device, iohidmanager_hid_
|
||||
if (iohidmanager_check_for_id(adapter->axes,i))
|
||||
{
|
||||
/* axis ID already exists, save to tmp for appending later */
|
||||
if (tmpAxes)
|
||||
iohidmanager_append_record(tmpAxes, axis);
|
||||
if (tmp_axes)
|
||||
iohidmanager_append_record(tmp_axes, axis);
|
||||
else
|
||||
tmpAxes = axis;
|
||||
tmp_axes = axis;
|
||||
}
|
||||
else
|
||||
{
|
||||
@ -847,10 +837,10 @@ static void iohidmanager_hid_device_add(IOHIDDeviceRef device, iohidmanager_hid_
|
||||
}
|
||||
else
|
||||
detected_button = 1;
|
||||
}
|
||||
break;
|
||||
}
|
||||
break;
|
||||
}
|
||||
break;
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
if (detected_button)
|
||||
@ -862,10 +852,10 @@ static void iohidmanager_hid_device_add(IOHIDDeviceRef device, iohidmanager_hid_
|
||||
|
||||
if (iohidmanager_check_for_id(adapter->buttons,btn->id))
|
||||
{
|
||||
if (tmpButtons)
|
||||
iohidmanager_append_record_ordered(&tmpButtons, btn);
|
||||
if (tmp_buttons)
|
||||
iohidmanager_append_record_ordered(&tmp_buttons, btn);
|
||||
else
|
||||
tmpButtons = btn;
|
||||
tmp_buttons = btn;
|
||||
}
|
||||
else
|
||||
{
|
||||
@ -882,13 +872,13 @@ static void iohidmanager_hid_device_add(IOHIDDeviceRef device, iohidmanager_hid_
|
||||
/* take care of buttons/axes with duplicate 'use' values */
|
||||
for (i = 0; i < 11; i++)
|
||||
{
|
||||
if (!found_axis[i] && tmpAxes)
|
||||
if (!found_axis[i] && tmp_axes)
|
||||
{
|
||||
apple_input_rec_t *next = tmpAxes->next;
|
||||
tmpAxes->id = i;
|
||||
tmpAxes->next = NULL;
|
||||
iohidmanager_append_record(adapter->axes, tmpAxes);
|
||||
tmpAxes = next;
|
||||
apple_input_rec_t *next = tmp_axes->next;
|
||||
tmp_axes->id = i;
|
||||
tmp_axes->next = NULL;
|
||||
iohidmanager_append_record(adapter->axes, tmp_axes);
|
||||
tmp_axes = next;
|
||||
}
|
||||
}
|
||||
|
||||
@ -900,16 +890,16 @@ static void iohidmanager_hid_device_add(IOHIDDeviceRef device, iohidmanager_hid_
|
||||
tmp = tmp->next;
|
||||
}
|
||||
|
||||
while (tmpButtons)
|
||||
while (tmp_buttons)
|
||||
{
|
||||
apple_input_rec_t *next = tmpButtons->next;
|
||||
apple_input_rec_t *next = tmp_buttons->next;
|
||||
|
||||
tmpButtons->id = tmp->id;
|
||||
tmpButtons->next = NULL;
|
||||
tmp->next = tmpButtons;
|
||||
tmp_buttons->id = tmp->id;
|
||||
tmp_buttons->next = NULL;
|
||||
tmp->next = tmp_buttons;
|
||||
|
||||
tmp = tmp->next;
|
||||
tmpButtons = next;
|
||||
tmp_buttons = next;
|
||||
}
|
||||
|
||||
iohidmanager_hid_device_add_autodetect(adapter->slot,
|
||||
@ -919,50 +909,49 @@ static void iohidmanager_hid_device_add(IOHIDDeviceRef device, iohidmanager_hid_
|
||||
error:
|
||||
{
|
||||
apple_input_rec_t *tmp = NULL;
|
||||
while (adapter->hats != NULL)
|
||||
while (adapter->hats)
|
||||
{
|
||||
tmp = adapter->hats;
|
||||
adapter->hats = adapter->hats->next;
|
||||
free(tmp);
|
||||
}
|
||||
while (adapter->axes != NULL)
|
||||
while (adapter->axes)
|
||||
{
|
||||
tmp = adapter->axes;
|
||||
adapter->axes = adapter->axes->next;
|
||||
free(tmp);
|
||||
}
|
||||
while (adapter->buttons != NULL)
|
||||
while (adapter->buttons)
|
||||
{
|
||||
tmp = adapter->buttons;
|
||||
adapter->buttons = adapter->buttons->next;
|
||||
free(tmp);
|
||||
}
|
||||
while (tmpAxes != NULL)
|
||||
while (tmp_axes)
|
||||
{
|
||||
tmp = tmpAxes;
|
||||
tmpAxes = tmpAxes->next;
|
||||
tmp = tmp_axes;
|
||||
tmp_axes = tmp_axes->next;
|
||||
free(tmp);
|
||||
}
|
||||
while (tmpButtons != NULL)
|
||||
while (tmp_buttons)
|
||||
{
|
||||
tmp = tmpButtons;
|
||||
tmpButtons = tmpButtons->next;
|
||||
tmp = tmp_buttons;
|
||||
tmp_buttons = tmp_buttons->next;
|
||||
free(tmp);
|
||||
}
|
||||
free(adapter);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
static void iohidmanager_hid_device_matched(void *data, IOReturn result,
|
||||
void* sender, IOHIDDeviceRef device)
|
||||
void* sender, IOHIDDeviceRef device)
|
||||
{
|
||||
iohidmanager_hid_t *hid = (iohidmanager_hid_t*) hid_driver_get_data();
|
||||
|
||||
iohidmanager_hid_device_add(device, hid);
|
||||
}
|
||||
|
||||
static void iohidmanager_hid_device_removed(void *data, IOReturn result,
|
||||
void* sender, IOHIDDeviceRef device)
|
||||
void* sender, IOHIDDeviceRef device)
|
||||
{
|
||||
iohidmanager_hid_t *hid = (iohidmanager_hid_t*) hid_driver_get_data();
|
||||
iohidmanager_hid_device_remove(device, hid);
|
||||
@ -993,16 +982,14 @@ static int iohidmanager_hid_manager_init(iohidmanager_hid_t *hid)
|
||||
{
|
||||
if (!hid)
|
||||
return -1;
|
||||
if (hid->ptr) /* already initialized. */
|
||||
return 0;
|
||||
|
||||
hid->ptr = IOHIDManagerCreate(kCFAllocatorDefault, kIOHIDOptionsTypeNone);
|
||||
|
||||
if (!hid->ptr)
|
||||
return -1;
|
||||
IOHIDManagerSetDeviceMatching(hid->ptr, NULL);
|
||||
IOHIDManagerScheduleWithRunLoop(hid->ptr, CFRunLoopGetCurrent(),
|
||||
kCFRunLoopDefaultMode);
|
||||
if (!hid->ptr) /* Already initialized? */
|
||||
{
|
||||
if (!(hid->ptr = IOHIDManagerCreate(kCFAllocatorDefault, kIOHIDOptionsTypeNone)))
|
||||
return -1;
|
||||
IOHIDManagerSetDeviceMatching(hid->ptr, NULL);
|
||||
IOHIDManagerScheduleWithRunLoop(hid->ptr, CFRunLoopGetCurrent(),
|
||||
kCFRunLoopDefaultMode);
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
@ -1048,7 +1035,6 @@ static int iohidmanager_hid_manager_set_device_matching(
|
||||
|
||||
CFRelease(matcher);
|
||||
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
@ -1060,9 +1046,7 @@ static void *iohidmanager_hid_init(void)
|
||||
if (!hid_apple)
|
||||
return NULL;
|
||||
|
||||
hid_apple->slots = pad_connection_init(MAX_USERS);
|
||||
|
||||
if (!hid_apple->slots)
|
||||
if (!(hid_apple->slots = pad_connection_init(MAX_USERS)))
|
||||
goto error;
|
||||
if (iohidmanager_hid_manager_init(hid_apple) == -1)
|
||||
goto error;
|
||||
@ -1094,23 +1078,21 @@ static void iohidmanager_hid_free(const void *data)
|
||||
free(hid_apple);
|
||||
}
|
||||
|
||||
static void iohidmanager_hid_poll(void *data)
|
||||
{
|
||||
(void)data;
|
||||
}
|
||||
static void iohidmanager_hid_poll(void *data) { }
|
||||
|
||||
static int32_t iohidmanager_set_report(void *handle, uint8_t report_type, uint8_t report_id, uint8_t *data_buf, size_t size)
|
||||
{
|
||||
struct iohidmanager_hid_adapter *adapter =
|
||||
(struct iohidmanager_hid_adapter*)handle;
|
||||
|
||||
if (adapter)
|
||||
return IOHIDDeviceSetReport(adapter->handle, translate_hid_report_type(report_type), report_id, data_buf + 1, size - 1);
|
||||
|
||||
return IOHIDDeviceSetReport(adapter->handle,
|
||||
translate_hid_report_type(report_type), report_id,
|
||||
data_buf + 1, size - 1);
|
||||
return -1;
|
||||
}
|
||||
|
||||
static int32_t iohidmanager_get_report(void *handle, uint8_t report_type, uint8_t report_id, uint8_t *data_buf, size_t size)
|
||||
static int32_t iohidmanager_get_report(void *handle, uint8_t report_type, uint8_t report_id,
|
||||
uint8_t *data_buf, size_t size)
|
||||
{
|
||||
struct iohidmanager_hid_adapter *adapter =
|
||||
(struct iohidmanager_hid_adapter*)handle;
|
||||
|
@ -36,23 +36,20 @@ static bool wiiu_hid_joypad_query(void *data, unsigned slot)
|
||||
return slot < joypad_state.max_slot;
|
||||
}
|
||||
|
||||
static joypad_connection_t *get_pad(wiiu_hid_t *hid, unsigned slot)
|
||||
static joypad_connection_t *wiiu_hid_get_pad(wiiu_hid_t *hid, unsigned slot)
|
||||
{
|
||||
joypad_connection_t *result;
|
||||
if (!wiiu_hid_joypad_query(hid, slot)) {
|
||||
RARCH_LOG("wiiu_hid: get_pad: invalid slot: %d", slot);
|
||||
if (!wiiu_hid_joypad_query(hid, slot))
|
||||
return NULL;
|
||||
}
|
||||
result = &joypad_state.pads[slot];
|
||||
if (!result->connected || !result->iface || !result->connection) {
|
||||
if (!result->connected || !result->iface || !result->connection)
|
||||
return NULL;
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
static const char *wiiu_hid_joypad_name(void *data, unsigned slot)
|
||||
{
|
||||
joypad_connection_t *pad = get_pad((wiiu_hid_t *)data, slot);
|
||||
joypad_connection_t *pad = wiiu_hid_get_pad((wiiu_hid_t *)data, slot);
|
||||
|
||||
if (!pad || !pad->iface->get_name)
|
||||
return NULL;
|
||||
@ -62,7 +59,7 @@ static const char *wiiu_hid_joypad_name(void *data, unsigned slot)
|
||||
|
||||
static void wiiu_hid_joypad_get_buttons(void *data, unsigned slot, input_bits_t *state)
|
||||
{
|
||||
joypad_connection_t *pad = get_pad((wiiu_hid_t *)data, slot);
|
||||
joypad_connection_t *pad = wiiu_hid_get_pad((wiiu_hid_t *)data, slot);
|
||||
|
||||
if (pad && pad->iface->get_buttons)
|
||||
pad->iface->get_buttons(pad->connection, state);
|
||||
@ -71,7 +68,7 @@ static void wiiu_hid_joypad_get_buttons(void *data, unsigned slot, input_bits_t
|
||||
static int16_t wiiu_hid_joypad_button(void *data,
|
||||
unsigned slot, uint16_t joykey)
|
||||
{
|
||||
joypad_connection_t *pad = get_pad((wiiu_hid_t *)data, slot);
|
||||
joypad_connection_t *pad = wiiu_hid_get_pad((wiiu_hid_t *)data, slot);
|
||||
if (!pad || !pad->iface->button)
|
||||
return 0;
|
||||
return pad->iface->button(pad->connection, joykey);
|
||||
@ -79,24 +76,24 @@ static int16_t wiiu_hid_joypad_button(void *data,
|
||||
|
||||
static int16_t wiiu_hid_joypad_axis(void *data, unsigned slot, uint32_t joyaxis)
|
||||
{
|
||||
joypad_connection_t *pad = get_pad((wiiu_hid_t *)data, slot);
|
||||
joypad_connection_t *pad = wiiu_hid_get_pad((wiiu_hid_t *)data, slot);
|
||||
|
||||
if (!pad)
|
||||
return 0;
|
||||
|
||||
if (AXIS_NEG_GET(joyaxis) < 4)
|
||||
if (pad)
|
||||
{
|
||||
int16_t val = pad->iface->get_axis(pad->connection, AXIS_NEG_GET(joyaxis));
|
||||
if (AXIS_NEG_GET(joyaxis) < 4)
|
||||
{
|
||||
int16_t val = pad->iface->get_axis(pad->connection, AXIS_NEG_GET(joyaxis));
|
||||
|
||||
if (val < 0)
|
||||
return val;
|
||||
}
|
||||
else if (AXIS_POS_GET(joyaxis) < 4)
|
||||
{
|
||||
int16_t val = pad->iface->get_axis(pad->connection, AXIS_POS_GET(joyaxis));
|
||||
if (val < 0)
|
||||
return val;
|
||||
}
|
||||
else if (AXIS_POS_GET(joyaxis) < 4)
|
||||
{
|
||||
int16_t val = pad->iface->get_axis(pad->connection, AXIS_POS_GET(joyaxis));
|
||||
|
||||
if (val > 0)
|
||||
return val;
|
||||
if (val > 0)
|
||||
return val;
|
||||
}
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
@ -112,7 +109,7 @@ static int16_t wiiu_hid_joypad_state(
|
||||
const struct retro_keybind *binds = (const struct retro_keybind*)
|
||||
binds_data;
|
||||
uint16_t port_idx = joypad_info->joy_idx;
|
||||
joypad_connection_t *pad = get_pad((wiiu_hid_t *)data, port_idx);
|
||||
joypad_connection_t *pad = wiiu_hid_get_pad((wiiu_hid_t *)data, port_idx);
|
||||
if (!pad)
|
||||
return 0;
|
||||
|
||||
@ -139,7 +136,7 @@ static int16_t wiiu_hid_joypad_state(
|
||||
static bool wiiu_hid_joypad_rumble(void *data, unsigned slot,
|
||||
enum retro_rumble_effect effect, uint16_t strength)
|
||||
{
|
||||
joypad_connection_t *pad = get_pad((wiiu_hid_t *)data, slot);
|
||||
joypad_connection_t *pad = wiiu_hid_get_pad((wiiu_hid_t *)data, slot);
|
||||
|
||||
if (!pad || !pad->iface->set_rumble)
|
||||
return false;
|
||||
@ -148,11 +145,237 @@ static bool wiiu_hid_joypad_rumble(void *data, unsigned slot,
|
||||
return false;
|
||||
}
|
||||
|
||||
static void *alloc_zeroed(size_t alignment, size_t size)
|
||||
{
|
||||
void *result = memalign(alignment, size);
|
||||
if (result)
|
||||
memset(result, 0, size);
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
static void wiiu_hid_init_lists(void)
|
||||
{
|
||||
memset(&events, 0, sizeof(events));
|
||||
OSFastMutex_Init(&(events.lock), "attach_events");
|
||||
memset(&adapters, 0, sizeof(adapters));
|
||||
OSFastMutex_Init(&(adapters.lock), "adapters");
|
||||
}
|
||||
|
||||
static void delete_adapter(wiiu_adapter_t *adapter)
|
||||
{
|
||||
if (!adapter)
|
||||
return;
|
||||
|
||||
if (adapter->rx_buffer)
|
||||
{
|
||||
free(adapter->rx_buffer);
|
||||
adapter->rx_buffer = NULL;
|
||||
}
|
||||
if (adapter->tx_buffer)
|
||||
{
|
||||
free(adapter->tx_buffer);
|
||||
adapter->tx_buffer = NULL;
|
||||
}
|
||||
|
||||
if (adapter->pad_driver && adapter->pad_driver_data)
|
||||
{
|
||||
adapter->pad_driver->deinit(adapter->pad_driver_data);
|
||||
adapter->pad_driver_data = NULL;
|
||||
}
|
||||
|
||||
free(adapter);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Block until all the HIDRead() calls have returned.
|
||||
*/
|
||||
static void wiiu_hid_polling_thread_cleanup(OSThread *thread, void *stack)
|
||||
{
|
||||
int incomplete = 0;
|
||||
int retries = 0;
|
||||
wiiu_adapter_t *adapter = NULL;
|
||||
|
||||
RARCH_LOG("Waiting for in-flight reads to finish.\n");
|
||||
|
||||
/* We don't need to protect the adapter list here because nothing else
|
||||
will access it during this method (the HID system is shut down, and
|
||||
the only other access is the polling thread that just stopped */
|
||||
do
|
||||
{
|
||||
incomplete = 0;
|
||||
for (adapter = adapters.list; adapter != NULL; adapter = adapter->next)
|
||||
{
|
||||
if (adapter->state == ADAPTER_STATE_READING)
|
||||
incomplete++;
|
||||
}
|
||||
|
||||
if (incomplete == 0)
|
||||
{
|
||||
RARCH_LOG("All in-flight reads complete.\n");
|
||||
while (adapters.list)
|
||||
{
|
||||
RARCH_LOG("[hid]: shutting down adapter..\n");
|
||||
adapter = adapters.list;
|
||||
adapters.list = adapter->next;
|
||||
pad_connection_pad_deregister(joypad_state.pads, adapter->pad_driver, adapter->pad_driver_data);
|
||||
delete_adapter(adapter);
|
||||
}
|
||||
}
|
||||
|
||||
if (incomplete)
|
||||
usleep(5000);
|
||||
|
||||
if (++retries >= 1000)
|
||||
{
|
||||
RARCH_WARN("[hid]: timed out waiting for in-flight read to finish.\n");
|
||||
incomplete = 0;
|
||||
}
|
||||
} while (incomplete);
|
||||
}
|
||||
|
||||
static OSThread *new_thread(void)
|
||||
{
|
||||
OSThread *t = alloc_zeroed(8, sizeof(OSThread));
|
||||
|
||||
if (!t)
|
||||
return NULL;
|
||||
|
||||
t->tag = OS_THREAD_TAG;
|
||||
|
||||
return t;
|
||||
}
|
||||
|
||||
static void start_polling_thread(wiiu_hid_t *hid)
|
||||
{
|
||||
OSThreadAttributes attributes = OS_THREAD_ATTRIB_AFFINITY_CPU2;
|
||||
int32_t stack_size = 0x8000;
|
||||
int32_t priority = 10;
|
||||
OSThread *thread = new_thread();
|
||||
void *stack = alloc_zeroed(16, stack_size);
|
||||
|
||||
RARCH_LOG("[hid]: starting polling thread.\n");
|
||||
|
||||
if (!thread || !stack)
|
||||
goto error;
|
||||
|
||||
if (!OSCreateThread(thread,
|
||||
wiiu_hid_polling_thread,
|
||||
1, (char *)hid,
|
||||
stack+stack_size, stack_size,
|
||||
priority,
|
||||
attributes))
|
||||
{
|
||||
RARCH_LOG("[hid]: OSCreateThread failed.\n");
|
||||
goto error;
|
||||
}
|
||||
|
||||
OSSetThreadCleanupCallback(thread, wiiu_hid_polling_thread_cleanup);
|
||||
|
||||
hid->polling_thread = thread;
|
||||
hid->polling_thread_stack = stack;
|
||||
OSResumeThread(thread);
|
||||
return;
|
||||
|
||||
error:
|
||||
if (thread)
|
||||
free(thread);
|
||||
if (stack)
|
||||
free(stack);
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
static void stop_polling_thread(wiiu_hid_t *hid)
|
||||
{
|
||||
int thread_result = 0;
|
||||
|
||||
if (!hid || !hid->polling_thread)
|
||||
return;
|
||||
|
||||
/* Unregister our HID client so we don't get any new events. */
|
||||
if (hid->client)
|
||||
{
|
||||
HIDDelClient(hid->client);
|
||||
hid->client = NULL;
|
||||
}
|
||||
|
||||
/* tell the thread it's time to stop. */
|
||||
hid->polling_thread_quit = true;
|
||||
/* This returns once the thread runs and the cleanup method completes. */
|
||||
OSJoinThread(hid->polling_thread, &thread_result);
|
||||
free(hid->polling_thread);
|
||||
free(hid->polling_thread_stack);
|
||||
hid->polling_thread = NULL;
|
||||
hid->polling_thread_stack = NULL;
|
||||
}
|
||||
|
||||
static void synchronized_add_event(wiiu_attach_event *event)
|
||||
{
|
||||
wiiu_attach_event *head = (wiiu_attach_event *)SwapAtomic32((uint32_t *)&events.list, 0);
|
||||
event->next = head;
|
||||
head = event;
|
||||
SwapAtomic32((uint32_t *)&events.list, (uint32_t)head);
|
||||
}
|
||||
|
||||
static wiiu_attach_event *synchronized_get_events_list(void)
|
||||
{
|
||||
return (wiiu_attach_event *)SwapAtomic32((uint32_t *)&events.list, 0);
|
||||
}
|
||||
|
||||
static wiiu_adapter_t *synchronized_lookup_adapter(uint32_t handle)
|
||||
{
|
||||
OSFastMutex_Lock(&(adapters.lock));
|
||||
wiiu_adapter_t *iterator;
|
||||
|
||||
for (iterator = adapters.list; iterator != NULL; iterator = iterator->next)
|
||||
{
|
||||
if (iterator->handle == handle)
|
||||
break;
|
||||
}
|
||||
OSFastMutex_Unlock(&(adapters.lock));
|
||||
|
||||
return iterator;
|
||||
}
|
||||
|
||||
static void synchronized_add_to_adapters_list(wiiu_adapter_t *adapter)
|
||||
{
|
||||
OSFastMutex_Lock(&(adapters.lock));
|
||||
adapter->next = adapters.list;
|
||||
adapters.list = adapter;
|
||||
OSFastMutex_Unlock(&(adapters.lock));
|
||||
}
|
||||
|
||||
static int32_t wiiu_attach_callback(HIDClient *client,
|
||||
HIDDevice *device, uint32_t attach)
|
||||
{
|
||||
wiiu_attach_event *event = NULL;
|
||||
|
||||
if (attach)
|
||||
log_device(device);
|
||||
|
||||
if (device)
|
||||
event = new_attach_event(device);
|
||||
|
||||
if (!event)
|
||||
goto error;
|
||||
|
||||
event->type = attach;
|
||||
synchronized_add_event(event);
|
||||
|
||||
return DEVICE_USED;
|
||||
|
||||
error:
|
||||
if (event)
|
||||
free(event);
|
||||
return DEVICE_UNUSED;
|
||||
}
|
||||
|
||||
static void *wiiu_hid_init(void)
|
||||
{
|
||||
RARCH_LOG("[hid]: initializing\n");
|
||||
wiiu_hid_t *hid = new_hid();
|
||||
HIDClient *client = new_hidclient();
|
||||
wiiu_hid_t *hid = alloc_zeroed(4, sizeof(wiiu_hid_t));
|
||||
HIDClient *client = alloc_zeroed(32, sizeof(HIDClient));
|
||||
|
||||
if (!hid || !client)
|
||||
goto error;
|
||||
@ -168,11 +391,11 @@ static void *wiiu_hid_init(void)
|
||||
return hid;
|
||||
|
||||
error:
|
||||
RARCH_LOG("[hid]: initialization failed. cleaning up.\n");
|
||||
|
||||
stop_polling_thread(hid);
|
||||
delete_hid(hid);
|
||||
delete_hidclient(client);
|
||||
if (hid)
|
||||
free(hid);
|
||||
if (client)
|
||||
free(client);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
@ -184,8 +407,10 @@ static void wiiu_hid_free(const void *data)
|
||||
return;
|
||||
|
||||
stop_polling_thread(hid);
|
||||
delete_hidclient(hid->client);
|
||||
delete_hid(hid);
|
||||
if (client)
|
||||
free(client);
|
||||
if (hid)
|
||||
free(hid);
|
||||
|
||||
if (events.list)
|
||||
{
|
||||
@ -193,12 +418,65 @@ static void wiiu_hid_free(const void *data)
|
||||
while ((event = events.list) != NULL)
|
||||
{
|
||||
events.list = event->next;
|
||||
delete_attach_event(event);
|
||||
if (event)
|
||||
free(event);
|
||||
}
|
||||
memset(&events, 0, sizeof(events));
|
||||
}
|
||||
}
|
||||
|
||||
static void synchronized_process_adapters(wiiu_hid_t *hid)
|
||||
{
|
||||
wiiu_adapter_t *adapter = NULL;
|
||||
wiiu_adapter_t *prev = NULL, *adapter_next = NULL;
|
||||
bool keep_prev = false;
|
||||
|
||||
OSFastMutex_Lock(&(adapters.lock));
|
||||
|
||||
for (adapter = adapters.list; adapter != NULL; adapter = adapter_next)
|
||||
{
|
||||
adapter_next = adapter->next;
|
||||
|
||||
switch(adapter->state)
|
||||
{
|
||||
case ADAPTER_STATE_NEW:
|
||||
adapter->state = try_init_driver(adapter);
|
||||
break;
|
||||
case ADAPTER_STATE_READY:
|
||||
case ADAPTER_STATE_READING:
|
||||
if (adapter->pad_driver && adapter->pad_driver->multi_pad)
|
||||
pad_connection_pad_refresh(joypad_state.pads, adapter->pad_driver, adapter->pad_driver_data, adapter, &hidpad_driver);
|
||||
break;
|
||||
case ADAPTER_STATE_DONE:
|
||||
break;
|
||||
case ADAPTER_STATE_GC:
|
||||
{
|
||||
/* remove from the list */
|
||||
if (!prev)
|
||||
adapters.list = adapter->next;
|
||||
else
|
||||
prev->next = adapter->next;
|
||||
|
||||
if (adapter->pad_driver && adapter->pad_driver_data)
|
||||
pad_connection_pad_deregister(joypad_state.pads, adapter->pad_driver, adapter->pad_driver_data);
|
||||
/* adapter is no longer valid after this point */
|
||||
delete_adapter(adapter);
|
||||
/* signal not to update prev ptr since adapter is now invalid */
|
||||
keep_prev = true;
|
||||
}
|
||||
break;
|
||||
|
||||
default:
|
||||
RARCH_ERR("[hid]: Invalid adapter state: %d\n", adapter->state);
|
||||
break;
|
||||
}
|
||||
if (!keep_prev)
|
||||
prev = adapter;
|
||||
keep_prev = false;
|
||||
}
|
||||
OSFastMutex_Unlock(&(adapters.lock));
|
||||
}
|
||||
|
||||
static void wiiu_hid_poll(void *data)
|
||||
{
|
||||
wiiu_hid_t *hid = (wiiu_hid_t *)data;
|
||||
@ -235,8 +513,10 @@ static void wiiu_hid_send_control(void *data, uint8_t *buf, size_t size)
|
||||
}
|
||||
}
|
||||
|
||||
static void _fixup_report_buffer(uint8_t **buffer, uint8_t report_id, size_t *length) {
|
||||
if((*buffer)[0] == report_id) {
|
||||
static void _fixup_report_buffer(uint8_t **buffer, uint8_t report_id, size_t *length)
|
||||
{
|
||||
if ((*buffer)[0] == report_id)
|
||||
{
|
||||
*buffer = (*buffer)+ 1;
|
||||
*length = *length - 1;
|
||||
}
|
||||
@ -323,74 +603,6 @@ static int32_t wiiu_hid_read(void *data, void *buffer, size_t size)
|
||||
return result;
|
||||
}
|
||||
|
||||
static void start_polling_thread(wiiu_hid_t *hid)
|
||||
{
|
||||
OSThreadAttributes attributes = OS_THREAD_ATTRIB_AFFINITY_CPU2;
|
||||
int32_t stack_size = 0x8000;
|
||||
int32_t priority = 10;
|
||||
OSThread *thread = new_thread();
|
||||
void *stack = alloc_zeroed(16, stack_size);
|
||||
|
||||
RARCH_LOG("[hid]: starting polling thread.\n");
|
||||
|
||||
if (!thread || !stack)
|
||||
{
|
||||
RARCH_LOG("[hid]: allocation failed, aborting thread start.\n");
|
||||
goto error;
|
||||
}
|
||||
|
||||
if (!OSCreateThread(thread,
|
||||
wiiu_hid_polling_thread,
|
||||
1, (char *)hid,
|
||||
stack+stack_size, stack_size,
|
||||
priority,
|
||||
attributes))
|
||||
{
|
||||
RARCH_LOG("[hid]: OSCreateThread failed.\n");
|
||||
goto error;
|
||||
}
|
||||
|
||||
OSSetThreadCleanupCallback(thread, wiiu_hid_polling_thread_cleanup);
|
||||
|
||||
hid->polling_thread = thread;
|
||||
hid->polling_thread_stack = stack;
|
||||
OSResumeThread(thread);
|
||||
return;
|
||||
|
||||
error:
|
||||
if (thread)
|
||||
free(thread);
|
||||
if (stack)
|
||||
free(stack);
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
static void stop_polling_thread(wiiu_hid_t *hid)
|
||||
{
|
||||
int thread_result = 0;
|
||||
RARCH_LOG("[hid]: stopping polling thread.\n");
|
||||
|
||||
if (!hid || !hid->polling_thread)
|
||||
return;
|
||||
|
||||
/* Unregister our HID client so we don't get any new events. */
|
||||
if (hid->client)
|
||||
{
|
||||
HIDDelClient(hid->client);
|
||||
hid->client = NULL;
|
||||
}
|
||||
|
||||
/* tell the thread it's time to stop. */
|
||||
hid->polling_thread_quit = true;
|
||||
/* This returns once the thread runs and the cleanup method completes. */
|
||||
OSJoinThread(hid->polling_thread, &thread_result);
|
||||
free(hid->polling_thread);
|
||||
free(hid->polling_thread_stack);
|
||||
hid->polling_thread = NULL;
|
||||
hid->polling_thread_stack = NULL;
|
||||
}
|
||||
|
||||
static void log_device(HIDDevice *device)
|
||||
{
|
||||
if (!device)
|
||||
@ -409,42 +621,49 @@ static void log_device(HIDDevice *device)
|
||||
RARCH_LOG(" max_packet_size_tx: %d\n", device->max_packet_size_tx);
|
||||
}
|
||||
|
||||
static uint8_t try_init_driver_multi(wiiu_adapter_t *adapter, joypad_connection_entry_t *entry) {
|
||||
static uint8_t try_init_driver_multi(wiiu_adapter_t *adapter, joypad_connection_entry_t *entry)
|
||||
{
|
||||
adapter->pad_driver_data = entry->iface->init(adapter, -1, &wiiu_hid);
|
||||
if(!adapter->pad_driver_data) {
|
||||
if (!adapter->pad_driver_data)
|
||||
return ADAPTER_STATE_DONE;
|
||||
}
|
||||
|
||||
pad_connection_pad_register(joypad_state.pads, adapter->pad_driver, adapter->pad_driver_data, adapter, &hidpad_driver, SLOT_AUTO);
|
||||
return ADAPTER_STATE_READY;
|
||||
}
|
||||
|
||||
static uint8_t try_init_driver(wiiu_adapter_t *adapter)
|
||||
{
|
||||
joypad_connection_entry_t *entry;
|
||||
int slot;
|
||||
|
||||
entry = find_connection_entry(adapter->vendor_id, adapter->product_id, adapter->device_name);
|
||||
if(!entry) {
|
||||
RARCH_LOG("Failed to find entry for vid: 0x%04x, pid: 0x%04x, name: %s\n", SWAP_IF_BIG(adapter->vendor_id), SWAP_IF_BIG(adapter->product_id), adapter->device_name);
|
||||
joypad_connection_entry_t *entry = find_connection_entry(adapter->vendor_id, adapter->product_id, adapter->device_name);
|
||||
if (!entry)
|
||||
{
|
||||
RARCH_LOG("Failed to find entry for vid: 0x%04x, pid: 0x%04x, name: %s\n",
|
||||
SWAP_IF_BIG(adapter->vendor_id),
|
||||
SWAP_IF_BIG(adapter->product_id),
|
||||
adapter->device_name);
|
||||
return ADAPTER_STATE_DONE;
|
||||
}
|
||||
else
|
||||
RARCH_LOG("Found entry for: vid: 0x%04x, pid: 0x%04x, name: %s\n", SWAP_IF_BIG(adapter->vendor_id), SWAP_IF_BIG(adapter->product_id), adapter->device_name);
|
||||
|
||||
RARCH_LOG("Found entry for: vid: 0x%04x, pid: 0x%04x, name: %s\n",
|
||||
SWAP_IF_BIG(adapter->vendor_id),
|
||||
SWAP_IF_BIG(adapter->product_id),
|
||||
adapter->device_name);
|
||||
|
||||
adapter->pad_driver = entry->iface;
|
||||
|
||||
if(entry->iface->multi_pad) {
|
||||
if (entry->iface->multi_pad)
|
||||
return try_init_driver_multi(adapter, entry);
|
||||
}
|
||||
|
||||
slot = pad_connection_find_vacant_pad(joypad_state.pads);
|
||||
if(slot < 0) {
|
||||
if (slot < 0)
|
||||
{
|
||||
RARCH_LOG("try_init_driver: no slot available\n");
|
||||
return ADAPTER_STATE_DONE;
|
||||
}
|
||||
|
||||
adapter->pad_driver_data = entry->iface->init(adapter, slot, &wiiu_hid);
|
||||
if(!adapter->pad_driver_data) {
|
||||
|
||||
if (!adapter->pad_driver_data)
|
||||
{
|
||||
RARCH_LOG("try_init_driver: pad init failed\n");
|
||||
return ADAPTER_STATE_DONE;
|
||||
}
|
||||
@ -454,123 +673,6 @@ static uint8_t try_init_driver(wiiu_adapter_t *adapter)
|
||||
return ADAPTER_STATE_READY;
|
||||
}
|
||||
|
||||
static void synchronized_process_adapters(wiiu_hid_t *hid)
|
||||
{
|
||||
wiiu_adapter_t *adapter = NULL;
|
||||
wiiu_adapter_t *prev = NULL, *adapter_next = NULL;
|
||||
bool keep_prev = false;
|
||||
|
||||
OSFastMutex_Lock(&(adapters.lock));
|
||||
|
||||
for (adapter = adapters.list; adapter != NULL; adapter = adapter_next)
|
||||
{
|
||||
adapter_next = adapter->next;
|
||||
|
||||
switch(adapter->state)
|
||||
{
|
||||
case ADAPTER_STATE_NEW:
|
||||
adapter->state = try_init_driver(adapter);
|
||||
break;
|
||||
case ADAPTER_STATE_READY:
|
||||
case ADAPTER_STATE_READING:
|
||||
if(adapter->pad_driver && adapter->pad_driver->multi_pad) {
|
||||
pad_connection_pad_refresh(joypad_state.pads, adapter->pad_driver, adapter->pad_driver_data, adapter, &hidpad_driver);
|
||||
}
|
||||
case ADAPTER_STATE_DONE:
|
||||
break;
|
||||
case ADAPTER_STATE_GC:
|
||||
{
|
||||
/* remove from the list */
|
||||
if (!prev)
|
||||
adapters.list = adapter->next;
|
||||
else
|
||||
prev->next = adapter->next;
|
||||
|
||||
if(adapter->pad_driver && adapter->pad_driver_data)
|
||||
{
|
||||
pad_connection_pad_deregister(joypad_state.pads, adapter->pad_driver, adapter->pad_driver_data);
|
||||
}
|
||||
/* adapter is no longer valid after this point */
|
||||
delete_adapter(adapter);
|
||||
/* signal not to update prev ptr since adapter is now invalid */
|
||||
keep_prev = true;
|
||||
}
|
||||
break;
|
||||
|
||||
default:
|
||||
RARCH_ERR("[hid]: Invalid adapter state: %d\n", adapter->state);
|
||||
break;
|
||||
}
|
||||
prev = keep_prev ? prev : adapter;
|
||||
keep_prev = false;
|
||||
}
|
||||
OSFastMutex_Unlock(&(adapters.lock));
|
||||
}
|
||||
|
||||
static void synchronized_add_event(wiiu_attach_event *event)
|
||||
{
|
||||
wiiu_attach_event *head = (wiiu_attach_event *)SwapAtomic32((uint32_t *)&events.list, 0);
|
||||
|
||||
event->next = head;
|
||||
head = event;
|
||||
|
||||
SwapAtomic32((uint32_t *)&events.list, (uint32_t)head);
|
||||
}
|
||||
|
||||
static wiiu_attach_event *synchronized_get_events_list(void)
|
||||
{
|
||||
return (wiiu_attach_event *)SwapAtomic32((uint32_t *)&events.list, 0);
|
||||
}
|
||||
|
||||
static wiiu_adapter_t *synchronized_lookup_adapter(uint32_t handle)
|
||||
{
|
||||
OSFastMutex_Lock(&(adapters.lock));
|
||||
wiiu_adapter_t *iterator;
|
||||
|
||||
for (iterator = adapters.list; iterator != NULL; iterator = iterator->next)
|
||||
{
|
||||
if (iterator->handle == handle)
|
||||
break;
|
||||
}
|
||||
OSFastMutex_Unlock(&(adapters.lock));
|
||||
|
||||
return iterator;
|
||||
}
|
||||
|
||||
static void synchronized_add_to_adapters_list(wiiu_adapter_t *adapter)
|
||||
{
|
||||
OSFastMutex_Lock(&(adapters.lock));
|
||||
adapter->next = adapters.list;
|
||||
adapters.list = adapter;
|
||||
OSFastMutex_Unlock(&(adapters.lock));
|
||||
}
|
||||
|
||||
static int32_t wiiu_attach_callback(HIDClient *client,
|
||||
HIDDevice *device, uint32_t attach)
|
||||
{
|
||||
wiiu_attach_event *event = NULL;
|
||||
|
||||
if (attach)
|
||||
{
|
||||
log_device(device);
|
||||
}
|
||||
|
||||
if (device)
|
||||
event = new_attach_event(device);
|
||||
|
||||
if (!event)
|
||||
goto error;
|
||||
|
||||
event->type = attach;
|
||||
synchronized_add_event(event);
|
||||
|
||||
return DEVICE_USED;
|
||||
|
||||
error:
|
||||
delete_attach_event(event);
|
||||
return DEVICE_UNUSED;
|
||||
}
|
||||
|
||||
static void wiiu_hid_detach(wiiu_hid_t *hid, wiiu_attach_event *event)
|
||||
{
|
||||
wiiu_adapter_t *adapter = synchronized_lookup_adapter(event->handle);
|
||||
@ -684,53 +786,6 @@ static void report_hid_error(const char *msg, wiiu_adapter_t *adapter, int32_t e
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Block until all the HIDRead() calls have returned.
|
||||
*/
|
||||
static void wiiu_hid_polling_thread_cleanup(OSThread *thread, void *stack)
|
||||
{
|
||||
int incomplete = 0;
|
||||
int retries = 0;
|
||||
wiiu_adapter_t *adapter = NULL;
|
||||
|
||||
RARCH_LOG("Waiting for in-flight reads to finish.\n");
|
||||
|
||||
/* We don't need to protect the adapter list here because nothing else
|
||||
will access it during this method (the HID system is shut down, and
|
||||
the only other access is the polling thread that just stopped */
|
||||
do
|
||||
{
|
||||
incomplete = 0;
|
||||
for (adapter = adapters.list; adapter != NULL; adapter = adapter->next)
|
||||
{
|
||||
if (adapter->state == ADAPTER_STATE_READING)
|
||||
incomplete++;
|
||||
}
|
||||
|
||||
if (incomplete == 0)
|
||||
{
|
||||
RARCH_LOG("All in-flight reads complete.\n");
|
||||
while (adapters.list)
|
||||
{
|
||||
RARCH_LOG("[hid]: shutting down adapter..\n");
|
||||
adapter = adapters.list;
|
||||
adapters.list = adapter->next;
|
||||
pad_connection_pad_deregister(joypad_state.pads, adapter->pad_driver, adapter->pad_driver_data);
|
||||
delete_adapter(adapter);
|
||||
}
|
||||
}
|
||||
|
||||
if (incomplete)
|
||||
usleep(5000);
|
||||
|
||||
if (++retries >= 1000)
|
||||
{
|
||||
RARCH_WARN("[hid]: timed out waiting for in-flight read to finish.\n");
|
||||
incomplete = 0;
|
||||
}
|
||||
} while (incomplete);
|
||||
}
|
||||
|
||||
static void wiiu_handle_attach_events(wiiu_hid_t *hid, wiiu_attach_event *list)
|
||||
{
|
||||
wiiu_attach_event *event, *event_next = NULL;
|
||||
@ -745,7 +800,8 @@ static void wiiu_handle_attach_events(wiiu_hid_t *hid, wiiu_attach_event *list)
|
||||
wiiu_hid_attach(hid, event);
|
||||
else
|
||||
wiiu_hid_detach(hid, event);
|
||||
delete_attach_event(event);
|
||||
if (event)
|
||||
free(event);
|
||||
}
|
||||
}
|
||||
|
||||
@ -772,10 +828,8 @@ static void wiiu_poll_adapters(wiiu_hid_t *hid)
|
||||
if (it->state == ADAPTER_STATE_READY)
|
||||
wiiu_poll_adapter(it);
|
||||
|
||||
if (it->state == ADAPTER_STATE_DONE) {
|
||||
|
||||
if (it->state == ADAPTER_STATE_DONE)
|
||||
it->state = ADAPTER_STATE_GC;
|
||||
}
|
||||
}
|
||||
|
||||
OSFastMutex_Unlock(&(adapters.lock));
|
||||
@ -785,60 +839,15 @@ static int wiiu_hid_polling_thread(int argc, const char **argv)
|
||||
{
|
||||
wiiu_hid_t *hid = (wiiu_hid_t *)argv;
|
||||
|
||||
RARCH_LOG("[hid]: polling thread is starting\n");
|
||||
|
||||
while (!hid->polling_thread_quit)
|
||||
{
|
||||
wiiu_handle_attach_events(hid, synchronized_get_events_list());
|
||||
wiiu_poll_adapters(hid);
|
||||
}
|
||||
|
||||
RARCH_LOG("[hid]: polling thread is stopping\n");
|
||||
return 0;
|
||||
}
|
||||
|
||||
static OSThread *new_thread(void)
|
||||
{
|
||||
OSThread *t = alloc_zeroed(8, sizeof(OSThread));
|
||||
|
||||
if (!t)
|
||||
return NULL;
|
||||
|
||||
t->tag = OS_THREAD_TAG;
|
||||
|
||||
return t;
|
||||
}
|
||||
|
||||
static void wiiu_hid_init_lists(void)
|
||||
{
|
||||
memset(&events, 0, sizeof(events));
|
||||
OSFastMutex_Init(&(events.lock), "attach_events");
|
||||
memset(&adapters, 0, sizeof(adapters));
|
||||
OSFastMutex_Init(&(adapters.lock), "adapters");
|
||||
}
|
||||
|
||||
static wiiu_hid_t *new_hid(void)
|
||||
{
|
||||
return alloc_zeroed(4, sizeof(wiiu_hid_t));
|
||||
}
|
||||
|
||||
static void delete_hid(wiiu_hid_t *hid)
|
||||
{
|
||||
if (hid)
|
||||
free(hid);
|
||||
}
|
||||
|
||||
static HIDClient *new_hidclient(void)
|
||||
{
|
||||
return alloc_zeroed(32, sizeof(HIDClient));
|
||||
}
|
||||
|
||||
static void delete_hidclient(HIDClient *client)
|
||||
{
|
||||
if (client)
|
||||
free(client);
|
||||
}
|
||||
|
||||
static void init_cachealigned_buffer(int32_t min_size, uint8_t **out_buf_ptr, int32_t *actual_size)
|
||||
{
|
||||
*actual_size = (min_size + 0x3f) & ~0x3f;
|
||||
@ -865,39 +874,15 @@ static wiiu_adapter_t *new_adapter(wiiu_attach_event *event)
|
||||
return adapter;
|
||||
}
|
||||
|
||||
static void delete_adapter(wiiu_adapter_t *adapter)
|
||||
{
|
||||
if (!adapter)
|
||||
return;
|
||||
|
||||
if (adapter->rx_buffer)
|
||||
{
|
||||
free(adapter->rx_buffer);
|
||||
adapter->rx_buffer = NULL;
|
||||
}
|
||||
if (adapter->tx_buffer)
|
||||
{
|
||||
free(adapter->tx_buffer);
|
||||
adapter->tx_buffer = NULL;
|
||||
}
|
||||
if(adapter->pad_driver && adapter->pad_driver_data) {
|
||||
adapter->pad_driver->deinit(adapter->pad_driver_data);
|
||||
adapter->pad_driver_data = NULL;
|
||||
}
|
||||
|
||||
free(adapter);
|
||||
}
|
||||
|
||||
static void get_device_name(HIDDevice *device, wiiu_attach_event *event)
|
||||
{
|
||||
int32_t result;
|
||||
uint8_t name_buffer_size = 46; /* enough to detect WiiU Pro controller */
|
||||
uint8_t *name_buffer = alloc_zeroed(4, name_buffer_size);
|
||||
uint8_t *top = &event->device_name[0];
|
||||
uint8_t *name_buffer = alloc_zeroed(4, name_buffer_size);
|
||||
uint8_t *top = &event->device_name[0];
|
||||
|
||||
if(name_buffer == NULL) {
|
||||
if (!name_buffer)
|
||||
return;
|
||||
}
|
||||
|
||||
/* HIDGetDescriptor() fills name_buffer in this way:
|
||||
* - First two bytes are empty
|
||||
@ -905,8 +890,11 @@ static void get_device_name(HIDDevice *device, wiiu_attach_event *event)
|
||||
* - Maximum name_buffer size is unknown (with 63 it starts to fail with one of my controllers)
|
||||
* - Truncates device names if name_buffer is too small */
|
||||
result = HIDGetDescriptor(device->handle, 3, 2, 0, name_buffer, name_buffer_size, NULL, NULL);
|
||||
if(result > 0) {
|
||||
for(int i = 2; i < result; i += 2) {
|
||||
if (result > 0)
|
||||
{
|
||||
int i;
|
||||
for(i = 2; i < result; i += 2)
|
||||
{
|
||||
top[0] = name_buffer[i];
|
||||
top++;
|
||||
}
|
||||
@ -916,14 +904,11 @@ static void get_device_name(HIDDevice *device, wiiu_attach_event *event)
|
||||
|
||||
static wiiu_attach_event *new_attach_event(HIDDevice *device)
|
||||
{
|
||||
if(device->protocol > 0)
|
||||
{
|
||||
/* ignore mice and keyboards as HID devices */
|
||||
wiiu_attach_event *event = NULL;
|
||||
/* Ignore mice and keyboards as HID devices */
|
||||
if (device->protocol > 0)
|
||||
return NULL;
|
||||
}
|
||||
wiiu_attach_event *event = alloc_zeroed(4, sizeof(wiiu_attach_event));
|
||||
|
||||
if (!event)
|
||||
if (!(event = alloc_zeroed(4, sizeof(wiiu_attach_event))))
|
||||
return NULL;
|
||||
|
||||
event->handle = device->handle;
|
||||
@ -941,21 +926,6 @@ static wiiu_attach_event *new_attach_event(HIDDevice *device)
|
||||
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)
|
||||
memset(result, 0, size);
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
hid_driver_t wiiu_hid = {
|
||||
wiiu_hid_init,
|
||||
wiiu_hid_joypad_query,
|
||||
|
@ -34,7 +34,8 @@
|
||||
/* The read loop has fully stopped and the adapter can be freed */
|
||||
#define ADAPTER_STATE_GC 4
|
||||
|
||||
struct wiiu_hid {
|
||||
struct wiiu_hid
|
||||
{
|
||||
/* used to register for HID notifications */
|
||||
HIDClient *client;
|
||||
/* thread state data for the HID input polling thread */
|
||||
@ -49,7 +50,8 @@ struct wiiu_hid {
|
||||
* Each HID device attached to the WiiU gets its own adapter, which
|
||||
* connects the HID subsystem with the HID device driver.
|
||||
*/
|
||||
struct wiiu_adapter {
|
||||
struct wiiu_adapter
|
||||
{
|
||||
wiiu_adapter_t *next;
|
||||
pad_connection_interface_t *pad_driver;
|
||||
void *pad_driver_data;
|
||||
@ -72,7 +74,8 @@ struct wiiu_adapter {
|
||||
* event; the attach event handler translate them into these
|
||||
* structures.
|
||||
*/
|
||||
struct wiiu_attach {
|
||||
struct wiiu_attach
|
||||
{
|
||||
wiiu_attach_event *next;
|
||||
uint32_t type;
|
||||
uint32_t handle;
|
||||
@ -86,41 +89,16 @@ struct wiiu_attach {
|
||||
uint8_t device_name[32];
|
||||
};
|
||||
|
||||
struct _wiiu_event_list {
|
||||
struct _wiiu_event_list
|
||||
{
|
||||
OSFastMutex lock;
|
||||
wiiu_attach_event *list;
|
||||
};
|
||||
|
||||
struct _wiiu_adapter_list {
|
||||
struct _wiiu_adapter_list
|
||||
{
|
||||
OSFastMutex lock;
|
||||
wiiu_adapter_t *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 wiiu_adapter_t *new_adapter(wiiu_attach_event *event);
|
||||
static void delete_adapter(wiiu_adapter_t *adapter);
|
||||
static wiiu_attach_event *new_attach_event(HIDDevice *device);
|
||||
static void delete_attach_event(wiiu_attach_event *);
|
||||
|
||||
static void wiiu_hid_init_lists(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 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_process_adapters(wiiu_hid_t *hid);
|
||||
static void synchronized_add_to_adapters_list(wiiu_adapter_t *adapter);
|
||||
static void synchronized_add_event(wiiu_attach_event *event);
|
||||
static void wiiu_hid_read_loop_callback(uint32_t handle, int32_t error,
|
||||
uint8_t *buffer, uint32_t buffer_size, void *userdata);
|
||||
static void wiiu_hid_polling_thread_cleanup(OSThread *thread, void *stack);
|
||||
|
||||
#endif /* __WIIU_HID__H */
|
||||
|
@ -52,8 +52,8 @@ extern id apple_platform;
|
||||
#endif
|
||||
|
||||
#if defined(HAVE_COCOATOUCH)
|
||||
void rarch_start_draw_observer();
|
||||
void rarch_stop_draw_observer();
|
||||
void rarch_start_draw_observer(void);
|
||||
void rarch_stop_draw_observer(void);
|
||||
|
||||
@interface RetroArch_iOS : UINavigationController<ApplePlatform, UIApplicationDelegate,
|
||||
UINavigationControllerDelegate> {
|
||||
|
Loading…
Reference in New Issue
Block a user