mirror of
https://github.com/libretro/RetroArch
synced 2025-02-06 18:40:49 +00:00
(iOS) Move BTstack into a thread. It may still need synchronization with the input buffers, but shouldn't cause crashes or anything.
This commit is contained in:
parent
e3b4cb9a2d
commit
a7497ab416
@ -74,7 +74,6 @@
|
||||
966B9C9A16E418B7005B61E1 /* utils.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = utils.h; sourceTree = "<group>"; };
|
||||
966B9C9E16E418B7005B61E1 /* wiimote.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = wiimote.c; sourceTree = "<group>"; };
|
||||
966B9C9F16E418B7005B61E1 /* wiimote.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = wiimote.h; sourceTree = "<group>"; };
|
||||
966B9CA016E418B7005B61E1 /* WiiMoteHelper.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = WiiMoteHelper.h; sourceTree = "<group>"; };
|
||||
966B9CA116E418B7005B61E1 /* WiiMoteHelper.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = WiiMoteHelper.m; sourceTree = "<group>"; };
|
||||
966B9CA916E41C07005B61E1 /* browser.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = browser.h; sourceTree = "<group>"; };
|
||||
966B9CAA16E41C07005B61E1 /* browser.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = browser.m; sourceTree = "<group>"; };
|
||||
@ -157,7 +156,6 @@
|
||||
966B9C9416E418B7005B61E1 /* btstack */,
|
||||
966B9C9E16E418B7005B61E1 /* wiimote.c */,
|
||||
966B9C9F16E418B7005B61E1 /* wiimote.h */,
|
||||
966B9CA016E418B7005B61E1 /* WiiMoteHelper.h */,
|
||||
966B9CA116E418B7005B61E1 /* WiiMoteHelper.m */,
|
||||
);
|
||||
path = BTStack;
|
||||
|
@ -19,7 +19,7 @@
|
||||
#import "browser/browser.h"
|
||||
#import "settings/settings.h"
|
||||
|
||||
#import "input/BTStack/WiiMoteHelper.h"
|
||||
#include "input/BTstack/btdynamic.h"
|
||||
|
||||
#define kDOCSFOLDER [NSHomeDirectory() stringByAppendingPathComponent:@"Documents"]
|
||||
|
||||
@ -274,9 +274,9 @@
|
||||
#pragma mark Bluetooth Helpers
|
||||
- (UIBarButtonItem*)createBluetoothButton
|
||||
{
|
||||
if ([WiiMoteHelper haveBluetooth])
|
||||
if (btstack_is_loaded())
|
||||
{
|
||||
const bool isBTOn = [WiiMoteHelper isBluetoothRunning];
|
||||
const bool isBTOn = btstack_is_running();
|
||||
return [[UIBarButtonItem alloc]
|
||||
initWithTitle:isBTOn ? @"Stop Bluetooth" : @"Start Bluetooth"
|
||||
style:UIBarButtonItemStyleBordered
|
||||
@ -289,18 +289,18 @@
|
||||
|
||||
- (IBAction)startBluetooth
|
||||
{
|
||||
if ([WiiMoteHelper haveBluetooth])
|
||||
if (btstack_is_loaded())
|
||||
{
|
||||
[WiiMoteHelper startBluetooth];
|
||||
btstack_start();
|
||||
[self.topViewController.navigationItem setRightBarButtonItem:[self createBluetoothButton] animated:YES];
|
||||
}
|
||||
}
|
||||
|
||||
- (IBAction)stopBluetooth
|
||||
{
|
||||
if ([WiiMoteHelper haveBluetooth])
|
||||
if (btstack_is_loaded())
|
||||
{
|
||||
[WiiMoteHelper stopBluetooth];
|
||||
btstack_stop();
|
||||
[self.topViewController.navigationItem setRightBarButtonItem:[self createBluetoothButton] animated:YES];
|
||||
}
|
||||
}
|
||||
|
@ -1,40 +0,0 @@
|
||||
/*
|
||||
* This file is part of MAME4iOS.
|
||||
*
|
||||
* Copyright (C) 2012 David Valdeita (Seleuco)
|
||||
*
|
||||
* 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.
|
||||
*
|
||||
* 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.
|
||||
*/
|
||||
|
||||
|
||||
#import <UIKit/UIKit.h>
|
||||
|
||||
@interface WiiMoteHelper : NSObject
|
||||
+ (BOOL)haveBluetooth;
|
||||
+ (void)startBluetooth;
|
||||
+ (BOOL)isBluetoothRunning;
|
||||
+ (void)stopBluetooth;
|
||||
@end
|
||||
|
@ -39,10 +39,6 @@
|
||||
|
||||
#import "BTDevice.h"
|
||||
|
||||
static WiiMoteHelper* instance;
|
||||
static bool btstackOpen;
|
||||
static bool btOK;
|
||||
|
||||
static BTDevice* discoveredDevice;
|
||||
static bd_addr_t address;
|
||||
static uint32_t handle[2];
|
||||
@ -50,7 +46,27 @@ static uint32_t remote_cid[2];
|
||||
static uint32_t local_cid[2];
|
||||
uint8_t psdata_buffer[512];
|
||||
|
||||
void packet_handler(uint8_t packet_type, uint16_t channel, uint8_t *packet, uint16_t size)
|
||||
static void set_ps3_data(unsigned leds)
|
||||
{
|
||||
// TODO: LEDS
|
||||
|
||||
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
|
||||
};
|
||||
|
||||
bt_send_l2cap_ptr(local_cid[0], report_buffer, sizeof(report_buffer));
|
||||
}
|
||||
|
||||
|
||||
void btstack_packet_handler(uint8_t packet_type, uint16_t channel, uint8_t *packet, uint16_t size)
|
||||
{
|
||||
#if 1 // WiiMote
|
||||
bd_addr_t event_addr;
|
||||
@ -303,62 +319,3 @@ void packet_handler(uint8_t packet_type, uint16_t channel, uint8_t *packet, uint
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
@implementation WiiMoteHelper
|
||||
+ (BOOL)haveBluetooth
|
||||
{
|
||||
if (!btstackOpen)
|
||||
{
|
||||
btstackOpen = load_btstack();
|
||||
|
||||
if (btstackOpen)
|
||||
{
|
||||
run_loop_init_ptr(RUN_LOOP_COCOA);
|
||||
bt_register_packet_handler_ptr(packet_handler);
|
||||
}
|
||||
}
|
||||
|
||||
return btstackOpen;
|
||||
}
|
||||
|
||||
+ (void)startBluetooth
|
||||
{
|
||||
if (btstackOpen)
|
||||
{
|
||||
instance = instance ? instance : [WiiMoteHelper new];
|
||||
|
||||
if (!btOK)
|
||||
{
|
||||
if (bt_open_ptr())
|
||||
{
|
||||
btOK = false;
|
||||
return;
|
||||
}
|
||||
|
||||
bt_send_cmd_ptr(btstack_set_power_mode_ptr, HCI_POWER_ON);
|
||||
|
||||
btOK = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
+ (BOOL)isBluetoothRunning
|
||||
{
|
||||
return btstackOpen && btOK;
|
||||
}
|
||||
|
||||
+ (void)stopBluetooth
|
||||
{
|
||||
if (btstackOpen)
|
||||
{
|
||||
myosd_num_of_joys = 0;
|
||||
|
||||
if (btOK)
|
||||
bt_send_cmd_ptr(btstack_set_power_mode_ptr, HCI_POWER_OFF);
|
||||
|
||||
btOK = false;
|
||||
instance = nil;
|
||||
}
|
||||
}
|
||||
|
||||
@end
|
||||
|
@ -15,13 +15,12 @@
|
||||
#include <stdio.h>
|
||||
#include <assert.h>
|
||||
#include <dlfcn.h>
|
||||
#include <pthread.h>
|
||||
#include <CoreFoundation/CFRunLoop.h>
|
||||
|
||||
#define BUILDING_BTDYNAMIC
|
||||
#include "btdynamic.h"
|
||||
|
||||
static bool bt_tested;
|
||||
static bool bt_is_loaded;
|
||||
|
||||
#define GRAB(A) {#A, (void**)&A##_ptr}
|
||||
static struct
|
||||
{
|
||||
@ -35,6 +34,7 @@ static struct
|
||||
GRAB(bt_send_cmd),
|
||||
GRAB(bt_send_l2cap),
|
||||
GRAB(run_loop_init),
|
||||
GRAB(run_loop_execute),
|
||||
GRAB(btstack_get_system_bluetooth_enabled),
|
||||
GRAB(btstack_set_power_mode),
|
||||
GRAB(btstack_set_system_bluetooth_enabled),
|
||||
@ -52,14 +52,47 @@ static struct
|
||||
{0, 0}
|
||||
};
|
||||
|
||||
bool load_btstack()
|
||||
extern void btstack_packet_handler(uint8_t packet_type, uint16_t channel, uint8_t *packet, uint16_t size);
|
||||
|
||||
static pthread_t btstack_thread;
|
||||
static bool btstack_tested;
|
||||
static bool btstack_loaded;
|
||||
|
||||
// TODO: This may need to be synchronized, but an extra iterate on the bluetooth thread won't kill anybody.
|
||||
static volatile bool btstack_terminate = true;
|
||||
|
||||
static void* btstack_thread_function(void* data)
|
||||
{
|
||||
bt_register_packet_handler_ptr(btstack_packet_handler);
|
||||
|
||||
static bool btstack_running = false;
|
||||
if (!btstack_running)
|
||||
btstack_running = bt_open_ptr() ? false : true;
|
||||
|
||||
if (btstack_running)
|
||||
{
|
||||
bt_send_cmd_ptr(btstack_set_power_mode_ptr, HCI_POWER_ON);
|
||||
|
||||
// Loop
|
||||
while (!btstack_terminate && kCFRunLoopRunTimedOut == CFRunLoopRunInMode(kCFRunLoopDefaultMode, 1, false));
|
||||
|
||||
bt_send_cmd_ptr(btstack_set_power_mode_ptr, HCI_POWER_OFF);
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
bool btstack_load()
|
||||
{
|
||||
assert(sizeof(void**) == sizeof(void(*)));
|
||||
assert(sizeof(void**) == sizeof(void(*)()));
|
||||
|
||||
if (bt_tested)
|
||||
return bt_is_loaded;
|
||||
if (btstack_tested)
|
||||
return btstack_loaded;
|
||||
|
||||
btstack_tested = true;
|
||||
btstack_loaded = false;
|
||||
|
||||
bt_tested = true;
|
||||
void* btstack = dlopen("/usr/lib/libBTstack.dylib", RTLD_LAZY);
|
||||
|
||||
if (!btstack)
|
||||
@ -76,5 +109,38 @@ bool load_btstack()
|
||||
}
|
||||
}
|
||||
|
||||
run_loop_init_ptr(RUN_LOOP_COCOA);
|
||||
|
||||
btstack_loaded = true;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
void btstack_start()
|
||||
{
|
||||
if (btstack_terminate)
|
||||
{
|
||||
btstack_terminate = false;
|
||||
pthread_create(&btstack_thread, NULL, btstack_thread_function, 0);
|
||||
}
|
||||
}
|
||||
|
||||
void btstack_stop()
|
||||
{
|
||||
if (!btstack_terminate)
|
||||
{
|
||||
btstack_terminate = true;
|
||||
pthread_join(btstack_thread, 0);
|
||||
}
|
||||
}
|
||||
|
||||
bool btstack_is_loaded()
|
||||
{
|
||||
return btstack_load();
|
||||
}
|
||||
|
||||
bool btstack_is_running()
|
||||
{
|
||||
return !btstack_terminate;
|
||||
}
|
||||
|
||||
|
@ -19,20 +19,25 @@
|
||||
#include "btstack/utils.h"
|
||||
#include "btstack/btstack.h"
|
||||
|
||||
bool btstack_load();
|
||||
void btstack_start();
|
||||
void btstack_stop();
|
||||
bool btstack_is_loaded();
|
||||
bool btstack_is_running();
|
||||
|
||||
#ifndef BUILDING_BTDYNAMIC
|
||||
#define BTDIMPORT extern
|
||||
#else
|
||||
#define BTDIMPORT
|
||||
#endif
|
||||
|
||||
bool load_btstack();
|
||||
|
||||
BTDIMPORT int (*bt_open_ptr)(void);
|
||||
BTDIMPORT void (*bt_flip_addr_ptr)(bd_addr_t dest, bd_addr_t src);
|
||||
BTDIMPORT btstack_packet_handler_t (*bt_register_packet_handler_ptr)(btstack_packet_handler_t handler);
|
||||
BTDIMPORT int (*bt_send_cmd_ptr)(const hci_cmd_t *cmd, ...);
|
||||
BTDIMPORT void (*bt_send_l2cap_ptr)(uint16_t local_cid, uint8_t *data, uint16_t len);
|
||||
BTDIMPORT void (*run_loop_init_ptr)(RUN_LOOP_TYPE type);
|
||||
BTDIMPORT void (*run_loop_execute_ptr)();
|
||||
|
||||
BTDIMPORT const hci_cmd_t* btstack_get_system_bluetooth_enabled_ptr;
|
||||
BTDIMPORT const hci_cmd_t* btstack_set_power_mode_ptr;
|
||||
|
Loading…
x
Reference in New Issue
Block a user