diff --git a/apple/common/setting_data.c b/apple/common/setting_data.c
index 6866b44a28..1a1c07a095 100644
--- a/apple/common/setting_data.c
+++ b/apple/common/setting_data.c
@@ -120,6 +120,9 @@ void setting_data_reset_setting(const rarch_setting_t* setting)
default: break;
}
+
+ if (setting->change_handler)
+ setting->change_handler(setting);
}
void setting_data_reset(const rarch_setting_t* settings)
@@ -284,6 +287,9 @@ void setting_data_set_with_string_representation(const rarch_setting_t* setting,
default: return;
}
+
+ if (setting->change_handler)
+ setting->change_handler(setting);
}
const char* setting_data_get_string_representation(const rarch_setting_t* setting, char* buffer, size_t length)
diff --git a/apple/common/setting_data.h b/apple/common/setting_data.h
index 3364693f28..cd2dfc3a84 100644
--- a/apple/common/setting_data.h
+++ b/apple/common/setting_data.h
@@ -41,7 +41,7 @@ enum setting_flags
SD_FLAG_HAS_RANGE = 16
};
-typedef struct
+typedef struct rarch_setting_t
{
enum setting_type type;
@@ -58,6 +58,8 @@ typedef struct
const char* values;
uint64_t flags;
+ void (*change_handler)(const struct rarch_setting_t* setting);
+
union
{
bool boolean;
diff --git a/apple/iOS/bluetooth/btdynamic.c b/apple/iOS/bluetooth/btdynamic.c
index 3dd455543b..8ac9c78888 100644
--- a/apple/iOS/bluetooth/btdynamic.c
+++ b/apple/iOS/bluetooth/btdynamic.c
@@ -12,6 +12,7 @@
* You should have received a copy of the GNU General Public License along with RetroArch.
* If not, see .
*/
+#include
#include
#include
#include
@@ -30,6 +31,7 @@ static struct
} grabbers[] =
{
GRAB(bt_open),
+ GRAB(bt_close),
GRAB(bt_flip_addr),
GRAB(bd_addr_to_str),
GRAB(bt_register_packet_handler),
@@ -61,8 +63,9 @@ extern void btpad_packet_handler(uint8_t packet_type, uint16_t channel, uint8_t
static bool btstack_tested;
static bool btstack_loaded;
-static bool btstack_open;
-static bool btstack_poweron;
+
+static pthread_t btstack_thread;
+static CFRunLoopSourceRef btstack_quit_source;
bool btstack_try_load()
{
@@ -108,28 +111,54 @@ bool btstack_try_load()
return true;
}
+void btstack_thread_stop()
+{
+ bt_send_cmd_ptr(btstack_set_power_mode_ptr, HCI_POWER_OFF);
+}
+
+static void* btstack_thread_func(void* data)
+{
+ RARCH_LOG("BTstack: Thread started");
+
+ if (bt_open_ptr())
+ {
+ RARCH_LOG("BTstack: bt_open() failed\n");
+ return 0;
+ }
+
+ CFRunLoopSourceContext ctx = { 0, 0, 0, 0, 0, 0, 0, 0, 0, btstack_thread_stop };
+ btstack_quit_source = CFRunLoopSourceCreate(0, 0, &ctx);
+ CFRunLoopAddSource(CFRunLoopGetCurrent(), btstack_quit_source, kCFRunLoopCommonModes);
+
+ RARCH_LOG("BTstack: Turning on\n");
+ bt_send_cmd_ptr(btstack_set_power_mode_ptr, HCI_POWER_ON);
+
+ RARCH_LOG("BTstack: Running\n");
+ CFRunLoopRun();
+
+ RARCH_LOG("BTstack: Done\n");
+
+ CFRunLoopSourceInvalidate(btstack_quit_source);
+ CFRelease(btstack_quit_source);
+ return 0;
+}
+
void btstack_set_poweron(bool on)
{
if (!btstack_try_load())
return;
- if (!btstack_open && bt_open_ptr())
+ if (on && !btstack_thread)
+ pthread_create(&btstack_thread, 0, btstack_thread_func, 0);
+ else if (!on && btstack_thread && btstack_quit_source)
{
- RARCH_LOG("BTstack: bt_open failed\n");
- btstack_loaded = false;
- return;
+ CFRunLoopSourceSignal(btstack_quit_source);
+ pthread_join(btstack_thread, 0);
+ btstack_thread = 0;
}
-
- btstack_open = true;
- if (on != btstack_poweron)
- {
- btstack_poweron = on;
- RARCH_LOG("BTstack: Turning %s\n", on ? "on" : "off");
- bt_send_cmd_ptr(btstack_set_power_mode_ptr, on ? HCI_POWER_ON : HCI_POWER_OFF);
- }
}
bool btstack_is_running()
{
- return btstack_poweron;
+ return btstack_thread;
}
diff --git a/apple/iOS/bluetooth/btdynamic.h b/apple/iOS/bluetooth/btdynamic.h
index 324c90976a..7a24cbffe1 100644
--- a/apple/iOS/bluetooth/btdynamic.h
+++ b/apple/iOS/bluetooth/btdynamic.h
@@ -31,6 +31,7 @@ bool btstack_is_running();
#endif
BTDIMPORT int (*bt_open_ptr)(void);
+BTDIMPORT void (*bt_close_ptr)(void);
BTDIMPORT void (*bt_flip_addr_ptr)(bd_addr_t dest, bd_addr_t src);
BTDIMPORT char* (*bd_addr_to_str_ptr)(bd_addr_t addr);
BTDIMPORT btstack_packet_handler_t (*bt_register_packet_handler_ptr)(btstack_packet_handler_t handler);
diff --git a/apple/iOS/bluetooth/btpad.c b/apple/iOS/bluetooth/btpad.c
index c2ac281e55..b1fc84a14c 100644
--- a/apple/iOS/bluetooth/btpad.c
+++ b/apple/iOS/bluetooth/btpad.c
@@ -114,20 +114,25 @@ void btpad_packet_handler(uint8_t packet_type, uint16_t channel, uint8_t *packet
{
case BTSTACK_EVENT_STATE:
{
- if (packet[2] == HCI_STATE_WORKING)
- {
- btpad_queue_reset();
+ RARCH_LOG("BTstack: HCI State %d\n", packet[2]);
+
+ switch (packet[2])
+ {
+ case HCI_STATE_WORKING:
+ btpad_queue_reset();
- btpad_queue_hci_read_bd_addr();
- bt_send_cmd_ptr(l2cap_register_service_ptr, PSM_HID_CONTROL, 672); // TODO: Where did I get 672 for mtu?
- bt_send_cmd_ptr(l2cap_register_service_ptr, PSM_HID_INTERRUPT, 672);
- btpad_queue_hci_inquiry(HCI_INQUIRY_LAP, 3, 1);
+ btpad_queue_hci_read_bd_addr();
+ bt_send_cmd_ptr(l2cap_register_service_ptr, PSM_HID_CONTROL, 672); // TODO: Where did I get 672 for mtu?
+ bt_send_cmd_ptr(l2cap_register_service_ptr, PSM_HID_INTERRUPT, 672);
+ btpad_queue_hci_inquiry(HCI_INQUIRY_LAP, 3, 1);
- btpad_queue_run(1);
- }
- else if(packet[2] > HCI_STATE_WORKING)
- {
- btpad_close_all_connections();
+ btpad_queue_run(1);
+ break;
+
+ case HCI_STATE_HALTING:
+ btpad_close_all_connections();
+ CFRunLoopStop(CFRunLoopGetCurrent());
+ break;
}
}
break;
@@ -303,7 +308,7 @@ void btpad_packet_handler(uint8_t packet_type, uint16_t channel, uint8_t *packet
case L2CAP_EVENT_SERVICE_REGISTERED:
{
- if (!packet[2])
+ if (packet[2])
RARCH_LOG("BTpad: Got failed 'Service Registered' event (PSM: %02X, Status: %02X)\n", READ_BT_16(packet, 3), packet[2]);
}
break;
diff --git a/apple/iOS/menu.m b/apple/iOS/menu.m
index c04cb7718f..a48c423186 100644
--- a/apple/iOS/menu.m
+++ b/apple/iOS/menu.m
@@ -391,6 +391,8 @@ static void RunActionSheet(const char* title, const struct string_list* items, U
- (void)wasSelectedOnTableView:(UITableView*)tableView ofController:(UIViewController*)controller
{
+ RAMenuItemEnumSetting __weak* weakSelf = self;
+
struct string_list* items = string_split(self.setting->values, "|");
RunActionSheet(self.setting->short_description, items, self.parentTable,
^(UIActionSheet* actionSheet, NSInteger buttonIndex)
@@ -398,7 +400,7 @@ static void RunActionSheet(const char* title, const struct string_list* items, U
if (buttonIndex != actionSheet.cancelButtonIndex)
{
setting_data_set_with_string_representation(self.setting, [[actionSheet buttonTitleAtIndex:buttonIndex] UTF8String]);
- [self.parentTable reloadData];
+ [weakSelf.parentTable reloadData];
}
});
string_list_free(items);
diff --git a/apple/iOS/platform.m b/apple/iOS/platform.m
index ee9ef28ab7..1a6ecdf744 100644
--- a/apple/iOS/platform.m
+++ b/apple/iOS/platform.m
@@ -32,7 +32,6 @@
apple_frontend_settings_t apple_frontend_settings;
-#ifdef IOS
int get_ios_version_major(void)
{
static int version = -1;
@@ -48,7 +47,11 @@ void ios_set_bluetooth_mode(NSString* mode)
apple_input_enable_icade([mode isEqualToString:@"icade"]);
btstack_set_poweron([mode isEqualToString:@"btstack"]);
}
-#endif
+
+static void apple_refresh_frontend_config(const rarch_setting_t* setting)
+{
+ [[RetroArch_iOS get] refreshSystemConfig];
+}
const void* apple_get_frontend_settings(void)
{
@@ -60,9 +63,11 @@ const void* apple_get_frontend_settings(void)
settings[1] = setting_data_group_setting(ST_SUB_GROUP, "Frontend");
settings[2] = setting_data_bool_setting("ios_use_file_log", "Enable File Logging",
&apple_frontend_settings.logging_enabled, false);
+ settings[2].change_handler = apple_refresh_frontend_config;
settings[3] = setting_data_bool_setting("ios_tv_mode", "TV Mode", &apple_use_tv_mode, false);
settings[4] = setting_data_string_setting(ST_STRING, "ios_btmode", "Bluetooth Input Type", apple_frontend_settings.bluetooth_mode,
sizeof(apple_frontend_settings.bluetooth_mode), "none");
+ settings[4].change_handler = apple_refresh_frontend_config;
// Set ios_btmode options based on runtime environment
if (btstack_try_load())