mirror of
https://github.com/libretro/RetroArch
synced 2025-02-27 18:41:01 +00:00
(OSX/iOS)
Move Wii and PS3 hid drivers into the common source directory. Use the Wii and PS3 hid drivers on OSX when appropriate. Notably OSX now has WiiMote support.
This commit is contained in:
parent
1ea1f723b4
commit
083f1cdffe
@ -15,57 +15,48 @@
|
||||
|
||||
#include <IOKit/hid/IOHIDManager.h>
|
||||
#include "apple/common/apple_input.h"
|
||||
#include "apple/common/hidpad/hidpad.h"
|
||||
|
||||
// NOTE: I pieced this together through trial and error, any corrections are welcome
|
||||
#include "apple/common/hidpad/hidpad_ps3.c"
|
||||
#include "apple/common/hidpad/hidpad_wii.c"
|
||||
#include "apple/common/hidpad/wiimote.c"
|
||||
|
||||
struct hidpad_connection
|
||||
{
|
||||
uint32_t slot;
|
||||
|
||||
struct hidpad_interface* interface;
|
||||
void* hidpad;
|
||||
|
||||
IOHIDDeviceRef device;
|
||||
|
||||
uint8_t data[2048];
|
||||
};
|
||||
|
||||
static IOHIDManagerRef g_hid_manager;
|
||||
static uint32_t g_pad_slots;
|
||||
static struct hidpad_connection g_connected_pads[MAX_PADS];
|
||||
|
||||
#define HID_ISSET(t, x) (t & (1 << x))
|
||||
#define HID_SET(t, x) { t |= (1 << x); }
|
||||
#define HID_CLEAR(t, x) { t &= ~(1 << x); }
|
||||
|
||||
// Set the LEDs on PS3 controllers, if slot >= MAX_PADS the LEDs will be cleared
|
||||
static void osx_pad_set_leds(IOHIDDeviceRef device, uint32_t slot)
|
||||
void hidpad_send_control(struct hidpad_connection* connection, uint8_t* data, size_t size)
|
||||
{
|
||||
char buffer[1024];
|
||||
|
||||
CFStringRef device_name = IOHIDDeviceGetProperty(device, CFSTR(kIOHIDProductKey));
|
||||
if (device_name)
|
||||
{
|
||||
CFStringGetCString(device_name, buffer, 1024, kCFStringEncodingUTF8);
|
||||
|
||||
if (strncmp(buffer, "PLAYSTATION(R)3 Controller", 1024) == 0)
|
||||
{
|
||||
static uint8_t report_buffer[] = {
|
||||
0x01,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0x27,
|
||||
0x10, 0x00, 0x32, 0xff, 0x27, 0x10, 0x00, 0x32, 0xff, 0x27, 0x10, 0x00,
|
||||
0x32, 0xff, 0x27, 0x10, 0x00, 0x32, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
|
||||
};
|
||||
report_buffer[10] = (slot >= MAX_PADS) ? 0 : (1 << (slot + 1));
|
||||
|
||||
IOHIDDeviceSetReport(device, kIOHIDReportTypeOutput, 0x01, report_buffer, sizeof(report_buffer));
|
||||
}
|
||||
}
|
||||
IOHIDDeviceSetReport(connection->device, kIOHIDReportTypeOutput, 0x01, data, size);
|
||||
}
|
||||
|
||||
static void hid_device_input_callback(void* inContext, IOReturn inResult, void* inSender, IOHIDValueRef inIOHIDValueRef)
|
||||
// NOTE: I pieced this together through trial and error, any corrections are welcome
|
||||
static void hid_device_input_callback(void* context, IOReturn result, void* sender, IOHIDValueRef value)
|
||||
{
|
||||
IOHIDElementRef element = IOHIDValueGetElement(inIOHIDValueRef);
|
||||
IOHIDDeviceRef device = IOHIDElementGetDevice(element);
|
||||
struct hidpad_connection* connection = context;
|
||||
|
||||
IOHIDElementRef element = IOHIDValueGetElement(value);
|
||||
uint32_t type = IOHIDElementGetType(element);
|
||||
uint32_t page = IOHIDElementGetUsagePage(element);
|
||||
uint32_t use = IOHIDElementGetUsage(element);
|
||||
|
||||
// Mouse handler
|
||||
if (IOHIDDeviceConformsTo(device, kHIDPage_GenericDesktop, kHIDUsage_GD_Mouse))
|
||||
if (!connection)
|
||||
{
|
||||
if (type == kIOHIDElementTypeInput_Button && page == kHIDPage_Button)
|
||||
{
|
||||
CFIndex state = IOHIDValueGetIntegerValue(inIOHIDValueRef);
|
||||
CFIndex state = IOHIDValueGetIntegerValue(value);
|
||||
|
||||
if (state) g_current_input_data.mouse_buttons |= (1 << (use - 1));
|
||||
else g_current_input_data.mouse_buttons &= ~(1 << (use - 1));
|
||||
@ -76,22 +67,18 @@ static void hid_device_input_callback(void* inContext, IOReturn inResult, void*
|
||||
|
||||
for (int i = 0; i < 2; i ++)
|
||||
if (use == axis_use_ids[i])
|
||||
g_current_input_data.mouse_delta[i] += IOHIDValueGetIntegerValue(inIOHIDValueRef);
|
||||
g_current_input_data.mouse_delta[i] += IOHIDValueGetIntegerValue(value);
|
||||
}
|
||||
}
|
||||
// Joystick handler
|
||||
else if (IOHIDDeviceConformsTo(device, kHIDPage_GenericDesktop, kHIDUsage_GD_Joystick))
|
||||
// Joystick handler: TODO: Can GamePad work the same?
|
||||
else if (IOHIDDeviceConformsTo(connection->device, kHIDPage_GenericDesktop, kHIDUsage_GD_Joystick))
|
||||
{
|
||||
uint32_t slot = (uint32_t)inContext;
|
||||
if (slot >= 4)
|
||||
return;
|
||||
|
||||
if (type == kIOHIDElementTypeInput_Button && page == kHIDPage_Button)
|
||||
{
|
||||
CFIndex state = IOHIDValueGetIntegerValue(inIOHIDValueRef);
|
||||
CFIndex state = IOHIDValueGetIntegerValue(value);
|
||||
|
||||
if (state) g_current_input_data.pad_buttons[slot] |= (1 << (use - 1));
|
||||
else g_current_input_data.pad_buttons[slot] &= ~(1 << (use - 1));
|
||||
if (state) g_current_input_data.pad_buttons[connection->slot] |= (1 << (use - 1));
|
||||
else g_current_input_data.pad_buttons[connection->slot] &= ~(1 << (use - 1));
|
||||
}
|
||||
else if (type == kIOHIDElementTypeInput_Misc && page == kHIDPage_GenericDesktop)
|
||||
{
|
||||
@ -102,62 +89,94 @@ static void hid_device_input_callback(void* inContext, IOReturn inResult, void*
|
||||
{
|
||||
CFIndex min = IOHIDElementGetPhysicalMin(element);
|
||||
CFIndex max = IOHIDElementGetPhysicalMax(element) - min;
|
||||
CFIndex state = IOHIDValueGetIntegerValue(inIOHIDValueRef) - min;
|
||||
CFIndex state = IOHIDValueGetIntegerValue(value) - min;
|
||||
|
||||
float val = (float)state / (float)max;
|
||||
g_current_input_data.pad_axis[slot][i] = ((val * 2.0f) - 1.0f) * 32767.0f;
|
||||
g_current_input_data.pad_axis[connection->slot][i] = ((val * 2.0f) - 1.0f) * 32767.0f;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static void hid_device_removed(void* inContext, IOReturn inResult, void* inSender)
|
||||
static void hid_device_removed(void* context, IOReturn result, void* sender)
|
||||
{
|
||||
IOHIDDeviceRef inDevice = (IOHIDDeviceRef)inSender;
|
||||
struct hidpad_connection* connection = (struct hidpad_connection*)context;
|
||||
|
||||
if (IOHIDDeviceConformsTo(inDevice, kHIDPage_GenericDesktop, kHIDUsage_GD_Joystick))
|
||||
if (connection && connection->slot < MAX_PADS)
|
||||
{
|
||||
uint32_t pad_index = (uint32_t)inContext;
|
||||
g_current_input_data.pad_buttons[connection->slot] = 0;
|
||||
memset(g_current_input_data.pad_axis[connection->slot], 0, sizeof(g_current_input_data.pad_axis));
|
||||
|
||||
if (pad_index < MAX_PADS)
|
||||
{
|
||||
HID_CLEAR(g_pad_slots, pad_index);
|
||||
|
||||
g_current_input_data.pad_buttons[pad_index] = 0;
|
||||
memset(g_current_input_data.pad_axis[pad_index], 0, sizeof(g_current_input_data.pad_axis));
|
||||
}
|
||||
if (connection->interface)
|
||||
connection->interface->disconnect(connection->hidpad);
|
||||
memset(connection, 0, sizeof(*connection));
|
||||
}
|
||||
|
||||
osx_pad_set_leds(inDevice, MAX_PADS);
|
||||
IOHIDDeviceClose(inDevice, kIOHIDOptionsTypeNone);
|
||||
IOHIDDeviceClose(sender, kIOHIDOptionsTypeNone);
|
||||
}
|
||||
|
||||
static void hid_manager_device_attached(void* inContext, IOReturn inResult, void* inSender, IOHIDDeviceRef inDevice)
|
||||
static void hid_device_report(void* context, IOReturn result, void *sender, IOHIDReportType type, uint32_t reportID, uint8_t *report, CFIndex reportLength)
|
||||
{
|
||||
uint32_t pad_index = 0;
|
||||
if (IOHIDDeviceConformsTo(inDevice, kHIDPage_GenericDesktop, kHIDUsage_GD_Joystick))
|
||||
{
|
||||
if ((g_pad_slots & 0xF) == 0xF)
|
||||
return;
|
||||
struct hidpad_connection* connection = (struct hidpad_connection*)context;
|
||||
connection->interface->packet_handler(connection->hidpad, report, reportLength);
|
||||
}
|
||||
|
||||
for (pad_index = 0; pad_index != MAX_PADS; pad_index ++)
|
||||
if (!HID_ISSET(g_pad_slots, pad_index))
|
||||
static void hid_manager_device_attached(void* context, IOReturn result, void* sender, IOHIDDeviceRef device)
|
||||
{
|
||||
HID_SET(g_pad_slots, pad_index);
|
||||
bool is_pad = (IOHIDDeviceConformsTo(device, kHIDPage_GenericDesktop, kHIDUsage_GD_Joystick) ||
|
||||
IOHIDDeviceConformsTo(device, kHIDPage_GenericDesktop, kHIDUsage_GD_GamePad));
|
||||
|
||||
struct hidpad_connection* connection = 0;
|
||||
|
||||
if (is_pad)
|
||||
{
|
||||
for (int i = 0; i != MAX_PADS; i ++)
|
||||
{
|
||||
if (!g_connected_pads[i].device)
|
||||
{
|
||||
connection = &g_connected_pads[i];
|
||||
connection->device = device;
|
||||
connection->slot = i;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
IOHIDDeviceOpen(inDevice, kIOHIDOptionsTypeNone);
|
||||
IOHIDDeviceScheduleWithRunLoop(inDevice, CFRunLoopGetCurrent(), kCFRunLoopCommonModes);
|
||||
IOHIDDeviceRegisterInputValueCallback(inDevice, hid_device_input_callback, (void*)pad_index);
|
||||
IOHIDDeviceRegisterRemovalCallback(inDevice, hid_device_removed, (void*)pad_index);
|
||||
|
||||
osx_pad_set_leds(inDevice, pad_index);
|
||||
if (!connection)
|
||||
return;
|
||||
}
|
||||
|
||||
static CFMutableDictionaryRef build_matching_dictionary(uint32_t page, uint32_t use)
|
||||
IOHIDDeviceOpen(device, kIOHIDOptionsTypeNone);
|
||||
IOHIDDeviceScheduleWithRunLoop(device, CFRunLoopGetCurrent(), kCFRunLoopCommonModes);
|
||||
IOHIDDeviceRegisterRemovalCallback(device, hid_device_removed, connection);
|
||||
|
||||
CFStringRef device_name = IOHIDDeviceGetProperty(device, CFSTR(kIOHIDProductKey));
|
||||
if (is_pad && device_name)
|
||||
{
|
||||
static const struct { const char* name; struct hidpad_interface* iface; } hidpad_map[] = {
|
||||
{ "Nintendo RVL-CNT-01", &hidpad_wii },
|
||||
{ "PLAYSTATION(R)3 Controller", &hidpad_ps3 },
|
||||
{ 0, 0} };
|
||||
|
||||
char buffer[1024];
|
||||
CFStringGetCString(device_name, buffer, 1024, kCFStringEncodingUTF8);
|
||||
|
||||
for (int i = 0; hidpad_map[i].name; i ++)
|
||||
{
|
||||
if (strstr(buffer, hidpad_map[i].name))
|
||||
{
|
||||
connection->interface = hidpad_map[i].iface;
|
||||
IOHIDDeviceRegisterInputReportCallback(device, connection->data, 2048, hid_device_report, connection);
|
||||
connection->hidpad = connection->interface->connect(connection, connection->slot);
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
IOHIDDeviceRegisterInputValueCallback(device, hid_device_input_callback, connection);
|
||||
}
|
||||
|
||||
static void append_matching_dictionary(CFMutableArrayRef array, uint32_t page, uint32_t use)
|
||||
{
|
||||
CFMutableDictionaryRef matcher = CFDictionaryCreateMutable(kCFAllocatorDefault, 0, &kCFTypeDictionaryKeyCallBacks, &kCFTypeDictionaryValueCallBacks);
|
||||
|
||||
@ -169,7 +188,8 @@ static CFMutableDictionaryRef build_matching_dictionary(uint32_t page, uint32_t
|
||||
CFDictionarySetValue(matcher, CFSTR(kIOHIDDeviceUsageKey), usen);
|
||||
CFRelease(usen);
|
||||
|
||||
return matcher;
|
||||
CFArrayAppendValue(array, matcher);
|
||||
CFRelease(matcher);
|
||||
}
|
||||
|
||||
void osx_pad_init()
|
||||
@ -179,14 +199,9 @@ void osx_pad_init()
|
||||
g_hid_manager = IOHIDManagerCreate(kCFAllocatorDefault, kIOHIDOptionsTypeNone);
|
||||
|
||||
CFMutableArrayRef matcher = CFArrayCreateMutable(kCFAllocatorDefault, 0, &kCFTypeArrayCallBacks);
|
||||
|
||||
CFMutableDictionaryRef mouse = build_matching_dictionary(kHIDPage_GenericDesktop, kHIDUsage_GD_Mouse);
|
||||
CFArrayAppendValue(matcher, mouse);
|
||||
CFRelease(mouse);
|
||||
|
||||
CFMutableDictionaryRef joystick = build_matching_dictionary(kHIDPage_GenericDesktop, kHIDUsage_GD_Joystick);
|
||||
CFArrayAppendValue(matcher, joystick);
|
||||
CFRelease(joystick);
|
||||
append_matching_dictionary(matcher, kHIDPage_GenericDesktop, kHIDUsage_GD_Mouse);
|
||||
append_matching_dictionary(matcher, kHIDPage_GenericDesktop, kHIDUsage_GD_Joystick);
|
||||
append_matching_dictionary(matcher, kHIDPage_GenericDesktop, kHIDUsage_GD_GamePad);
|
||||
|
||||
IOHIDManagerSetDeviceMatchingMultiple(g_hid_manager, matcher);
|
||||
CFRelease(matcher);
|
||||
|
@ -18,15 +18,16 @@
|
||||
|
||||
#ifdef IOS
|
||||
#include "apple/iOS/bluetooth/btdynamic.c"
|
||||
#include "apple/iOS/bluetooth/wiimote.c"
|
||||
#include "apple/iOS/bluetooth/btpad.c"
|
||||
#include "apple/iOS/bluetooth/btpad_ps3.c"
|
||||
#include "apple/iOS/bluetooth/btpad_wii.c"
|
||||
#include "apple/iOS/bluetooth/btpad_queue.c"
|
||||
#elif defined(OSX)
|
||||
#include "../OSX/hid_pad.c"
|
||||
#endif
|
||||
|
||||
#include "apple/common/hidpad/wiimote.c"
|
||||
#include "apple/common/hidpad/hidpad_ps3.c"
|
||||
#include "apple/common/hidpad/hidpad_wii.c"
|
||||
|
||||
|
||||
static bool apple_joypad_init(void)
|
||||
{
|
||||
|
32
apple/common/hidpad/hidpad.h
Normal file
32
apple/common/hidpad/hidpad.h
Normal file
@ -0,0 +1,32 @@
|
||||
/* RetroArch - A frontend for libretro.
|
||||
* Copyright (C) 2013 - Jason Fetters
|
||||
*
|
||||
* 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 __IOS_RARCH_HIDPAD_H__
|
||||
#define __IOS_RARCH_HIDPAD_H__
|
||||
|
||||
struct hidpad_connection;
|
||||
void hidpad_send_control(struct hidpad_connection* connection, uint8_t* data, size_t size);
|
||||
|
||||
struct hidpad_interface
|
||||
{
|
||||
void* (*connect)(struct hidpad_connection* connection, uint32_t slot);
|
||||
void (*disconnect)(void* device);
|
||||
void (*packet_handler)(void* device, uint8_t *packet, uint16_t size);
|
||||
};
|
||||
|
||||
extern struct hidpad_interface hidpad_wii;
|
||||
extern struct hidpad_interface hidpad_ps3;
|
||||
|
||||
#endif
|
@ -20,22 +20,19 @@
|
||||
#include "boolean.h"
|
||||
#include "apple/common/rarch_wrapper.h"
|
||||
|
||||
#include "btdynamic.h"
|
||||
#include "btpad.h"
|
||||
#include "hidpad.h"
|
||||
|
||||
struct btpad_ps3_data
|
||||
struct hidpad_ps3_data
|
||||
{
|
||||
uint8_t data[512];
|
||||
struct hidpad_connection* connection;
|
||||
|
||||
bd_addr_t address;
|
||||
uint32_t handle;
|
||||
uint32_t channels[2];
|
||||
uint8_t data[512];
|
||||
|
||||
uint32_t slot;
|
||||
bool have_led;
|
||||
};
|
||||
|
||||
static void btpad_ps3_send_control(struct btpad_ps3_data* device)
|
||||
static void hidpad_ps3_send_control(struct hidpad_ps3_data* device)
|
||||
{
|
||||
// TODO: Can this be modified to turn off motion tracking?
|
||||
static uint8_t report_buffer[] = {
|
||||
@ -52,35 +49,38 @@ static void btpad_ps3_send_control(struct btpad_ps3_data* device)
|
||||
};
|
||||
|
||||
report_buffer[11] = 1 << ((device->slot % 4) + 1);
|
||||
bt_send_l2cap_ptr(device->channels[0], report_buffer, sizeof(report_buffer));
|
||||
#ifdef IOS
|
||||
hidpad_send_control(device->connection, report_buffer, sizeof(report_buffer));
|
||||
#else
|
||||
hidpad_send_control(device->connection, report_buffer + 1, sizeof(report_buffer) - 1);
|
||||
#endif
|
||||
}
|
||||
|
||||
static void* btpad_ps3_connect(const btpad_connection_t* connection)
|
||||
static void* hidpad_ps3_connect(struct hidpad_connection* connection, uint32_t slot)
|
||||
{
|
||||
struct btpad_ps3_data* device = malloc(sizeof(struct btpad_ps3_data));
|
||||
struct hidpad_ps3_data* device = malloc(sizeof(struct hidpad_ps3_data));
|
||||
memset(device, 0, sizeof(*device));
|
||||
|
||||
memcpy(device->address, connection->address, BD_ADDR_LEN);
|
||||
device->handle = connection->handle;
|
||||
device->channels[0] = connection->channels[0];
|
||||
device->channels[1] = connection->channels[1];
|
||||
device->slot = connection->slot;
|
||||
device->connection = connection;
|
||||
device->slot = slot;
|
||||
|
||||
// Magic packet to start reports
|
||||
#ifdef IOS
|
||||
static uint8_t data[] = {0x53, 0xF4, 0x42, 0x03, 0x00, 0x00};
|
||||
bt_send_l2cap_ptr(device->channels[0], data, 6);
|
||||
hidpad_send_control(device->connection, data, 6);
|
||||
#endif
|
||||
|
||||
// Without this the digital buttons won't be reported
|
||||
btpad_ps3_send_control(device);
|
||||
hidpad_ps3_send_control(device);
|
||||
|
||||
return device;
|
||||
}
|
||||
|
||||
static void btpad_ps3_disconnect(struct btpad_ps3_data* device)
|
||||
static void hidpad_ps3_disconnect(struct hidpad_ps3_data* device)
|
||||
{
|
||||
free(device);
|
||||
}
|
||||
|
||||
static uint32_t btpad_ps3_get_buttons(struct btpad_ps3_data* device)
|
||||
static uint32_t hidpad_ps3_get_buttons(struct hidpad_ps3_data* device)
|
||||
{
|
||||
#define KEY(X) RETRO_DEVICE_ID_JOYPAD_##X
|
||||
static const uint32_t button_mapping[17] =
|
||||
@ -102,7 +102,7 @@ static uint32_t btpad_ps3_get_buttons(struct btpad_ps3_data* device)
|
||||
return result;
|
||||
}
|
||||
|
||||
static int16_t btpad_ps3_get_axis(struct btpad_ps3_data* device, unsigned axis)
|
||||
static int16_t hidpad_ps3_get_axis(struct hidpad_ps3_data* device, unsigned axis)
|
||||
{
|
||||
if (axis < 4)
|
||||
{
|
||||
@ -114,28 +114,28 @@ static int16_t btpad_ps3_get_axis(struct btpad_ps3_data* device, unsigned axis)
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void btpad_ps3_packet_handler(struct btpad_ps3_data* device, uint8_t packet_type, uint16_t channel, uint8_t *packet, uint16_t size)
|
||||
{
|
||||
if (packet_type == L2CAP_DATA_PACKET && packet[0] == 0xA1)
|
||||
static void hidpad_ps3_packet_handler(struct hidpad_ps3_data* device, uint8_t *packet, uint16_t size)
|
||||
{
|
||||
if (!device->have_led)
|
||||
{
|
||||
btpad_ps3_send_control(device);
|
||||
hidpad_ps3_send_control(device);
|
||||
device->have_led = true;
|
||||
}
|
||||
|
||||
#ifdef IOS
|
||||
memcpy(device->data, packet, size);
|
||||
g_current_input_data.pad_buttons[device->slot] = btpad_ps3_get_buttons(device);
|
||||
#else
|
||||
memcpy(device->data + 1, packet, size);
|
||||
#endif
|
||||
|
||||
g_current_input_data.pad_buttons[device->slot] = hidpad_ps3_get_buttons(device);
|
||||
for (int i = 0; i < 4; i ++)
|
||||
g_current_input_data.pad_axis[device->slot][i] = btpad_ps3_get_axis(device, i);
|
||||
}
|
||||
g_current_input_data.pad_axis[device->slot][i] = hidpad_ps3_get_axis(device, i);
|
||||
}
|
||||
|
||||
struct btpad_interface btpad_ps3 =
|
||||
struct hidpad_interface hidpad_ps3 =
|
||||
{
|
||||
(void*)&btpad_ps3_connect,
|
||||
(void*)&btpad_ps3_disconnect,
|
||||
(void*)&btpad_ps3_get_buttons,
|
||||
(void*)&btpad_ps3_get_axis,
|
||||
(void*)&btpad_ps3_packet_handler
|
||||
(void*)&hidpad_ps3_connect,
|
||||
(void*)&hidpad_ps3_disconnect,
|
||||
(void*)&hidpad_ps3_packet_handler
|
||||
};
|
113
apple/common/hidpad/hidpad_wii.c
Normal file
113
apple/common/hidpad/hidpad_wii.c
Normal file
@ -0,0 +1,113 @@
|
||||
/* RetroArch - A frontend for libretro.
|
||||
* Copyright (C) 2013 - Jason Fetters
|
||||
*
|
||||
* 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/>.
|
||||
*/
|
||||
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
#include <stdlib.h>
|
||||
|
||||
#include "boolean.h"
|
||||
#include "apple/common/rarch_wrapper.h"
|
||||
|
||||
#include "wiimote.h"
|
||||
#include "hidpad.h"
|
||||
|
||||
static void* hidpad_wii_connect(struct hidpad_connection* connection, uint32_t slot)
|
||||
{
|
||||
struct wiimote_t* device = malloc(sizeof(struct wiimote_t));
|
||||
memset(device, 0, sizeof(struct wiimote_t));
|
||||
|
||||
device->connection = connection;
|
||||
device->unid = slot;
|
||||
device->state = WIIMOTE_STATE_CONNECTED;
|
||||
device->exp.type = EXP_NONE;
|
||||
|
||||
wiimote_handshake(device, -1, NULL, -1);
|
||||
|
||||
return device;
|
||||
}
|
||||
|
||||
static void hidpad_wii_disconnect(struct wiimote_t* device)
|
||||
{
|
||||
free(device);
|
||||
}
|
||||
|
||||
static int16_t hidpad_wii_get_axis(struct wiimote_t* device, unsigned axis)
|
||||
{
|
||||
/* TODO
|
||||
if (device->.exp.type == EXP_CLASSIC)
|
||||
{
|
||||
switch (axis)
|
||||
{
|
||||
case 0: return device->wiimote.exp.classic.ljs.rx * 0x7FFF;
|
||||
case 1: return device->wiimote.exp.classic.ljs.ry * 0x7FFF;
|
||||
case 2: return device->wiimote.exp.classic.rjs.rx * 0x7FFF;
|
||||
case 3: return device->wiimote.exp.classic.rjs.ry * 0x7FFF;
|
||||
default: return 0;
|
||||
}
|
||||
}
|
||||
*/
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void hidpad_wii_packet_handler(struct wiimote_t* device, uint8_t *packet, uint16_t size)
|
||||
{
|
||||
#ifdef IOS
|
||||
byte* msg = packet + 2;
|
||||
switch (packet[1])
|
||||
#else
|
||||
byte* msg = packet + 1;
|
||||
switch (packet[0])
|
||||
#endif
|
||||
{
|
||||
case WM_RPT_BTN:
|
||||
{
|
||||
wiimote_pressed_buttons(device, msg);
|
||||
break;
|
||||
}
|
||||
|
||||
case WM_RPT_READ:
|
||||
{
|
||||
wiimote_pressed_buttons(device, msg);
|
||||
wiimote_handshake(device, WM_RPT_READ, msg + 5, ((msg[2] & 0xF0) >> 4) + 1);
|
||||
break;
|
||||
}
|
||||
|
||||
case WM_RPT_CTRL_STATUS:
|
||||
{
|
||||
wiimote_pressed_buttons(device, msg);
|
||||
wiimote_handshake(device,WM_RPT_CTRL_STATUS,msg,-1);
|
||||
break;
|
||||
}
|
||||
|
||||
case WM_RPT_BTN_EXP:
|
||||
{
|
||||
wiimote_pressed_buttons(device, msg);
|
||||
wiimote_handle_expansion(device, msg+2);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
g_current_input_data.pad_buttons[device->unid] = device->btns | (device->exp.classic.btns << 16);
|
||||
for (int i = 0; i < 4; i ++)
|
||||
g_current_input_data.pad_axis[device->unid][i] = hidpad_wii_get_axis(device, i);
|
||||
}
|
||||
|
||||
struct hidpad_interface hidpad_wii =
|
||||
{
|
||||
(void*)&hidpad_wii_connect,
|
||||
(void*)&hidpad_wii_disconnect,
|
||||
(void*)&hidpad_wii_packet_handler
|
||||
};
|
@ -45,8 +45,6 @@
|
||||
#include <unistd.h>
|
||||
#include "boolean.h"
|
||||
|
||||
#include "btdynamic.h"
|
||||
#include "btstack/btstack.h"
|
||||
#include "wiimote.h"
|
||||
|
||||
int wiimote_send(struct wiimote_t* wm, byte report_type, byte* msg, int len);
|
||||
@ -360,7 +358,11 @@ int wiimote_send(struct wiimote_t* wm, byte report_type, byte* msg, int len)
|
||||
printf("\n");
|
||||
#endif
|
||||
|
||||
bt_send_l2cap_ptr( wm->c_source_cid, buf, len+2);
|
||||
#ifdef IOS
|
||||
hidpad_send_control(wm->connection, buf, len + 2);
|
||||
#else
|
||||
hidpad_send_control(wm->connection, buf + 1, len + 1);
|
||||
#endif
|
||||
return 1;
|
||||
}
|
||||
|
@ -41,7 +41,7 @@
|
||||
#ifndef __WIIMOTE_H__
|
||||
#define __WIIMOTE_H__
|
||||
|
||||
#include "btstack/utils.h"
|
||||
#include "hidpad.h"
|
||||
|
||||
#if defined(__cplusplus)
|
||||
extern "C" {
|
||||
@ -232,11 +232,7 @@ extern "C" {
|
||||
typedef struct wiimote_t {
|
||||
int unid; /**< user specified id */
|
||||
|
||||
uint16_t wiiMoteConHandle;
|
||||
uint16_t i_source_cid;
|
||||
uint16_t c_source_cid;
|
||||
bd_addr_t addr;
|
||||
|
||||
struct hidpad_connection* connection;
|
||||
int state; /**< various state flags */
|
||||
byte leds; /**< currently lit leds */
|
||||
float battery_level; /**< battery level */
|
@ -294,31 +294,31 @@ const rarch_setting_t setting_data[] =
|
||||
END_SUB_GROUP()
|
||||
|
||||
START_SUB_GROUP("Player 1")
|
||||
CONFIG_BIND(g_settings.input.binds[0][RETRO_DEVICE_ID_JOYPAD_B], 1, "b", "B button (down)")
|
||||
CONFIG_BIND(g_settings.input.binds[0][RETRO_DEVICE_ID_JOYPAD_Y], 1, "y", "Y button (left)")
|
||||
CONFIG_BIND(g_settings.input.binds[0][RETRO_DEVICE_ID_JOYPAD_SELECT],1, "select", "Select button")
|
||||
CONFIG_BIND(g_settings.input.binds[0][RETRO_DEVICE_ID_JOYPAD_START], 1, "start", "Start button")
|
||||
CONFIG_BIND(g_settings.input.binds[0][RETRO_DEVICE_ID_JOYPAD_UP], 1, "up", "Up D-pad")
|
||||
CONFIG_BIND(g_settings.input.binds[0][RETRO_DEVICE_ID_JOYPAD_DOWN], 1, "down", "Down D-pad")
|
||||
CONFIG_BIND(g_settings.input.binds[0][RETRO_DEVICE_ID_JOYPAD_LEFT], 1, "left", "Left D-pad")
|
||||
CONFIG_BIND(g_settings.input.binds[0][RETRO_DEVICE_ID_JOYPAD_RIGHT], 1, "right", "Right D-pad")
|
||||
CONFIG_BIND(g_settings.input.binds[0][RETRO_DEVICE_ID_JOYPAD_SELECT],1, "select", "Select button")
|
||||
CONFIG_BIND(g_settings.input.binds[0][RETRO_DEVICE_ID_JOYPAD_START], 1, "start", "Start button")
|
||||
CONFIG_BIND(g_settings.input.binds[0][RETRO_DEVICE_ID_JOYPAD_B], 1, "b", "B button (down)")
|
||||
CONFIG_BIND(g_settings.input.binds[0][RETRO_DEVICE_ID_JOYPAD_A], 1, "a", "A button (right)")
|
||||
CONFIG_BIND(g_settings.input.binds[0][RETRO_DEVICE_ID_JOYPAD_X], 1, "x", "X button (top)")
|
||||
CONFIG_BIND(g_settings.input.binds[0][RETRO_DEVICE_ID_JOYPAD_Y], 1, "y", "Y button (left)")
|
||||
CONFIG_BIND(g_settings.input.binds[0][RETRO_DEVICE_ID_JOYPAD_L], 1, "l", "L button (left shoulder)")
|
||||
CONFIG_BIND(g_settings.input.binds[0][RETRO_DEVICE_ID_JOYPAD_R], 1, "r", "R button (right shoulder)")
|
||||
CONFIG_BIND(g_settings.input.binds[0][RETRO_DEVICE_ID_JOYPAD_L2], 1, "l2", "L2 button (left shoulder #2)")
|
||||
CONFIG_BIND(g_settings.input.binds[0][RETRO_DEVICE_ID_JOYPAD_R2], 1, "r2", "R2 button (right shoulder #2)")
|
||||
CONFIG_BIND(g_settings.input.binds[0][RETRO_DEVICE_ID_JOYPAD_L3], 1, "l3", "L3 button (left analog button)")
|
||||
CONFIG_BIND(g_settings.input.binds[0][RETRO_DEVICE_ID_JOYPAD_R3], 1, "r3", "R3 button (right analog button)")
|
||||
CONFIG_BIND(g_settings.input.binds[0][RARCH_TURBO_ENABLE], 1, "turbo", "Turbo enable")
|
||||
CONFIG_BIND(g_settings.input.binds[0][RARCH_ANALOG_LEFT_X_PLUS], 1, "l_x_plus", "Left analog X+ (right)")
|
||||
CONFIG_BIND(g_settings.input.binds[0][RARCH_ANALOG_LEFT_X_MINUS], 1, "l_x_minus", "Left analog X- (left)")
|
||||
CONFIG_BIND(g_settings.input.binds[0][RARCH_ANALOG_LEFT_Y_PLUS], 1, "l_y_plus", "Left analog Y+ (down)")
|
||||
CONFIG_BIND(g_settings.input.binds[0][RARCH_ANALOG_LEFT_Y_MINUS], 1, "l_y_minus", "Left analog Y- (up)")
|
||||
CONFIG_BIND(g_settings.input.binds[0][RARCH_ANALOG_RIGHT_X_PLUS], 1, "r_x_plus", "Right analog X+ (right)")
|
||||
CONFIG_BIND(g_settings.input.binds[0][RARCH_ANALOG_RIGHT_X_MINUS], 1, "r_x_minus", "Right analog X- (left)")
|
||||
CONFIG_BIND(g_settings.input.binds[0][RARCH_ANALOG_RIGHT_Y_PLUS], 1, "r_y_plus", "Right analog Y+ (down)")
|
||||
CONFIG_BIND(g_settings.input.binds[0][RARCH_ANALOG_LEFT_Y_PLUS], 1, "l_y_plus", "Left analog Y+ (down)")
|
||||
CONFIG_BIND(g_settings.input.binds[0][RARCH_ANALOG_LEFT_X_MINUS], 1, "l_x_minus", "Left analog X- (left)")
|
||||
CONFIG_BIND(g_settings.input.binds[0][RARCH_ANALOG_LEFT_X_PLUS], 1, "l_x_plus", "Left analog X+ (right)")
|
||||
CONFIG_BIND(g_settings.input.binds[0][RARCH_ANALOG_RIGHT_Y_MINUS], 1, "r_y_minus", "Right analog Y- (up)")
|
||||
CONFIG_BIND(g_settings.input.binds[0][RARCH_ANALOG_RIGHT_Y_PLUS], 1, "r_y_plus", "Right analog Y+ (down)")
|
||||
CONFIG_BIND(g_settings.input.binds[0][RARCH_ANALOG_RIGHT_X_MINUS], 1, "r_x_minus", "Right analog X- (left)")
|
||||
CONFIG_BIND(g_settings.input.binds[0][RARCH_ANALOG_RIGHT_X_PLUS], 1, "r_x_plus", "Right analog X+ (right)")
|
||||
CONFIG_BIND(g_settings.input.binds[0][RARCH_TURBO_ENABLE], 1, "turbo", "Turbo enable")
|
||||
END_SUB_GROUP()
|
||||
END_GROUP()
|
||||
|
||||
|
@ -21,14 +21,38 @@
|
||||
#include <string.h>
|
||||
|
||||
#include "apple/common/rarch_wrapper.h"
|
||||
#include "apple/common/hidpad/hidpad.h"
|
||||
#include "btdynamic.h"
|
||||
#include "btpad.h"
|
||||
#include "btpad_queue.h"
|
||||
#include "wiimote.h"
|
||||
|
||||
static btpad_connection_t btpad_connection[MAX_PADS];
|
||||
static struct btpad_interface* btpad_iface[MAX_PADS];
|
||||
static void* btpad_device[MAX_PADS];
|
||||
// Private interface
|
||||
enum btpad_state { BTPAD_EMPTY, BTPAD_CONNECTING, BTPAD_CONNECTED };
|
||||
|
||||
struct hidpad_connection
|
||||
{
|
||||
uint32_t slot;
|
||||
|
||||
struct hidpad_interface* interface;
|
||||
void* hidpad;
|
||||
|
||||
enum btpad_state state;
|
||||
|
||||
bool has_address;
|
||||
bd_addr_t address;
|
||||
|
||||
uint16_t handle;
|
||||
uint16_t channels[2]; //0: Control, 1: Interrupt
|
||||
};
|
||||
|
||||
static struct hidpad_connection g_connected_pads[MAX_PADS];
|
||||
|
||||
void hidpad_send_control(struct hidpad_connection* connection, uint8_t* data, size_t size)
|
||||
{
|
||||
bt_send_l2cap_ptr(connection->channels[0], data, size);
|
||||
}
|
||||
|
||||
|
||||
static bool inquiry_off;
|
||||
static bool inquiry_running;
|
||||
|
||||
@ -41,35 +65,18 @@ void btpad_set_inquiry_state(bool on)
|
||||
btpad_queue_hci_inquiry(HCI_INQUIRY_LAP, 3, 1);
|
||||
}
|
||||
|
||||
// MAIN THREAD ONLY
|
||||
uint32_t btpad_get_buttons(uint32_t slot)
|
||||
{
|
||||
if (slot < MAX_PADS && btpad_device[slot] && btpad_iface[slot])
|
||||
return btpad_iface[slot]->get_buttons(btpad_device[slot]);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int16_t btpad_get_axis(uint32_t slot, unsigned axis)
|
||||
{
|
||||
if (slot < MAX_PADS && btpad_device[slot] && btpad_iface[slot])
|
||||
return btpad_iface[slot]->get_axis(btpad_device[slot], axis);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
// Internal interface:
|
||||
static int32_t btpad_find_slot_for(uint16_t handle, bd_addr_t address)
|
||||
{
|
||||
for (int i = 0; i < MAX_PADS; i ++)
|
||||
{
|
||||
if (!btpad_connection[i].handle && !btpad_connection[i].has_address)
|
||||
if (!g_connected_pads[i].handle && !g_connected_pads[i].has_address)
|
||||
continue;
|
||||
|
||||
if (handle && btpad_connection[i].handle && handle != btpad_connection[i].handle)
|
||||
if (handle && g_connected_pads[i].handle && handle != g_connected_pads[i].handle)
|
||||
continue;
|
||||
|
||||
if (address && btpad_connection[i].has_address && (BD_ADDR_CMP(address, btpad_connection[i].address)))
|
||||
if (address && g_connected_pads[i].has_address && (BD_ADDR_CMP(address, g_connected_pads[i].address)))
|
||||
continue;
|
||||
|
||||
return i;
|
||||
@ -81,7 +88,7 @@ static int32_t btpad_find_slot_for(uint16_t handle, bd_addr_t address)
|
||||
static int32_t btpad_find_slot_with_state(enum btpad_state state)
|
||||
{
|
||||
for (int i = 0; i < MAX_PADS; i ++)
|
||||
if (btpad_connection[i].state == state)
|
||||
if (g_connected_pads[i].state == state)
|
||||
return i;
|
||||
|
||||
return -1;
|
||||
@ -92,19 +99,16 @@ static void btpad_disconnect_pad(uint32_t slot)
|
||||
if (slot > MAX_PADS)
|
||||
return;
|
||||
|
||||
if (btpad_iface[slot] && btpad_device[slot])
|
||||
if (g_connected_pads[slot].interface && g_connected_pads[slot].hidpad)
|
||||
{
|
||||
ios_add_log_message("BTpad: Disconnecting slot %d", slot);
|
||||
|
||||
btpad_iface[slot]->disconnect(btpad_device[slot]);
|
||||
btpad_device[slot] = 0;
|
||||
btpad_iface[slot] = 0;
|
||||
g_connected_pads[slot].interface->disconnect(g_connected_pads[slot].hidpad);
|
||||
}
|
||||
|
||||
if (btpad_connection[slot].handle)
|
||||
btpad_queue_hci_disconnect(btpad_connection[slot].handle, 0x15);
|
||||
if (g_connected_pads[slot].handle)
|
||||
btpad_queue_hci_disconnect(g_connected_pads[slot].handle, 0x15);
|
||||
|
||||
memset(&btpad_connection[slot], 0, sizeof(btpad_connection_t));
|
||||
memset(&g_connected_pads[slot], 0, sizeof(struct hidpad_connection));
|
||||
}
|
||||
|
||||
static void btpad_disconnect_all_pads()
|
||||
@ -134,7 +138,7 @@ void btpad_packet_handler(uint8_t packet_type, uint16_t channel, uint8_t *packet
|
||||
|
||||
btpad_queue_run(1);
|
||||
}
|
||||
else if(packet[2] > HCI_STATE_WORKING && btpad_iface && btpad_device)
|
||||
else if(packet[2] > HCI_STATE_WORKING)
|
||||
{
|
||||
btpad_disconnect_all_pads();
|
||||
}
|
||||
@ -171,14 +175,14 @@ void btpad_packet_handler(uint8_t packet_type, uint16_t channel, uint8_t *packet
|
||||
{
|
||||
ios_add_log_message("BTpad: Inquiry found device (Slot %d)", slot);
|
||||
|
||||
memcpy(btpad_connection[slot].address, event_addr, sizeof(bd_addr_t));
|
||||
memcpy(g_connected_pads[slot].address, event_addr, sizeof(bd_addr_t));
|
||||
|
||||
btpad_connection[slot].has_address = true;
|
||||
btpad_connection[slot].state = BTPAD_CONNECTING;
|
||||
btpad_connection[slot].slot = slot;
|
||||
g_connected_pads[slot].has_address = true;
|
||||
g_connected_pads[slot].state = BTPAD_CONNECTING;
|
||||
g_connected_pads[slot].slot = slot;
|
||||
|
||||
bt_send_cmd_ptr(l2cap_create_channel_ptr, btpad_connection[slot].address, PSM_HID_CONTROL);
|
||||
bt_send_cmd_ptr(l2cap_create_channel_ptr, btpad_connection[slot].address, PSM_HID_INTERRUPT);
|
||||
bt_send_cmd_ptr(l2cap_create_channel_ptr, g_connected_pads[slot].address, PSM_HID_CONTROL);
|
||||
bt_send_cmd_ptr(l2cap_create_channel_ptr, g_connected_pads[slot].address, PSM_HID_INTERRUPT);
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -213,19 +217,19 @@ void btpad_packet_handler(uint8_t packet_type, uint16_t channel, uint8_t *packet
|
||||
}
|
||||
|
||||
ios_add_log_message("BTpad: L2CAP channel opened: (Slot: %d, PSM: %02X)", slot, psm);
|
||||
btpad_connection[slot].handle = handle;
|
||||
g_connected_pads[slot].handle = handle;
|
||||
|
||||
if (psm == PSM_HID_CONTROL)
|
||||
btpad_connection[slot].channels[0] = channel_id;
|
||||
g_connected_pads[slot].channels[0] = channel_id;
|
||||
else if (psm == PSM_HID_INTERRUPT)
|
||||
btpad_connection[slot].channels[1] = channel_id;
|
||||
g_connected_pads[slot].channels[1] = channel_id;
|
||||
else
|
||||
ios_add_log_message("BTpad: Got unknown L2CAP PSM, ignoring (Slot: %d, PSM: %02X)", slot, psm);
|
||||
|
||||
if (btpad_connection[slot].channels[0] && btpad_connection[slot].channels[1])
|
||||
if (g_connected_pads[slot].channels[0] && g_connected_pads[slot].channels[1])
|
||||
{
|
||||
ios_add_log_message("BTpad: Got both L2CAP channels, requesting name (Slot: %d)", slot);
|
||||
btpad_queue_hci_remote_name_request(btpad_connection[slot].address, 0, 0, 0);
|
||||
btpad_queue_hci_remote_name_request(g_connected_pads[slot].address, 0, 0, 0);
|
||||
}
|
||||
}
|
||||
else
|
||||
@ -249,12 +253,12 @@ void btpad_packet_handler(uint8_t packet_type, uint16_t channel, uint8_t *packet
|
||||
{
|
||||
ios_add_log_message("BTpad: Got new incoming connection (Slot: %d)", slot);
|
||||
|
||||
memcpy(btpad_connection[slot].address, event_addr, sizeof(bd_addr_t));
|
||||
memcpy(g_connected_pads[slot].address, event_addr, sizeof(bd_addr_t));
|
||||
|
||||
btpad_connection[slot].has_address = true;
|
||||
btpad_connection[slot].handle = handle;
|
||||
btpad_connection[slot].state = BTPAD_CONNECTING;
|
||||
btpad_connection[slot].slot = slot;
|
||||
g_connected_pads[slot].has_address = true;
|
||||
g_connected_pads[slot].handle = handle;
|
||||
g_connected_pads[slot].state = BTPAD_CONNECTING;
|
||||
g_connected_pads[slot].slot = slot;
|
||||
}
|
||||
else break;
|
||||
}
|
||||
@ -277,14 +281,14 @@ void btpad_packet_handler(uint8_t packet_type, uint16_t channel, uint8_t *packet
|
||||
|
||||
ios_add_log_message("BTpad: Got %.200s (Slot: %d)", (char*)&packet[9], slot);
|
||||
if (strncmp((char*)&packet[9], "PLAYSTATION(R)3 Controller", 26) == 0)
|
||||
btpad_iface[slot] = &btpad_ps3;
|
||||
g_connected_pads[slot].interface = &hidpad_ps3;
|
||||
else if (strncmp((char*)&packet[9], "Nintendo RVL-CNT-01", 19) == 0)
|
||||
btpad_iface[slot] = &btpad_wii;
|
||||
g_connected_pads[slot].interface = &hidpad_wii;
|
||||
|
||||
if (btpad_iface[slot])
|
||||
if (g_connected_pads[slot].interface)
|
||||
{
|
||||
btpad_device[slot] = btpad_iface[slot]->connect(&btpad_connection[slot]);
|
||||
btpad_connection[slot].state = BTPAD_CONNECTED;
|
||||
g_connected_pads[slot].hidpad = g_connected_pads[slot].interface->connect(&g_connected_pads[slot], slot);
|
||||
g_connected_pads[slot].state = BTPAD_CONNECTED;
|
||||
}
|
||||
}
|
||||
break;
|
||||
@ -307,7 +311,7 @@ void btpad_packet_handler(uint8_t packet_type, uint16_t channel, uint8_t *packet
|
||||
const int32_t slot = btpad_find_slot_for(handle, 0);
|
||||
if (slot >= 0)
|
||||
{
|
||||
btpad_connection[slot].handle = 0;
|
||||
g_connected_pads[slot].handle = 0;
|
||||
btpad_disconnect_pad(slot);
|
||||
|
||||
ios_add_log_message("BTpad: Device disconnected (Slot: %d)", slot);
|
||||
@ -326,8 +330,14 @@ void btpad_packet_handler(uint8_t packet_type, uint16_t channel, uint8_t *packet
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
else if (packet_type == L2CAP_DATA_PACKET)
|
||||
{
|
||||
for (int i = 0; i < MAX_PADS; i ++)
|
||||
if (btpad_device[i] && btpad_iface[i] && (btpad_connection[i].channels[0] == channel || btpad_connection[i].channels[1] == channel))
|
||||
btpad_iface[i]->packet_handler(btpad_device[i], packet_type, channel, packet, size);
|
||||
{
|
||||
struct hidpad_connection* connection = &g_connected_pads[i];
|
||||
|
||||
if (connection->hidpad && connection->interface && (connection->channels[0] == channel || connection->channels[1] == channel))
|
||||
connection->interface->packet_handler(connection->hidpad, packet, size);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -20,39 +20,4 @@
|
||||
|
||||
void btpad_set_inquiry_state(bool on);
|
||||
|
||||
uint32_t btpad_get_buttons(uint32_t slot);
|
||||
int16_t btpad_get_axis(uint32_t slot, unsigned axis);
|
||||
|
||||
// Private interface
|
||||
enum btpad_state { BTPAD_EMPTY, BTPAD_CONNECTING, BTPAD_CONNECTED };
|
||||
|
||||
typedef struct
|
||||
{
|
||||
enum btpad_state state;
|
||||
|
||||
uint32_t slot;
|
||||
uint16_t handle;
|
||||
|
||||
bool has_address;
|
||||
bd_addr_t address;
|
||||
|
||||
uint16_t channels[2]; //0: Control, 1: Interrupt
|
||||
|
||||
bool connected;
|
||||
} btpad_connection_t;
|
||||
|
||||
struct btpad_interface
|
||||
{
|
||||
void* (*connect)(const btpad_connection_t* connection);
|
||||
void (*disconnect)(void* device);
|
||||
|
||||
uint32_t (*get_buttons)(void* device);
|
||||
int16_t (*get_axis)(void* device, unsigned axis);
|
||||
|
||||
void (*packet_handler)(void* device, uint8_t packet_type, uint16_t channel, uint8_t *packet, uint16_t size);
|
||||
};
|
||||
|
||||
extern struct btpad_interface btpad_ps3;
|
||||
extern struct btpad_interface btpad_wii;
|
||||
|
||||
#endif
|
||||
|
@ -1,123 +0,0 @@
|
||||
/* RetroArch - A frontend for libretro.
|
||||
* Copyright (C) 2013 - Jason Fetters
|
||||
*
|
||||
* 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/>.
|
||||
*/
|
||||
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
#include <stdlib.h>
|
||||
|
||||
#include "boolean.h"
|
||||
#include "apple/common/rarch_wrapper.h"
|
||||
|
||||
#include "btdynamic.h"
|
||||
#include "btpad.h"
|
||||
#include "wiimote.h"
|
||||
|
||||
static void* btpad_wii_connect(const btpad_connection_t* connection)
|
||||
{
|
||||
struct wiimote_t* device = malloc(sizeof(struct wiimote_t));
|
||||
memset(device, 0, sizeof(struct wiimote_t));
|
||||
|
||||
memcpy(device->addr, connection->address, BD_ADDR_LEN);
|
||||
|
||||
device->unid = connection->slot;
|
||||
device->wiiMoteConHandle = connection->handle;
|
||||
device->c_source_cid = connection->channels[0];
|
||||
device->i_source_cid = connection->channels[1];
|
||||
device->state = WIIMOTE_STATE_CONNECTED;
|
||||
device->exp.type = EXP_NONE;
|
||||
|
||||
wiimote_handshake(device, -1, NULL, -1);
|
||||
|
||||
return device;
|
||||
}
|
||||
|
||||
static void btpad_wii_disconnect(struct wiimote_t* device)
|
||||
{
|
||||
}
|
||||
|
||||
static uint32_t btpad_wii_get_buttons(struct wiimote_t* device)
|
||||
{
|
||||
return device->btns | (device->exp.classic.btns << 16);
|
||||
}
|
||||
|
||||
static int16_t btpad_wii_get_axis(struct wiimote_t* device, unsigned axis)
|
||||
{
|
||||
/* TODO
|
||||
if (device->.exp.type == EXP_CLASSIC)
|
||||
{
|
||||
switch (axis)
|
||||
{
|
||||
case 0: return device->wiimote.exp.classic.ljs.rx * 0x7FFF;
|
||||
case 1: return device->wiimote.exp.classic.ljs.ry * 0x7FFF;
|
||||
case 2: return device->wiimote.exp.classic.rjs.rx * 0x7FFF;
|
||||
case 3: return device->wiimote.exp.classic.rjs.ry * 0x7FFF;
|
||||
default: return 0;
|
||||
}
|
||||
}
|
||||
*/
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void btpad_wii_packet_handler(struct wiimote_t* device, uint8_t packet_type, uint16_t channel, uint8_t *packet, uint16_t size)
|
||||
{
|
||||
if(packet_type == L2CAP_DATA_PACKET)
|
||||
{
|
||||
byte* msg = packet + 2;
|
||||
|
||||
switch (packet[1])
|
||||
{
|
||||
case WM_RPT_BTN:
|
||||
{
|
||||
wiimote_pressed_buttons(device, msg);
|
||||
break;
|
||||
}
|
||||
|
||||
case WM_RPT_READ:
|
||||
{
|
||||
wiimote_pressed_buttons(device, msg);
|
||||
wiimote_handshake(device, WM_RPT_READ, msg + 5, ((msg[2] & 0xF0) >> 4) + 1);
|
||||
break;
|
||||
}
|
||||
|
||||
case WM_RPT_CTRL_STATUS:
|
||||
{
|
||||
wiimote_pressed_buttons(device, msg);
|
||||
wiimote_handshake(device,WM_RPT_CTRL_STATUS,msg,-1);
|
||||
break;
|
||||
}
|
||||
|
||||
case WM_RPT_BTN_EXP:
|
||||
{
|
||||
wiimote_pressed_buttons(device, msg);
|
||||
wiimote_handle_expansion(device, msg+2);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
g_current_input_data.pad_buttons[device->unid] = btpad_wii_get_buttons(device);
|
||||
for (int i = 0; i < 4; i ++)
|
||||
g_current_input_data.pad_axis[device->unid][i] = btpad_wii_get_axis(device, i);
|
||||
}
|
||||
}
|
||||
|
||||
struct btpad_interface btpad_wii =
|
||||
{
|
||||
(void*)&btpad_wii_connect,
|
||||
(void*)&btpad_wii_disconnect,
|
||||
(void*)&btpad_wii_get_buttons,
|
||||
(void*)&btpad_wii_get_axis,
|
||||
(void*)&btpad_wii_packet_handler
|
||||
};
|
Loading…
x
Reference in New Issue
Block a user