From fae300aaafef92c2f4da2bdf7e9b7b6ff3b98214 Mon Sep 17 00:00:00 2001 From: meancoot Date: Thu, 3 Oct 2013 17:43:41 -0400 Subject: [PATCH] (Apple) Rework gamepad connection management; fix BTstack support when building with the iOS 7 SDK. --- apple/OSX/hid_pad.c | 70 ++----- apple/common/apple_input.h | 26 ++- apple/common/apple_joypad.c | 73 +++++++- .../hidpad/{hidpad_ps3.c => apple_ps3_pad.c} | 25 +-- .../hidpad/{hidpad_wii.c => apple_wii_pad.c} | 13 +- apple/common/hidpad/hidpad.h | 32 ---- apple/common/hidpad/wiimote.c | 6 +- apple/common/hidpad/wiimote.h | 4 +- apple/iOS/bluetooth/btpad.c | 175 ++++++++---------- apple/iOS/platform.m | 29 +-- 10 files changed, 215 insertions(+), 238 deletions(-) rename apple/common/hidpad/{hidpad_ps3.c => apple_ps3_pad.c} (83%) rename apple/common/hidpad/{hidpad_wii.c => apple_wii_pad.c} (89%) delete mode 100644 apple/common/hidpad/hidpad.h diff --git a/apple/OSX/hid_pad.c b/apple/OSX/hid_pad.c index 4d0b50eb66..0ba9281d5c 100644 --- a/apple/OSX/hid_pad.c +++ b/apple/OSX/hid_pad.c @@ -15,32 +15,25 @@ #include #include "apple/common/apple_input.h" -#include "apple/common/hidpad/hidpad.h" -struct hidpad_connection +struct apple_pad_connection { uint32_t slot; - - struct hidpad_interface* interface; - void* hidpad; - IOHIDDeviceRef device; - uint8_t data[2048]; }; static IOHIDManagerRef g_hid_manager; -static struct hidpad_connection g_connected_pads[MAX_PADS]; -void hidpad_send_control(struct hidpad_connection* connection, uint8_t* data, size_t size) +void apple_pad_send_control(struct apple_pad_connection* connection, uint8_t* data, size_t size) { - IOHIDDeviceSetReport(connection->device, kIOHIDReportTypeOutput, 0x01, data, size); + IOHIDDeviceSetReport(connection->device, kIOHIDReportTypeOutput, 0x01, data + 1, size - 1); } // 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) { - struct hidpad_connection* connection = context; + struct apple_pad_connection* connection = context; IOHIDElementRef element = IOHIDValueGetElement(value); uint32_t type = IOHIDElementGetType(element); @@ -97,16 +90,15 @@ static void hid_device_input_callback(void* context, IOReturn result, void* send static void hid_device_removed(void* context, IOReturn result, void* sender) { - struct hidpad_connection* connection = (struct hidpad_connection*)context; + struct apple_pad_connection* connection = (struct apple_pad_connection*)context; - if (connection && connection->slot < MAX_PADS) + if (connection && connection->slot < MAX_PLAYERS) { 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 (connection->interface) - connection->interface->disconnect(connection->hidpad); - memset(connection, 0, sizeof(*connection)); + apple_joypad_disconnect(connection->slot); + free(connection); } IOHIDDeviceClose(sender, kIOHIDOptionsTypeNone); @@ -114,8 +106,8 @@ static void hid_device_removed(void* context, IOReturn result, void* sender) static void hid_device_report(void* context, IOReturn result, void *sender, IOHIDReportType type, uint32_t reportID, uint8_t *report, CFIndex reportLength) { - struct hidpad_connection* connection = (struct hidpad_connection*)context; - connection->interface->packet_handler(connection->hidpad, report, reportLength); + struct apple_pad_connection* connection = (struct apple_pad_connection*)context; + apple_joypad_packet(connection->slot, connection->data, reportLength + 1); } static void hid_manager_device_attached(void* context, IOReturn result, void* sender, IOHIDDeviceRef device) @@ -123,24 +115,9 @@ static void hid_manager_device_attached(void* context, IOReturn result, void* se 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; - } - } - - if (!connection) - return; - } + struct apple_pad_connection* connection = calloc(1, sizeof(struct apple_pad_connection)); + connection->device = device; + connection->slot = MAX_PLAYERS; IOHIDDeviceOpen(device, kIOHIDOptionsTypeNone); IOHIDDeviceScheduleWithRunLoop(device, CFRunLoopGetCurrent(), kCFRunLoopCommonModes); @@ -149,27 +126,14 @@ static void hid_manager_device_attached(void* context, IOReturn result, void* se 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; - } - } + connection->slot = apple_joypad_connect(buffer, connection); + IOHIDDeviceRegisterInputReportCallback(device, connection->data + 1, sizeof(connection->data) - 1, hid_device_report, connection); } - - IOHIDDeviceRegisterInputValueCallback(device, hid_device_input_callback, connection); + else + IOHIDDeviceRegisterInputValueCallback(device, hid_device_input_callback, connection); } static void append_matching_dictionary(CFMutableArrayRef array, uint32_t page, uint32_t use) diff --git a/apple/common/apple_input.h b/apple/common/apple_input.h index 924faf5e94..0c739484a8 100644 --- a/apple/common/apple_input.h +++ b/apple/common/apple_input.h @@ -16,10 +16,11 @@ #ifndef __APPLE_RARCH_INPUT_H__ #define __APPLE_RARCH_INPUT_H__ +#include "general.h" + // Input responder #define MAX_TOUCHES 16 #define MAX_KEYS 256 -#define MAX_PADS 4 typedef struct { @@ -38,10 +39,28 @@ typedef struct uint32_t keys[MAX_KEYS]; - uint32_t pad_buttons[MAX_PADS]; - int16_t pad_axis[MAX_PADS][4]; + uint32_t pad_buttons[MAX_PLAYERS]; + int16_t pad_axis[MAX_PLAYERS][4]; } apple_input_data_t; +struct apple_pad_connection; +struct apple_pad_interface +{ + void* (*connect)(struct apple_pad_connection* connection, uint32_t slot); + void (*disconnect)(void* device); + void (*packet_handler)(void* device, uint8_t *packet, uint16_t size); +}; + + +// Joypad data +int32_t apple_joypad_connect(const char* name, struct apple_pad_connection* connection); +void apple_joypad_disconnect(uint32_t slot); +void apple_joypad_packet(uint32_t slot, uint8_t* data, uint32_t length); + +// This is implemented in the platform specific portions of the input code +void apple_joypad_send_hid_control(struct apple_pad_connection* connection, uint8_t* data, size_t size); + +// Input data for the main thread and the game thread extern apple_input_data_t g_current_input_data; //< Main thread data extern apple_input_data_t g_polled_input_data; //< Game thread data @@ -51,7 +70,6 @@ uint32_t apple_input_get_icade_buttons(); void apple_input_reset_icade_buttons(); void apple_input_handle_key_event(unsigned keycode, bool down); - extern int32_t apple_input_find_any_key(); extern int32_t apple_input_find_any_button(uint32_t port); extern int32_t apple_input_find_any_axis(uint32_t port); diff --git a/apple/common/apple_joypad.c b/apple/common/apple_joypad.c index 1ae1e247ce..64d9d286ae 100644 --- a/apple/common/apple_joypad.c +++ b/apple/common/apple_joypad.c @@ -25,10 +25,77 @@ #endif #include "apple/common/hidpad/wiimote.c" -#include "apple/common/hidpad/hidpad_ps3.c" -#include "apple/common/hidpad/hidpad_wii.c" +#include "apple/common/hidpad/apple_ps3_pad.c" +#include "apple/common/hidpad/apple_wii_pad.c" + +typedef struct +{ + bool used; + struct apple_pad_interface* iface; + void* data; +} joypad_slot_t; + +static joypad_slot_t slots[MAX_PLAYERS]; + +static int32_t find_empty_slot() +{ + for (int i = 0; i != MAX_PLAYERS; i ++) + if (!slots[i].used) + return i; + return -1; +} + +int32_t apple_joypad_connect(const char* name, struct apple_pad_connection* connection) +{ + int32_t slot = find_empty_slot(); + + if (slot >= 0 && slot < MAX_PLAYERS) + { + joypad_slot_t* s = &slots[slot]; + s->used = true; + + static const struct { const char* name; struct apple_pad_interface* iface; } pad_map[] = { + { "Nintendo RVL-CNT-01", &apple_pad_wii }, + { "PLAYSTATION(R)3 Controller", &apple_pad_ps3 }, + { 0, 0} }; + + for (int i = 0; name && pad_map[i].name; i ++) + if (strstr(name, pad_map[i].name)) + { + s->iface = pad_map[i].iface; + s->data = s->iface->connect(connection, slot); + } + } + + return slot; +} + +void apple_joypad_disconnect(uint32_t slot) +{ + if (slot < MAX_PLAYERS && slots[slot].used) + { + joypad_slot_t* s = &slots[slot]; + + if (s->iface && s->data) + s->iface->disconnect(s->data); + + s->used = false; + } +} + +void apple_joypad_packet(uint32_t slot, uint8_t* data, uint32_t length) +{ + if (slot < MAX_PLAYERS && slots[slot].used) + { + joypad_slot_t* s = &slots[slot]; + + if (s->iface && s->data) + s->iface->packet_handler(s->data, data, length); + } +} +// RetroArch joypad driver: static bool apple_joypad_init(void) { return true; @@ -52,7 +119,7 @@ static bool apple_joypad_button(unsigned port, uint16_t joykey) if (GET_HAT_DIR(joykey)) return false; else // Check the button - return (port < MAX_PADS && joykey < 32) ? (g_polled_input_data.pad_buttons[port] & (1 << joykey)) != 0 : false; + return (port < MAX_PLAYERS && joykey < 32) ? (g_polled_input_data.pad_buttons[port] & (1 << joykey)) != 0 : false; } static int16_t apple_joypad_axis(unsigned port, uint32_t joyaxis) diff --git a/apple/common/hidpad/hidpad_ps3.c b/apple/common/hidpad/apple_ps3_pad.c similarity index 83% rename from apple/common/hidpad/hidpad_ps3.c rename to apple/common/hidpad/apple_ps3_pad.c index d68411269d..1da630a861 100644 --- a/apple/common/hidpad/hidpad_ps3.c +++ b/apple/common/hidpad/apple_ps3_pad.c @@ -18,13 +18,11 @@ #include #include "boolean.h" -#include "apple/common/rarch_wrapper.h" - -#include "hidpad.h" +#include "apple/common/apple_input.h" struct hidpad_ps3_data { - struct hidpad_connection* connection; + struct apple_pad_connection* connection; uint8_t data[512]; @@ -49,24 +47,19 @@ static void hidpad_ps3_send_control(struct hidpad_ps3_data* device) }; report_buffer[11] = 1 << ((device->slot % 4) + 1); -#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 + apple_pad_send_control(device->connection, report_buffer, sizeof(report_buffer)); } -static void* hidpad_ps3_connect(struct hidpad_connection* connection, uint32_t slot) +static void* hidpad_ps3_connect(struct apple_pad_connection* connection, uint32_t slot) { - struct hidpad_ps3_data* device = malloc(sizeof(struct hidpad_ps3_data)); - memset(device, 0, sizeof(*device)); + struct hidpad_ps3_data* device = calloc(1, sizeof(struct hidpad_ps3_data)); device->connection = connection; device->slot = slot; // Magic packet to start reports #ifdef IOS static uint8_t data[] = {0x53, 0xF4, 0x42, 0x03, 0x00, 0x00}; - hidpad_send_control(device->connection, data, 6); + apple_pad_send_control(device->connection, data, 6); #endif // Without this the digital buttons won't be reported @@ -122,18 +115,14 @@ static void hidpad_ps3_packet_handler(struct hidpad_ps3_data* device, uint8_t *p device->have_led = true; } -#ifdef IOS memcpy(device->data, packet, size); -#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] = hidpad_ps3_get_axis(device, i); } -struct hidpad_interface hidpad_ps3 = +struct apple_pad_interface apple_pad_ps3 = { (void*)&hidpad_ps3_connect, (void*)&hidpad_ps3_disconnect, diff --git a/apple/common/hidpad/hidpad_wii.c b/apple/common/hidpad/apple_wii_pad.c similarity index 89% rename from apple/common/hidpad/hidpad_wii.c rename to apple/common/hidpad/apple_wii_pad.c index 5d54bd4860..5215db83ad 100644 --- a/apple/common/hidpad/hidpad_wii.c +++ b/apple/common/hidpad/apple_wii_pad.c @@ -21,12 +21,10 @@ #include "apple/common/rarch_wrapper.h" #include "wiimote.h" -#include "hidpad.h" -static void* hidpad_wii_connect(struct hidpad_connection* connection, uint32_t slot) +static void* hidpad_wii_connect(struct apple_pad_connection* connection, uint32_t slot) { - struct wiimote_t* device = malloc(sizeof(struct wiimote_t)); - memset(device, 0, sizeof(struct wiimote_t)); + struct wiimote_t* device = calloc(1, sizeof(struct wiimote_t)); device->connection = connection; device->unid = slot; @@ -64,13 +62,8 @@ static int16_t hidpad_wii_get_axis(struct wiimote_t* device, unsigned axis) 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: { @@ -105,7 +98,7 @@ static void hidpad_wii_packet_handler(struct wiimote_t* device, uint8_t *packet, g_current_input_data.pad_axis[device->unid][i] = hidpad_wii_get_axis(device, i); } -struct hidpad_interface hidpad_wii = +struct apple_pad_interface apple_pad_wii = { (void*)&hidpad_wii_connect, (void*)&hidpad_wii_disconnect, diff --git a/apple/common/hidpad/hidpad.h b/apple/common/hidpad/hidpad.h deleted file mode 100644 index 4002c8d060..0000000000 --- a/apple/common/hidpad/hidpad.h +++ /dev/null @@ -1,32 +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 . - */ - -#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 diff --git a/apple/common/hidpad/wiimote.c b/apple/common/hidpad/wiimote.c index 35dadfa65a..b55f16079f 100644 --- a/apple/common/hidpad/wiimote.c +++ b/apple/common/hidpad/wiimote.c @@ -358,11 +358,7 @@ int wiimote_send(struct wiimote_t* wm, byte report_type, byte* msg, int len) printf("\n"); #endif -#ifdef IOS - hidpad_send_control(wm->connection, buf, len + 2); -#else - hidpad_send_control(wm->connection, buf + 1, len + 1); -#endif + apple_pad_send_control(wm->connection, buf, len + 2); return 1; } diff --git a/apple/common/hidpad/wiimote.h b/apple/common/hidpad/wiimote.h index c2d985f52e..6e6ac1be56 100644 --- a/apple/common/hidpad/wiimote.h +++ b/apple/common/hidpad/wiimote.h @@ -41,8 +41,6 @@ #ifndef __WIIMOTE_H__ #define __WIIMOTE_H__ -#include "hidpad.h" - #if defined(__cplusplus) extern "C" { #endif @@ -232,7 +230,7 @@ extern "C" { typedef struct wiimote_t { int unid; /**< user specified id */ - struct hidpad_connection* connection; + struct apple_pad_connection* connection; int state; /**< various state flags */ byte leds; /**< currently lit leds */ float battery_level; /**< battery level */ diff --git a/apple/iOS/bluetooth/btpad.c b/apple/iOS/bluetooth/btpad.c index abb6333ded..12525b353f 100644 --- a/apple/iOS/bluetooth/btpad.c +++ b/apple/iOS/bluetooth/btpad.c @@ -21,7 +21,6 @@ #include #include "apple/common/rarch_wrapper.h" -#include "apple/common/hidpad/hidpad.h" #include "btdynamic.h" #include "btpad.h" #include "btpad_queue.h" @@ -29,13 +28,10 @@ // Private interface enum btpad_state { BTPAD_EMPTY, BTPAD_CONNECTING, BTPAD_CONNECTED }; -struct hidpad_connection +struct apple_pad_connection { uint32_t slot; - struct hidpad_interface* interface; - void* hidpad; - enum btpad_state state; bool has_address; @@ -45,9 +41,9 @@ struct hidpad_connection uint16_t channels[2]; //0: Control, 1: Interrupt }; -static struct hidpad_connection g_connected_pads[MAX_PADS]; +static struct apple_pad_connection g_connections[MAX_PLAYERS]; -void hidpad_send_control(struct hidpad_connection* connection, uint8_t* data, size_t size) +void apple_pad_send_control(struct apple_pad_connection* connection, uint8_t* data, size_t size) { bt_send_l2cap_ptr(connection->channels[0], data, size); } @@ -66,55 +62,46 @@ void btpad_set_inquiry_state(bool on) } // Internal interface: -static int32_t btpad_find_slot_for(uint16_t handle, bd_addr_t address) +static struct apple_pad_connection* btpad_find_empty_connection() { - for (int i = 0; i < MAX_PADS; i ++) + for (int i = 0; i != MAX_PLAYERS; i ++) + if (g_connections[i].state == BTPAD_EMPTY) + return &g_connections[i]; + + return 0; +} + +static struct apple_pad_connection* btpad_find_connection_for(uint16_t handle, bd_addr_t address) +{ + for (int i = 0; i < MAX_PLAYERS; i ++) { - if (!g_connected_pads[i].handle && !g_connected_pads[i].has_address) + if (!g_connections[i].handle && !g_connections[i].has_address) continue; - if (handle && g_connected_pads[i].handle && handle != g_connected_pads[i].handle) + if (handle && g_connections[i].handle && handle != g_connections[i].handle) continue; - if (address && g_connected_pads[i].has_address && (BD_ADDR_CMP(address, g_connected_pads[i].address))) + if (address && g_connections[i].has_address && (BD_ADDR_CMP(address, g_connections[i].address))) continue; - return i; + return &g_connections[i]; } - return -1; + return 0; } -static int32_t btpad_find_slot_with_state(enum btpad_state state) +static void btpad_close_connection(struct apple_pad_connection* connection) { - for (int i = 0; i < MAX_PADS; i ++) - if (g_connected_pads[i].state == state) - return i; + if (connection->handle) + btpad_queue_hci_disconnect(connection->handle, 0x15); - return -1; + memset(connection, 0, sizeof(struct apple_pad_connection)); } -static void btpad_disconnect_pad(uint32_t slot) +static void btpad_close_all_connections() { - if (slot > MAX_PADS) - return; - - if (g_connected_pads[slot].interface && g_connected_pads[slot].hidpad) - { - ios_add_log_message("BTpad: Disconnecting slot %d", slot); - g_connected_pads[slot].interface->disconnect(g_connected_pads[slot].hidpad); - } - - if (g_connected_pads[slot].handle) - btpad_queue_hci_disconnect(g_connected_pads[slot].handle, 0x15); - - memset(&g_connected_pads[slot], 0, sizeof(struct hidpad_connection)); -} - -static void btpad_disconnect_all_pads() -{ - for (int i = 0; i < MAX_PADS; i ++) - btpad_disconnect_pad(i); + for (int i = 0; i < MAX_PLAYERS; i ++) + btpad_close_connection(&g_connections[i]); } void btpad_packet_handler(uint8_t packet_type, uint16_t channel, uint8_t *packet, uint16_t size) @@ -140,7 +127,7 @@ void btpad_packet_handler(uint8_t packet_type, uint16_t channel, uint8_t *packet } else if(packet[2] > HCI_STATE_WORKING) { - btpad_disconnect_all_pads(); + btpad_close_all_connections(); } } break; @@ -170,19 +157,18 @@ void btpad_packet_handler(uint8_t packet_type, uint16_t channel, uint8_t *packet { bt_flip_addr_ptr(event_addr, &packet[3]); - const int32_t slot = btpad_find_slot_with_state(BTPAD_EMPTY); - if (slot >= 0) + struct apple_pad_connection* connection = btpad_find_empty_connection(); + if (connection) { - ios_add_log_message("BTpad: Inquiry found device (Slot %d)", slot); + ios_add_log_message("BTpad: Inquiry found device"); + memset(connection, 0, sizeof(struct apple_pad_connection)); - memcpy(g_connected_pads[slot].address, event_addr, sizeof(bd_addr_t)); + memcpy(connection->address, event_addr, sizeof(bd_addr_t)); + connection->has_address = true; + connection->state = BTPAD_CONNECTING; - 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, g_connected_pads[slot].address, PSM_HID_CONTROL); - bt_send_cmd_ptr(l2cap_create_channel_ptr, g_connected_pads[slot].address, PSM_HID_INTERRUPT); + bt_send_cmd_ptr(l2cap_create_channel_ptr, connection->address, PSM_HID_CONTROL); + bt_send_cmd_ptr(l2cap_create_channel_ptr, connection->address, PSM_HID_INTERRUPT); } } } @@ -190,8 +176,7 @@ void btpad_packet_handler(uint8_t packet_type, uint16_t channel, uint8_t *packet case HCI_EVENT_INQUIRY_COMPLETE: { - // TODO: Check performance and battery effect of this - + // This must be turned off during gameplay as it causes a ton of lag inquiry_running = !inquiry_off; if (inquiry_running) @@ -206,34 +191,34 @@ void btpad_packet_handler(uint8_t packet_type, uint16_t channel, uint8_t *packet const uint16_t psm = READ_BT_16(packet, 11); const uint16_t channel_id = READ_BT_16(packet, 13); - const int32_t slot = btpad_find_slot_for(handle, event_addr); + struct apple_pad_connection* connection = btpad_find_connection_for(handle, event_addr); if (!packet[2]) { - if (slot < 0) + if (!connection) { ios_add_log_message("BTpad: Got L2CAP 'Channel Opened' event for unrecognized device"); break; } - ios_add_log_message("BTpad: L2CAP channel opened: (Slot: %d, PSM: %02X)", slot, psm); - g_connected_pads[slot].handle = handle; + ios_add_log_message("BTpad: L2CAP channel opened: (PSM: %02X)", psm); + connection->handle = handle; if (psm == PSM_HID_CONTROL) - g_connected_pads[slot].channels[0] = channel_id; + connection->channels[0] = channel_id; else if (psm == PSM_HID_INTERRUPT) - g_connected_pads[slot].channels[1] = channel_id; + connection->channels[1] = channel_id; else - ios_add_log_message("BTpad: Got unknown L2CAP PSM, ignoring (Slot: %d, PSM: %02X)", slot, psm); + ios_add_log_message("BTpad: Got unknown L2CAP PSM, ignoring (PSM: %02X)", psm); - if (g_connected_pads[slot].channels[0] && g_connected_pads[slot].channels[1]) + if (connection->channels[0] && connection->channels[1]) { - ios_add_log_message("BTpad: Got both L2CAP channels, requesting name (Slot: %d)", slot); - btpad_queue_hci_remote_name_request(g_connected_pads[slot].address, 0, 0, 0); + ios_add_log_message("BTpad: Got both L2CAP channels, requesting name"); + btpad_queue_hci_remote_name_request(connection->address, 0, 0, 0); } } else - ios_add_log_message("BTpad: Got failed L2CAP 'Channel Opened' event (Slot %d, PSM: %02X, Status: %02X)", -1, psm, packet[2]); + ios_add_log_message("BTpad: Got failed L2CAP 'Channel Opened' event (PSM: %02X, Status: %02X)", psm, packet[2]); } break; @@ -244,26 +229,26 @@ void btpad_packet_handler(uint8_t packet_type, uint16_t channel, uint8_t *packet const uint32_t psm = READ_BT_16(packet, 10); const uint32_t channel_id = READ_BT_16(packet, 12); - int32_t slot = btpad_find_slot_for(handle, event_addr); - if (slot < 0) + struct apple_pad_connection* connection = btpad_find_connection_for(handle, event_addr); + + if (!connection) { - slot = btpad_find_slot_with_state(BTPAD_EMPTY); - - if (slot >= 0) + connection = btpad_find_empty_connection(); + if (connection) { - ios_add_log_message("BTpad: Got new incoming connection (Slot: %d)", slot); + ios_add_log_message("BTpad: Got new incoming connection"); - memcpy(g_connected_pads[slot].address, event_addr, sizeof(bd_addr_t)); + memset(connection, 0, sizeof(struct apple_pad_connection)); - 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; + memcpy(connection->address, event_addr, sizeof(bd_addr_t)); + connection->has_address = true; + connection->handle = handle; + connection->state = BTPAD_CONNECTING; } else break; } - ios_add_log_message("BTpad: Incoming L2CAP connection (Slot: %d, PSM: %02X)", slot, psm); + ios_add_log_message("BTpad: Incoming L2CAP connection (PSM: %02X)", psm); bt_send_cmd_ptr(l2cap_accept_connection_ptr, channel_id); } break; @@ -271,25 +256,19 @@ void btpad_packet_handler(uint8_t packet_type, uint16_t channel, uint8_t *packet case HCI_EVENT_REMOTE_NAME_REQUEST_COMPLETE: { bt_flip_addr_ptr(event_addr, &packet[3]); + + struct apple_pad_connection* connection = btpad_find_connection_for(0, event_addr); - const int32_t slot = btpad_find_slot_for(0, event_addr); - if (slot < 0) + if (!connection) { ios_add_log_message("BTpad: Got unexpected remote name, ignoring"); break; } - ios_add_log_message("BTpad: Got %.200s (Slot: %d)", (char*)&packet[9], slot); - if (strncmp((char*)&packet[9], "PLAYSTATION(R)3 Controller", 26) == 0) - g_connected_pads[slot].interface = &hidpad_ps3; - else if (strncmp((char*)&packet[9], "Nintendo RVL-CNT-01", 19) == 0) - g_connected_pads[slot].interface = &hidpad_wii; - - if (g_connected_pads[slot].interface) - { - g_connected_pads[slot].hidpad = g_connected_pads[slot].interface->connect(&g_connected_pads[slot], slot); - g_connected_pads[slot].state = BTPAD_CONNECTED; - } + ios_add_log_message("BTpad: Got %.200s", (char*)&packet[9]); + + connection->slot = apple_joypad_connect((char*)packet + 9, connection); + connection->state = BTPAD_CONNECTED; } break; @@ -308,13 +287,13 @@ void btpad_packet_handler(uint8_t packet_type, uint16_t channel, uint8_t *packet if (!packet[2]) { - const int32_t slot = btpad_find_slot_for(handle, 0); - if (slot >= 0) + struct apple_pad_connection* connection = btpad_find_connection_for(handle, 0); + if (connection) { - g_connected_pads[slot].handle = 0; - btpad_disconnect_pad(slot); - - ios_add_log_message("BTpad: Device disconnected (Slot: %d)", slot); + connection->handle = 0; + + apple_joypad_disconnect(connection->slot); + btpad_close_connection(connection); } } else @@ -332,12 +311,12 @@ void btpad_packet_handler(uint8_t packet_type, uint16_t channel, uint8_t *packet } else if (packet_type == L2CAP_DATA_PACKET) { - for (int i = 0; i < MAX_PADS; i ++) + for (int i = 0; i < MAX_PLAYERS; i ++) { - struct hidpad_connection* connection = &g_connected_pads[i]; + struct apple_pad_connection* connection = &g_connections[i]; - if (connection->hidpad && connection->interface && (connection->channels[0] == channel || connection->channels[1] == channel)) - connection->interface->packet_handler(connection->hidpad, packet, size); + if (connection->state == BTPAD_CONNECTED && (connection->channels[0] == channel || connection->channels[1] == channel)) + apple_joypad_packet(connection->slot, packet, size); } } } diff --git a/apple/iOS/platform.m b/apple/iOS/platform.m index 73811fccac..e0088772dd 100644 --- a/apple/iOS/platform.m +++ b/apple/iOS/platform.m @@ -29,23 +29,28 @@ #include "file.h" //#define HAVE_DEBUG_FILELOG -void ios_set_bluetooth_mode(NSString* mode) -{ -#ifndef __IPHONE_7_0 // iOS7 iCade Support - apple_input_enable_icade([mode isEqualToString:@"icade"]); - btstack_set_poweron([mode isEqualToString:@"btstack"]); -#else - bool enabled = [mode isEqualToString:@"icade"]; - apple_input_enable_icade(enabled); - [[RAGameView get] iOS7SetiCadeMode:enabled]; -#endif -} - bool is_ios_7() { return [[UIDevice currentDevice].systemVersion compare:@"7.0" options:NSNumericSearch] != NSOrderedAscending; } +void ios_set_bluetooth_mode(NSString* mode) +{ + if (!is_ios_7()) + { + apple_input_enable_icade([mode isEqualToString:@"icade"]); + btstack_set_poweron([mode isEqualToString:@"btstack"]); + } +#ifdef __IPHONE_7_0 // iOS7 iCade Support + else + { + bool enabled = [mode isEqualToString:@"icade"]; + apple_input_enable_icade(enabled); + [[RAGameView get] iOS7SetiCadeMode:enabled]; + } +#endif +} + // Input helpers: This is kept here because it needs objective-c static void handle_touch_event(NSArray* touches) {