diff --git a/frontend/drivers/platform_darwin.m b/frontend/drivers/platform_darwin.m index 4068fabcab..6c1b3dfdf1 100644 --- a/frontend/drivers/platform_darwin.m +++ b/frontend/drivers/platform_darwin.m @@ -736,6 +736,17 @@ static int frontend_darwin_parse_drive_list(void *data, bool load_content) FILE_TYPE_DIRECTORY, 0, 0, NULL); string_list_free(str_list); +#if TARGET_OS_IOS + if ( filebrowser_get_type() == FILEBROWSER_NONE || + filebrowser_get_type() == FILEBROWSER_SCAN_FILE || + filebrowser_get_type() == FILEBROWSER_SELECT_FILE) + menu_entries_append(list, + msg_hash_to_str(MENU_ENUM_LABEL_VALUE_FILE_BROWSER_OPEN_PICKER), + msg_hash_to_str(MENU_ENUM_LABEL_FILE_BROWSER_OPEN_PICKER), + MENU_ENUM_LABEL_FILE_BROWSER_OPEN_PICKER, + MENU_SETTING_ACTION, 0, 0, NULL); +#endif + ret = 0; #endif #endif diff --git a/griffin/griffin_objc.m b/griffin/griffin_objc.m index ec64a64803..df04871935 100644 --- a/griffin/griffin_objc.m +++ b/griffin/griffin_objc.m @@ -23,6 +23,10 @@ #define __IPHONE_OS_VERSION_MAX_ALLOWED 00000 #endif +#if defined(HAVE_ZLIB) || defined(HAVE_7ZIP) +#define HAVE_COMPRESSION 1 +#endif + #if defined(__APPLE__) && defined(__MACH__) #include "../frontend/drivers/platform_darwin.m" #endif diff --git a/menu/cbs/menu_cbs_deferred_push.c b/menu/cbs/menu_cbs_deferred_push.c index 932a74518e..f66510b0f9 100644 --- a/menu/cbs/menu_cbs_deferred_push.c +++ b/menu/cbs/menu_cbs_deferred_push.c @@ -430,14 +430,21 @@ static int general_push(menu_displaylist_info_t *info, /* Need to use the scratch buffer here */ char tmp_str[PATH_MAX_LENGTH]; #if IOS - char tmp_path[PATH_MAX_LENGTH]; - fill_pathname_expand_special(tmp_path, menu->scratch2_buf, sizeof(tmp_path)); - const char *menu_path = tmp_path; + if (path_is_absolute(menu->scratch_buf)) + strlcpy(tmp_str, menu->scratch_buf, sizeof(tmp_str)); + else + { + char tmp_path[PATH_MAX_LENGTH]; + fill_pathname_expand_special(tmp_path, menu->scratch2_buf, sizeof(tmp_path)); + const char *menu_path = tmp_path; + fill_pathname_join_special(tmp_str, menu_path, + menu->scratch_buf, sizeof(tmp_str)); + } #else const char *menu_path = menu->scratch2_buf; -#endif fill_pathname_join_special(tmp_str, menu_path, menu->scratch_buf, sizeof(tmp_str)); +#endif if (!string_is_empty(info->path)) free(info->path); diff --git a/menu/cbs/menu_cbs_ok.c b/menu/cbs/menu_cbs_ok.c index 54033b9610..6a16485805 100644 --- a/menu/cbs/menu_cbs_ok.c +++ b/menu/cbs/menu_cbs_ok.c @@ -92,6 +92,9 @@ #ifdef __WINRT__ #include "../../uwp/uwp_func.h" #endif +#ifdef IOS +#include "../../ui/drivers/cocoa/apple_platform.h" +#endif #if defined(ANDROID) #include "../../file_path_special.h" @@ -956,9 +959,14 @@ int generic_action_ok_displaylist_push( content_path = menu->scratch_buf; } if (content_path) - fill_pathname_join_special(menu->detect_content_path, - menu_path, content_path, - sizeof(menu->detect_content_path)); + { + if (path_is_absolute(content_path)) + strlcpy(menu->detect_content_path, content_path, sizeof(menu->detect_content_path)); + else + fill_pathname_join_special(menu->detect_content_path, + menu_path, content_path, + sizeof(menu->detect_content_path)); + } info_label = msg_hash_to_str( MENU_ENUM_LABEL_DEFERRED_ARCHIVE_OPEN_DETECT_CORE); @@ -1981,12 +1989,22 @@ static int file_load_with_detect_core_wrapper( if (string_is_equal(menu_label, msg_hash_to_str(MENU_ENUM_LABEL_DEFERRED_ARCHIVE_OPEN_DETECT_CORE))) - fill_pathname_join_special(menu_path_new, - menu->scratch2_buf, menu->scratch_buf, sizeof(menu_path_new)); + { + if (path_is_absolute(menu->scratch_buf)) + strlcpy(menu_path_new, menu->scratch_buf, sizeof(menu_path_new)); + else + fill_pathname_join_special(menu_path_new, + menu->scratch2_buf, menu->scratch_buf, sizeof(menu_path_new)); + } else if (string_is_equal(menu_label, msg_hash_to_str(MENU_ENUM_LABEL_DEFERRED_ARCHIVE_OPEN))) - fill_pathname_join_special(menu_path_new, - menu->scratch2_buf, menu->scratch_buf, sizeof(menu_path_new)); + { + if (path_is_absolute(menu->scratch_buf)) + strlcpy(menu_path_new, menu->scratch_buf, sizeof(menu_path_new)); + else + fill_pathname_join_special(menu_path_new, + menu->scratch2_buf, menu->scratch_buf, sizeof(menu_path_new)); + } core_info_get_list(&list); @@ -6408,6 +6426,10 @@ static int action_ok_open_uwp_permission_settings(const char *path, static int action_ok_open_picker(const char *path, const char *label, unsigned type, size_t idx, size_t entry_idx) { +#if TARGET_OS_IOS + ios_show_file_sheet(); + return 0; +#else char *new_path = NULL; int ret = generic_action_ok_displaylist_push( path, new_path, @@ -6417,6 +6439,7 @@ static int action_ok_open_picker(const char *path, free(new_path); return ret; +#endif } #ifdef HAVE_NETWORKING @@ -7586,9 +7609,12 @@ static int action_ok_load_archive_detect_core(const char *path, new_core_path, sizeof(new_core_path))) ret = -1; - fill_pathname_join_special( - menu->detect_content_path, menu_path, content_path, - sizeof(menu->detect_content_path)); + if (path_is_absolute(content_path)) + strlcpy(menu->detect_content_path, content_path, sizeof(menu->detect_content_path)); + else + fill_pathname_join_special( + menu->detect_content_path, menu_path, content_path, + sizeof(menu->detect_content_path)); switch (ret) { diff --git a/ui/drivers/cocoa/apple_platform.h b/ui/drivers/cocoa/apple_platform.h index 8fd28e6075..018aa5e36d 100644 --- a/ui/drivers/cocoa/apple_platform.h +++ b/ui/drivers/cocoa/apple_platform.h @@ -8,6 +8,10 @@ extern void write_userdefaults_config_file(void); extern void update_topshelf(void); #endif +#if TARGET_OS_IOS +extern void ios_show_file_sheet(void); +#endif + #ifdef __OBJC__ #ifdef HAVE_METAL diff --git a/ui/drivers/cocoa/cocoa_common.m b/ui/drivers/cocoa/cocoa_common.m index 61eee83a16..37bb579bbb 100644 --- a/ui/drivers/cocoa/cocoa_common.m +++ b/ui/drivers/cocoa/cocoa_common.m @@ -31,11 +31,19 @@ #import #import "../../pkg/apple/RetroArchTopShelfExtension/ContentProvider.h" #endif +#if TARGET_OS_IOS +#import +#import "../../../menu/menu_cbs.h" +#endif #endif #include "../../../configuration.h" +#include "../../../content.h" +#include "../../../core_info.h" +#include "../../../menu/menu_cbs.h" #include "../../../paths.h" #include "../../../retroarch.h" +#include "../../../tasks/task_content.h" #include "../../../verbosity.h" #include "../../input/drivers/cocoa_input.h" @@ -51,11 +59,15 @@ static CocoaView* g_instance; #ifdef HAVE_COCOATOUCH void *glkitview_init(void); +void cocoa_file_load_with_detect_core(const char *filename); @interface CocoaView() @end #endif @@ -285,6 +297,50 @@ void *glkitview_init(void); } #endif +#if TARGET_OS_IOS + +#pragma mark UIDocumentPickerViewController + +-(void)documentPicker:(UIDocumentPickerViewController *)controller didPickDocumentAtURL:(NSURL *)url +{ + NSFileManager *manager = [NSFileManager defaultManager]; + NSString *filename = (NSString*)url.path.lastPathComponent; + NSError *error = nil; + settings_t *settings = config_get_ptr(); + char fullpath[PATH_MAX_LENGTH] = {0}; + fill_pathname_join_special(fullpath, settings->paths.directory_core_assets, [filename UTF8String], sizeof(fullpath)); + NSString *destination = [NSString stringWithUTF8String:fullpath]; + NSString *documentsDir = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES).firstObject; + /* Copy file to documents directory if it's not already + * inside Documents directory */ + if (![[url path] containsString:documentsDir]) + if (![manager fileExistsAtPath:destination]) + [manager copyItemAtPath:[url path] toPath:destination error:&error]; + if (filebrowser_get_type() == FILEBROWSER_SCAN_FILE) + action_scan_file(fullpath, NULL, 0, 0); + else + { + cocoa_file_load_with_detect_core(fullpath); + } +} + +-(void)documentPickerWasCancelled:(UIDocumentPickerViewController *)controller +{ +} + +-(void)showDocumentPicker +{ + UIDocumentPickerViewController *documentPicker = [[UIDocumentPickerViewController alloc] + initWithDocumentTypes:@[(NSString *)kUTTypeDirectory, + (NSString *)kUTTypeItem] + inMode:UIDocumentPickerModeImport]; + documentPicker.delegate = self; + documentPicker.modalPresentationStyle = UIModalPresentationFormSheet; + [self presentViewController:documentPicker animated:YES completion:nil]; +} + +#endif + #if defined(OSX) - (void)setFrame:(NSRect)frameRect { @@ -657,6 +713,13 @@ void *glkitview_init(void); @end +#if TARGET_OS_IOS +void ios_show_file_sheet(void) +{ + [[CocoaView get] showDocumentPicker]; +} +#endif + void *cocoa_screen_get_chosen(void) { unsigned monitor_index; @@ -971,3 +1034,45 @@ void update_topshelf(void) } } #endif + +void cocoa_file_load_with_detect_core(const char *filename) +{ + /* largely copied from file_load_with_detect_core() in menu_cbs_ok.c */ + core_info_list_t *list = NULL; + const core_info_t *info = NULL; + size_t supported = 0; + + if (path_is_compressed_file(filename)) + { + generic_action_ok_displaylist_push(filename, NULL, + msg_hash_to_str(MENU_ENUM_LABEL_VALUE_DOWNLOADED_FILE_DETECT_CORE_LIST), + FILE_TYPE_CARCHIVE, 0, 0, ACTION_OK_DL_COMPRESSED_ARCHIVE_PUSH_DETECT_CORE); + return; + } + + core_info_get_list(&list); + core_info_list_get_supported_cores(list, filename, &info, &supported); + if (supported > 1) + { + struct menu_state *menu_st = menu_state_get_ptr(); + menu_handle_t *menu = menu_st->driver_data; + strlcpy(menu->deferred_path, filename, sizeof(menu->deferred_path)); + strlcpy(menu->detect_content_path, filename, sizeof(menu->detect_content_path)); + generic_action_ok_displaylist_push(filename, NULL, NULL, FILE_TYPE_NONE, 0, 0, ACTION_OK_DL_DEFERRED_CORE_LIST); + } + else if (supported == 1) + { + content_ctx_info_t content_info; + + content_info.argc = 0; + content_info.argv = NULL; + content_info.args = NULL; + content_info.environ_get = NULL; + + task_push_load_content_with_new_core_from_menu( + info->path, filename, + &content_info, + CORE_TYPE_PLAIN, + NULL, NULL); + } +}