mirror of
https://github.com/CTCaer/RetroArch.git
synced 2024-12-14 06:18:34 +00:00
(iOS, BTstack) More refactoring; Now have to choose the type of pad to connect (annoying, but there's no other way the code gets stable)
This commit is contained in:
parent
b4721106f6
commit
bb4b254be7
@ -247,6 +247,8 @@ INPUT
|
||||
#include "../ios/RetroArch/input/BTStack/btdynamic.c"
|
||||
#include "../ios/RetroArch/input/BTStack/wiimote.c"
|
||||
#include "../ios/RetroArch/input/BTStack/btpad.c"
|
||||
#include "../ios/RetroArch/input/BTStack/btpad_ps3.c"
|
||||
#include "../ios/RetroArch/input/BTStack/btpad_wii.c"
|
||||
#elif defined(__BLACKBERRY_QNX__)
|
||||
#include "../playbook/qnx_input.c"
|
||||
#endif
|
||||
|
@ -44,6 +44,8 @@
|
||||
/* End PBXBuildFile section */
|
||||
|
||||
/* Begin PBXFileReference section */
|
||||
960356BC1700652C008F55DA /* btpad_ps3.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = btpad_ps3.c; sourceTree = "<group>"; };
|
||||
960356BD1700652C008F55DA /* btpad_wii.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = btpad_wii.c; sourceTree = "<group>"; };
|
||||
96096DD716D1ABAF00BF4499 /* RAModuleInfoList.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = RAModuleInfoList.m; sourceTree = "<group>"; };
|
||||
9614C71F16DDC018000B36EF /* RetroArch copy-Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; name = "RetroArch copy-Info.plist"; path = "/Users/jason/Documents/Projects/ios/RetroArch/ios/RetroArch copy-Info.plist"; sourceTree = "<absolute>"; };
|
||||
962979F416C43B9500E6DCE0 /* ic_dir.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; name = ic_dir.png; path = "../../android/phoenix/res/drawable-xhdpi/ic_dir.png"; sourceTree = "<group>"; };
|
||||
@ -156,6 +158,8 @@
|
||||
children = (
|
||||
966B9C9416E418B7005B61E1 /* btstack */,
|
||||
966B9CA116E418B7005B61E1 /* btpad.c */,
|
||||
960356BC1700652C008F55DA /* btpad_ps3.c */,
|
||||
960356BD1700652C008F55DA /* btpad_wii.c */,
|
||||
96F9C27B16FF66BC002455B3 /* btpad.h */,
|
||||
96F9C27516FF5E97002455B3 /* btdynamic.c */,
|
||||
96F9C27616FF5E97002455B3 /* btdynamic.h */,
|
||||
|
@ -15,7 +15,7 @@
|
||||
|
||||
#import <UIKit/UIKit.h>
|
||||
|
||||
@interface RetroArch_iOS : UINavigationController<UIApplicationDelegate, UINavigationControllerDelegate>
|
||||
@interface RetroArch_iOS : UINavigationController<UIApplicationDelegate, UINavigationControllerDelegate, UIAlertViewDelegate>
|
||||
|
||||
+ (void)displayErrorMessage:(NSString*)message;
|
||||
|
||||
|
@ -19,7 +19,8 @@
|
||||
#import "browser/browser.h"
|
||||
#import "settings/settings.h"
|
||||
|
||||
#include "input/BTstack/btdynamic.h"
|
||||
#include "input/BTStack/btdynamic.h"
|
||||
#include "input/BTStack/btpad.h"
|
||||
|
||||
#define kDOCSFOLDER [NSHomeDirectory() stringByAppendingPathComponent:@"Documents"]
|
||||
|
||||
@ -291,6 +292,21 @@
|
||||
{
|
||||
if (btstack_is_loaded())
|
||||
{
|
||||
UIAlertView* alert = [[UIAlertView alloc] initWithTitle:@"RetroArch"
|
||||
message:@"Choose Pad Type"
|
||||
delegate:self
|
||||
cancelButtonTitle:nil
|
||||
otherButtonTitles:@"Wii", @"PS3", nil];
|
||||
[alert show];
|
||||
}
|
||||
}
|
||||
|
||||
- (void)alertView:(UIAlertView *)alertView clickedButtonAtIndex:(NSInteger)buttonIndex
|
||||
{
|
||||
if (btstack_is_loaded())
|
||||
{
|
||||
btpad_set_pad_type(buttonIndex == 0);
|
||||
|
||||
btstack_start();
|
||||
[self.topViewController.navigationItem setRightBarButtonItem:[self createBluetoothButton] animated:YES];
|
||||
}
|
||||
|
@ -41,6 +41,7 @@ static struct
|
||||
GRAB(btstack_set_power_mode),
|
||||
GRAB(btstack_set_system_bluetooth_enabled),
|
||||
GRAB(hci_delete_stored_link_key),
|
||||
GRAB(hci_disconnect),
|
||||
GRAB(hci_inquiry),
|
||||
GRAB(hci_inquiry_cancel),
|
||||
GRAB(hci_pin_code_request_reply),
|
||||
@ -56,7 +57,7 @@ static struct
|
||||
{0, 0}
|
||||
};
|
||||
|
||||
extern void btstack_packet_handler(uint8_t packet_type, uint16_t channel, uint8_t *packet, uint16_t size);
|
||||
extern void btpad_packet_handler(uint8_t packet_type, uint16_t channel, uint8_t *packet, uint16_t size);
|
||||
|
||||
static pthread_t btstack_thread;
|
||||
static bool btstack_tested;
|
||||
@ -70,7 +71,7 @@ static void* btstack_thread_function(void* data)
|
||||
ios_add_log_message("BTstack: Thread Initializing");
|
||||
|
||||
run_loop_init_ptr(RUN_LOOP_COCOA);
|
||||
bt_register_packet_handler_ptr(btstack_packet_handler);
|
||||
bt_register_packet_handler_ptr(btpad_packet_handler);
|
||||
|
||||
if (bt_open_ptr())
|
||||
{
|
||||
@ -140,6 +141,9 @@ bool btstack_load()
|
||||
|
||||
void btstack_start()
|
||||
{
|
||||
if (!btstack_load())
|
||||
return;
|
||||
|
||||
static bool thread_started = false;
|
||||
if (!thread_started)
|
||||
{
|
||||
@ -157,6 +161,9 @@ void btstack_start()
|
||||
|
||||
void btstack_stop()
|
||||
{
|
||||
if (!btstack_load())
|
||||
return;
|
||||
|
||||
if (btstack_poweron)
|
||||
{
|
||||
ios_add_log_message("BTstack: Clearing poweron flag");
|
||||
|
@ -44,6 +44,7 @@ BTDIMPORT const hci_cmd_t* btstack_get_system_bluetooth_enabled_ptr;
|
||||
BTDIMPORT const hci_cmd_t* btstack_set_power_mode_ptr;
|
||||
BTDIMPORT const hci_cmd_t* btstack_set_system_bluetooth_enabled_ptr;
|
||||
BTDIMPORT const hci_cmd_t* hci_delete_stored_link_key_ptr;
|
||||
BTDIMPORT const hci_cmd_t* hci_disconnect_ptr;
|
||||
BTDIMPORT const hci_cmd_t* hci_inquiry_ptr;
|
||||
BTDIMPORT const hci_cmd_t* hci_inquiry_cancel_ptr;
|
||||
BTDIMPORT const hci_cmd_t* hci_pin_code_request_reply_ptr;
|
||||
|
@ -1,31 +1,16 @@
|
||||
/*
|
||||
* This file is part of MAME4iOS.
|
||||
/* RetroArch - A frontend for libretro.
|
||||
* Copyright (C) 2013 - Jason Fetters
|
||||
*
|
||||
* Copyright (C) 2012 David Valdeita (Seleuco)
|
||||
* 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.
|
||||
*
|
||||
* This program 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 Foundation; either version 2 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.
|
||||
*
|
||||
* This program 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 this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
|
||||
*
|
||||
* In addition, as a special exception, Seleuco
|
||||
* gives permission to link the code of this program with
|
||||
* the MAME library (or with modified versions of MAME that use the
|
||||
* same license as MAME), and distribute linked combinations including
|
||||
* the two. You must obey the GNU General Public License in all
|
||||
* respects for all of the code used other than MAME. If you modify
|
||||
* this file, you may extend this exception to your version of the
|
||||
* file, but you are not obligated to do so. If you do not wish to
|
||||
* do so, delete this exception statement from your version.
|
||||
* You should have received a copy of the GNU General Public License along with RetroArch.
|
||||
* If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#include <sys/types.h>
|
||||
@ -38,392 +23,71 @@
|
||||
#include "btpad.h"
|
||||
#include "wiimote.h"
|
||||
|
||||
enum btpad_state_t { BTPAD_NOT_INITIALIZED, BTPAD_NO_CONNECTION, BTPAD_INQUIRY_CONNECTION, BTPAD_CONNECTION, BTPAD_WANT_NAME, BTPAD_CONNECTED };
|
||||
static enum btpad_state_t btpad_state = BTPAD_NOT_INITIALIZED;
|
||||
|
||||
static enum btpad_device_type_t device_type;
|
||||
static bd_addr_t device_address;
|
||||
static char device_name[256];
|
||||
|
||||
// Connection data
|
||||
static uint32_t device_handle[2];
|
||||
static uint32_t device_remote_cid[2];
|
||||
static uint32_t device_local_cid[2];
|
||||
|
||||
// Inquiry data
|
||||
static uint32_t device_page_scan_repetition_mode;
|
||||
static uint32_t device_class;
|
||||
static uint32_t device_clock_offset;
|
||||
|
||||
// Buffers
|
||||
static struct wiimote_t wiimote_buffer;
|
||||
static uint8_t psdata_buffer[512];
|
||||
static struct btpad_interface* btpad_iface;
|
||||
static void* btpad_device;
|
||||
static bool btpad_want_wiimote;
|
||||
static pthread_mutex_t btpad_lock = PTHREAD_MUTEX_INITIALIZER;
|
||||
|
||||
// MAIN THREAD ONLY
|
||||
enum btpad_device_type_t btpad_get_connected_type()
|
||||
{
|
||||
return device_type;
|
||||
}
|
||||
|
||||
uint32_t btpad_get_buttons()
|
||||
{
|
||||
switch (device_type)
|
||||
{
|
||||
case BTPAD_WIIMOTE:
|
||||
return wiimote_buffer.btns | (wiimote_buffer.exp.classic.btns << 16);
|
||||
case BTPAD_PS3:
|
||||
return psdata_buffer[3] | (psdata_buffer[4] << 8);
|
||||
default:
|
||||
return 0;
|
||||
}
|
||||
pthread_mutex_lock(&btpad_lock);
|
||||
uint32_t result = (btpad_device && btpad_iface) ? btpad_iface->get_buttons(btpad_device) : 0;
|
||||
pthread_mutex_unlock(&btpad_lock);
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
void btpad_set_pad_type(bool wiimote)
|
||||
{
|
||||
pthread_mutex_lock(&btpad_lock);
|
||||
btpad_want_wiimote = wiimote;
|
||||
pthread_mutex_unlock(&btpad_lock);
|
||||
}
|
||||
|
||||
// BT THREAD ONLY
|
||||
static void set_ps3_data(unsigned leds)
|
||||
static void btpad_connect_pad(bool wiimote)
|
||||
{
|
||||
// TODO: LEDS
|
||||
pthread_mutex_lock(&btpad_lock);
|
||||
|
||||
static uint8_t report_buffer[] = {
|
||||
0x52, 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
|
||||
};
|
||||
ios_add_log_message("BTpad: Connecting to %s", wiimote ? "WiiMote" : "PS3");
|
||||
|
||||
bt_send_l2cap_ptr(device_local_cid[0], report_buffer, sizeof(report_buffer));
|
||||
btpad_iface = (wiimote) ? &btpad_wii : &btpad_ps3;
|
||||
btpad_device = btpad_iface->connect();
|
||||
|
||||
pthread_mutex_unlock(&btpad_lock);
|
||||
}
|
||||
|
||||
static bool btstack_read_incoming_connection_packet(uint8_t* packet, uint16_t size)
|
||||
static void btpad_disconnect_pad()
|
||||
{
|
||||
const uint32_t psm = READ_BT_16(packet, 10);
|
||||
const unsigned interrupt = (psm == PSM_HID_INTERRUPT) ? 1 : 0;
|
||||
pthread_mutex_lock(&btpad_lock);
|
||||
|
||||
bt_flip_addr_ptr(device_address, &packet[2]);
|
||||
device_handle[interrupt] = READ_BT_16(packet, 8);
|
||||
device_local_cid[interrupt] = READ_BT_16(packet, 12);
|
||||
device_remote_cid[interrupt] = READ_BT_16(packet, 14);
|
||||
|
||||
return interrupt;
|
||||
}
|
||||
|
||||
static void btstack_not_initialized_handler(uint8_t* packet, uint16_t size)
|
||||
{
|
||||
switch (packet[0])
|
||||
if (btpad_iface && btpad_device)
|
||||
{
|
||||
case BTSTACK_EVENT_STATE:
|
||||
ios_add_log_message("BTpad: Disconnecting");
|
||||
|
||||
btpad_iface->disconnect(btpad_device);
|
||||
btpad_device = 0;
|
||||
btpad_iface = 0;
|
||||
}
|
||||
|
||||
pthread_mutex_unlock(&btpad_lock);
|
||||
}
|
||||
|
||||
void btpad_packet_handler(uint8_t packet_type, uint16_t channel, uint8_t *packet, uint16_t size)
|
||||
{
|
||||
if (packet_type == HCI_EVENT_PACKET && packet[0] == BTSTACK_EVENT_STATE)
|
||||
{
|
||||
if (packet[2] == HCI_STATE_WORKING)
|
||||
{
|
||||
ios_add_log_message("BTstack: Power state now HCI_STATE_WORKING");
|
||||
ios_add_log_message("BTstack: Registering HID INTERRUPT service");
|
||||
bt_send_cmd_ptr(l2cap_register_service_ptr, PSM_HID_INTERRUPT, 672);
|
||||
}
|
||||
else
|
||||
ios_add_log_message("BTstack: State is now %d", packet[2]);
|
||||
break;
|
||||
btpad_connect_pad(btpad_want_wiimote);
|
||||
else if(packet[2] > HCI_STATE_WORKING && btpad_iface && btpad_device)
|
||||
btpad_disconnect_pad();
|
||||
}
|
||||
|
||||
case L2CAP_EVENT_SERVICE_REGISTERED:
|
||||
if (btpad_device && btpad_iface)
|
||||
{
|
||||
if (READ_BT_16(packet, 3) == PSM_HID_INTERRUPT)
|
||||
{
|
||||
ios_add_log_message("BTstack: HID INTERRUPT service registered");
|
||||
ios_add_log_message("BTstack: Registering HID CONTROL service");
|
||||
bt_send_cmd_ptr(l2cap_register_service_ptr, PSM_HID_CONTROL, 672);
|
||||
}
|
||||
else if(READ_BT_16(packet, 3) == PSM_HID_CONTROL)
|
||||
{
|
||||
ios_add_log_message("BTstack: HID CONTROL service registered");
|
||||
|
||||
ios_add_log_message("BTstack: Waiting for connection");
|
||||
bt_send_cmd_ptr(hci_inquiry_ptr, HCI_INQUIRY_LAP, 3, 0);
|
||||
btpad_state = BTPAD_NO_CONNECTION;
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static void btstack_no_connection_handler(uint8_t* packet, uint16_t size)
|
||||
{
|
||||
switch (packet[0])
|
||||
{
|
||||
// Device is connecting to iOS
|
||||
case L2CAP_EVENT_INCOMING_CONNECTION:
|
||||
{
|
||||
ios_add_log_message("BTstack: Incoming L2CAP connection (PS3 Pad?)");
|
||||
|
||||
btpad_state = BTPAD_CONNECTION;
|
||||
|
||||
bool ch = btstack_read_incoming_connection_packet(packet, size);
|
||||
bt_send_cmd_ptr(l2cap_accept_connection_ptr, device_local_cid[ch ? 1 : 0]);
|
||||
|
||||
break;
|
||||
}
|
||||
|
||||
// iOS is connecting to device
|
||||
// Here we just copy the details of the first device found
|
||||
case HCI_EVENT_INQUIRY_RESULT:
|
||||
{
|
||||
ios_add_log_message("BTstack: Inquiry found device (WiiMote?)");
|
||||
|
||||
if (packet[2])
|
||||
{
|
||||
btpad_state = BTPAD_INQUIRY_CONNECTION;
|
||||
|
||||
bt_flip_addr_ptr(device_address, &packet[3]);
|
||||
device_page_scan_repetition_mode = packet [3 + packet[2] * (6)];
|
||||
device_class = READ_BT_24(packet, 3 + packet[2] * (6+1+1+1));
|
||||
device_clock_offset = READ_BT_16(packet, 3 + packet[2] * (6+1+1+1+3)) & 0x7fff;
|
||||
}
|
||||
|
||||
break;
|
||||
}
|
||||
|
||||
case HCI_EVENT_INQUIRY_COMPLETE:
|
||||
{
|
||||
bt_send_cmd_ptr(hci_inquiry_ptr, HCI_INQUIRY_LAP, 3, 0);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static void btstack_connection_handler(uint8_t* packet, uint16_t size)
|
||||
{
|
||||
switch (packet[0])
|
||||
{
|
||||
case L2CAP_EVENT_INCOMING_CONNECTION:
|
||||
{
|
||||
ios_add_log_message("BTstack: Got other half L2CAP connection; requesting name\n");
|
||||
|
||||
btpad_state = BTPAD_WANT_NAME;
|
||||
|
||||
bool ch = btstack_read_incoming_connection_packet(packet, size);
|
||||
bt_send_cmd_ptr(l2cap_accept_connection_ptr, device_local_cid[ch ? 1 : 0]);
|
||||
bt_send_cmd_ptr(hci_remote_name_request_ptr, device_address, 0, 0, 0);
|
||||
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static void btstack_inquiry_connection_handler(uint8_t* packet, uint16_t size)
|
||||
{
|
||||
switch (packet[0])
|
||||
{
|
||||
case HCI_EVENT_INQUIRY_COMPLETE:
|
||||
{
|
||||
ios_add_log_message("BTstack: Got inquiry complete; requesting name\n");
|
||||
|
||||
btpad_state = BTPAD_WANT_NAME;
|
||||
bt_send_cmd_ptr(hci_remote_name_request_ptr, device_address, device_page_scan_repetition_mode,
|
||||
0, device_clock_offset | 0x8000);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static void btstack_want_name_handler(uint8_t* packet, uint16_t size)
|
||||
{
|
||||
bd_addr_t event_addr;
|
||||
|
||||
switch (packet[0])
|
||||
{
|
||||
case HCI_EVENT_REMOTE_NAME_REQUEST_COMPLETE:
|
||||
{
|
||||
bt_flip_addr_ptr(event_addr, &packet[3]);
|
||||
|
||||
if (BD_ADDR_CMP(event_addr, device_address) == 0)
|
||||
{
|
||||
strncpy(device_name, (const char*)&packet[9], 248);
|
||||
device_name[248] = 0;
|
||||
|
||||
ios_add_log_message("BTstack: Got device name: %s\n", device_name);
|
||||
|
||||
if (strncmp(device_name, "Nintendo RVL-CNT-01", 19) == 0)
|
||||
{
|
||||
ios_add_log_message("BTstack: Got WiiMote\n");
|
||||
btpad_state = BTPAD_CONNECTED;
|
||||
device_type = BTPAD_WIIMOTE;
|
||||
bt_send_cmd_ptr(l2cap_create_channel_ptr, device_address, PSM_HID_CONTROL);
|
||||
}
|
||||
else if(strncmp(device_name, "PLAYSTATION(R)3 Controller", 26) == 0)
|
||||
{
|
||||
ios_add_log_message("BTstack: Got PS3 Pad; Sending startup packets\n");
|
||||
|
||||
btpad_state = BTPAD_CONNECTED;
|
||||
device_type = BTPAD_PS3;
|
||||
|
||||
// Special packet to tell PS3 controller to send reports
|
||||
uint8_t data[] = {0x53, 0xF4, 0x42, 0x03, 0x00, 0x00};
|
||||
bt_send_l2cap_ptr(device_local_cid[0], data, 6);
|
||||
set_ps3_data(0);
|
||||
}
|
||||
else
|
||||
{
|
||||
ios_add_log_message("BTstack: Unrecognized device; Will keep looking");
|
||||
btpad_state = BTPAD_NO_CONNECTION;
|
||||
}
|
||||
}
|
||||
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static void btstack_ps3_handler(uint8_t packet_type, uint16_t channel, uint8_t *packet, uint16_t size)
|
||||
{
|
||||
if (packet_type == L2CAP_DATA_PACKET && packet[0] == 0xA1)
|
||||
{
|
||||
static bool tag = false;
|
||||
if(!tag) ios_add_log_message("BTstack: Got PS3 Data Packet (Will only show once)\n");
|
||||
tag = true;
|
||||
|
||||
memcpy(psdata_buffer, packet, size);
|
||||
}
|
||||
}
|
||||
|
||||
static void btstack_wiimote_handler(uint8_t packet_type, uint16_t channel, uint8_t *packet, uint16_t size)
|
||||
{
|
||||
bd_addr_t event_addr;
|
||||
|
||||
if (packet_type == HCI_EVENT_PACKET && packet[0] == L2CAP_EVENT_CHANNEL_OPENED)
|
||||
{
|
||||
bt_flip_addr_ptr(event_addr, &packet[3]);
|
||||
const uint16_t psm = READ_BT_16(packet, 11);
|
||||
|
||||
if (packet[2] == 0 && BD_ADDR_CMP(event_addr, device_address) == 0)
|
||||
{
|
||||
ios_add_log_message("BTstack: WiiMote L2CAP channel openend: %02X\n", psm);
|
||||
|
||||
const unsigned interrupt = (psm == PSM_HID_INTERRUPT) ? 1 : 0;
|
||||
|
||||
device_local_cid[interrupt] = READ_BT_16(packet, 13);
|
||||
device_remote_cid[interrupt] = READ_BT_16(packet, 15);
|
||||
device_handle[interrupt] = READ_BT_16(packet, 9);
|
||||
|
||||
if (psm == PSM_HID_CONTROL)
|
||||
{
|
||||
bt_send_cmd_ptr(l2cap_create_channel_ptr, device_address, PSM_HID_INTERRUPT);
|
||||
|
||||
memset(&wiimote_buffer, 0, sizeof(struct wiimote_t));
|
||||
wiimote_buffer.unid = 0;
|
||||
wiimote_buffer.c_source_cid = device_local_cid[0];
|
||||
wiimote_buffer.exp.type = EXP_NONE;
|
||||
wiimote_buffer.wiiMoteConHandle = device_handle[0];
|
||||
memcpy(&wiimote_buffer.addr, &device_address, BD_ADDR_LEN);
|
||||
}
|
||||
else if (psm == PSM_HID_INTERRUPT)
|
||||
{
|
||||
wiimote_buffer.i_source_cid = device_local_cid[1];
|
||||
wiimote_buffer.state = WIIMOTE_STATE_CONNECTED;
|
||||
wiimote_handshake(&wiimote_buffer, -1, NULL, -1);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
ios_add_log_message("BTstack: Failed to open WiiMote L2CAP channel: %d", psm);
|
||||
ios_add_log_message("BTstack: Won't recover, please exit RetroArch from the task switcher");
|
||||
}
|
||||
}
|
||||
else if(packet_type == L2CAP_DATA_PACKET)
|
||||
{
|
||||
static bool tag = false;
|
||||
if(!tag) ios_add_log_message("BTstack: Got Wii Data Packet (Will only show once)\n");
|
||||
tag = true;
|
||||
|
||||
byte* msg = packet + 2;
|
||||
|
||||
switch (packet[1])
|
||||
{
|
||||
case WM_RPT_BTN:
|
||||
{
|
||||
wiimote_pressed_buttons(&wiimote_buffer, msg);
|
||||
break;
|
||||
}
|
||||
|
||||
case WM_RPT_READ:
|
||||
{
|
||||
wiimote_pressed_buttons(&wiimote_buffer, msg);
|
||||
|
||||
byte len = ((msg[2] & 0xF0) >> 4) + 1;
|
||||
byte *data = (msg + 5);
|
||||
|
||||
wiimote_handshake(&wiimote_buffer, WM_RPT_READ, data, len);
|
||||
return;
|
||||
}
|
||||
|
||||
case WM_RPT_CTRL_STATUS:
|
||||
{
|
||||
wiimote_pressed_buttons(&wiimote_buffer, msg);
|
||||
wiimote_handshake(&wiimote_buffer,WM_RPT_CTRL_STATUS,msg,-1);
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
case WM_RPT_BTN_EXP:
|
||||
{
|
||||
wiimote_pressed_buttons(&wiimote_buffer, msg);
|
||||
wiimote_handle_expansion(&wiimote_buffer, msg+2);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void btstack_packet_handler(uint8_t packet_type, uint16_t channel, uint8_t *packet, uint16_t size)
|
||||
{
|
||||
typedef void (*handler_t)(uint8_t*, uint16_t);
|
||||
static handler_t const handlers[] =
|
||||
{
|
||||
&btstack_not_initialized_handler,
|
||||
&btstack_no_connection_handler,
|
||||
&btstack_inquiry_connection_handler,
|
||||
&btstack_connection_handler,
|
||||
&btstack_want_name_handler
|
||||
};
|
||||
|
||||
if (packet_type == HCI_EVENT_PACKET && btpad_state <= BTPAD_WANT_NAME)
|
||||
{
|
||||
handlers[(unsigned)btpad_state](packet, size);
|
||||
}
|
||||
else if (btpad_state == BTPAD_CONNECTED)
|
||||
{
|
||||
if (device_type == BTPAD_PS3)
|
||||
btstack_ps3_handler(packet_type, channel, packet, size);
|
||||
else if(device_type == BTPAD_WIIMOTE)
|
||||
btstack_wiimote_handler(packet_type, channel, packet, size);
|
||||
}
|
||||
|
||||
if (packet_type == HCI_EVENT_PACKET)
|
||||
{
|
||||
bd_addr_t event_addr;
|
||||
|
||||
switch (packet[0])
|
||||
{
|
||||
// This PIN will work for Wiimotes, other devices with PINs aren't supported
|
||||
case HCI_EVENT_PIN_CODE_REQUEST:
|
||||
ios_add_log_message("BTstack: Sending PIN (will fail if device isn't WiiMote");
|
||||
|
||||
bt_flip_addr_ptr(event_addr, &packet[2]);
|
||||
bt_send_cmd_ptr(hci_pin_code_request_reply_ptr, device_address, 6, &packet[2]);
|
||||
break;
|
||||
|
||||
case L2CAP_EVENT_CHANNEL_CLOSED:
|
||||
ios_add_log_message("BTstack: Lost L2CAP connection; will start searching for new device");
|
||||
|
||||
btpad_state = BTPAD_NO_CONNECTION;
|
||||
device_type = BTPAD_NONE;
|
||||
|
||||
bt_send_cmd_ptr(hci_inquiry_ptr, HCI_INQUIRY_LAP, 3, 0);
|
||||
|
||||
break;
|
||||
}
|
||||
pthread_mutex_lock(&btpad_lock);
|
||||
btpad_iface->packet_handler(btpad_device, packet_type, channel, packet, size);
|
||||
pthread_mutex_unlock(&btpad_lock);
|
||||
}
|
||||
}
|
||||
|
@ -16,9 +16,22 @@
|
||||
#ifndef __IOS_RARCH_BTPAD_H__
|
||||
#define __IOS_RARCH_BTPAD_H__
|
||||
|
||||
enum btpad_device_type_t { BTPAD_NONE, BTPAD_PENDING, BTPAD_WIIMOTE, BTPAD_PS3 };
|
||||
|
||||
enum btpad_device_type_t btpad_get_connected_type();
|
||||
uint32_t btpad_get_buttons();
|
||||
void btpad_set_pad_type(bool wiimote);
|
||||
|
||||
// Private interface
|
||||
struct btpad_interface
|
||||
{
|
||||
void* (*connect)();
|
||||
void (*disconnect)(void* device);
|
||||
void (*set_leds)(void* device, unsigned leds);
|
||||
|
||||
uint32_t (*get_buttons)(void* device);
|
||||
|
||||
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
|
||||
|
Loading…
Reference in New Issue
Block a user