diff --git a/command.c b/command.c index bca4379177..4cc44a110f 100644 --- a/command.c +++ b/command.c @@ -1173,9 +1173,17 @@ bool command_event_save_config( #endif if (path_exists && config_save_file(config_path)) { +#if IOS + char tmp[PATH_MAX_LENGTH] = {0}; + fill_pathname_abbreviate_special(tmp, config_path, sizeof(tmp)); + snprintf(s, len, "%s \"%s\".", + msg_hash_to_str(MSG_SAVED_NEW_CONFIG_TO), + tmp); +#else snprintf(s, len, "%s \"%s\".", msg_hash_to_str(MSG_SAVED_NEW_CONFIG_TO), config_path); +#endif RARCH_LOG("[Config]: %s\n", s); return true; } diff --git a/config.def.h b/config.def.h index a1b1729466..7537ea20aa 100644 --- a/config.def.h +++ b/config.def.h @@ -1164,7 +1164,12 @@ #endif /* Will sync audio. (recommended) */ +#ifdef IOS +/* FIXME: coreaudio will cause the main thread to hang on backgrounding, causing a crash */ +#define DEFAULT_AUDIO_SYNC false +#else #define DEFAULT_AUDIO_SYNC true +#endif /* Audio rate control. */ #if !defined(RARCH_CONSOLE) diff --git a/configuration.c b/configuration.c index 0a0fa25097..70c31d6da8 100644 --- a/configuration.c +++ b/configuration.c @@ -3770,9 +3770,11 @@ static bool config_load_file(global_t *global, strlcpy(path_settings[i].ptr, tmp_str, PATH_MAX_LENGTH); } +#if !IOS if (config_get_path(conf, "libretro_directory", tmp_str, sizeof(tmp_str))) configuration_set_string(settings, settings->paths.directory_libretro, tmp_str); +#endif #ifdef RARCH_CONSOLE if (conf) diff --git a/frontend/drivers/platform_darwin.m b/frontend/drivers/platform_darwin.m index 9727e9164f..cecfd49079 100644 --- a/frontend/drivers/platform_darwin.m +++ b/frontend/drivers/platform_darwin.m @@ -54,6 +54,7 @@ #include #include #include +#include #ifdef HAVE_MENU #include "../../menu/menu_driver.h" @@ -410,7 +411,7 @@ static void frontend_darwin_get_env(int *argc, char *argv[], #if defined(HAVE_UPDATE_CORES) || defined(HAVE_STEAM) fill_pathname_join(g_defaults.dirs[DEFAULT_DIR_CORE], application_data, "cores", sizeof(g_defaults.dirs[DEFAULT_DIR_CORE])); #else - fill_pathname_join(g_defaults.dirs[DEFAULT_DIR_CORE], bundle_path_buf, "modules", sizeof(g_defaults.dirs[DEFAULT_DIR_CORE])); + fill_pathname_join(g_defaults.dirs[DEFAULT_DIR_CORE], bundle_path_buf, "Frameworks", sizeof(g_defaults.dirs[DEFAULT_DIR_CORE])); #endif fill_pathname_join(g_defaults.dirs[DEFAULT_DIR_DATABASE], application_data, "database/rdb", sizeof(g_defaults.dirs[DEFAULT_DIR_DATABASE])); fill_pathname_join(g_defaults.dirs[DEFAULT_DIR_CORE_ASSETS], application_data, "downloads", sizeof(g_defaults.dirs[DEFAULT_DIR_CORE_ASSETS])); @@ -712,36 +713,30 @@ static int frontend_darwin_parse_drive_list(void *data, bool load_content) int ret = -1; #if TARGET_OS_IPHONE #ifdef HAVE_MENU + struct string_list *str_list = NULL; file_list_t *list = (file_list_t*)data; - char bundle_path_buf[PATH_MAX_LENGTH] = {0}; - char home_dir_buf[PATH_MAX_LENGTH] = {0}; - CFBundleRef bundle = CFBundleGetMainBundle(); - enum msg_hash_enums enum_idx = load_content - ? MENU_ENUM_LABEL_FILE_DETECT_CORE_LIST_PUSH_DIR + enum msg_hash_enums enum_idx = load_content + ? MENU_ENUM_LABEL_FILE_DETECT_CORE_LIST_PUSH_DIR : MENU_ENUM_LABEL_FILE_BROWSER_DIRECTORY; - CFURLRef bundle_url = CFBundleCopyBundleURL(bundle); - CFStringRef bundle_path = CFURLCopyPath(bundle_url); - CFStringGetCString(bundle_path, bundle_path_buf, - sizeof(bundle_path_buf), kCFStringEncodingUTF8); + if (list->size == 0) + menu_entries_append(list, + "~/Documents/RetroArch", + msg_hash_to_str(MENU_ENUM_LABEL_FILE_DETECT_CORE_LIST_PUSH_DIR), + enum_idx, + FILE_TYPE_DIRECTORY, 0, 0, NULL); - CFSearchPathForDirectoriesInDomains( - home_dir_buf, sizeof(home_dir_buf)); - - menu_entries_append(list, - home_dir_buf, - msg_hash_to_str(MENU_ENUM_LABEL_FILE_DETECT_CORE_LIST_PUSH_DIR), - enum_idx, - FILE_TYPE_DIRECTORY, 0, 0, NULL); - menu_entries_append(list, "/", - msg_hash_to_str(MENU_ENUM_LABEL_FILE_DETECT_CORE_LIST_PUSH_DIR), - enum_idx, - FILE_TYPE_DIRECTORY, 0, 0, NULL); + str_list = string_list_new(); + // only add / if it's jailbroken + dir_list_append(str_list, "/private/var", NULL, true, false, false, false); + if (str_list->size > 0) + menu_entries_append(list, "/", + msg_hash_to_str(MENU_ENUM_LABEL_FILE_DETECT_CORE_LIST_PUSH_DIR), + enum_idx, + FILE_TYPE_DIRECTORY, 0, 0, NULL); + string_list_free(str_list); ret = 0; - - CFRelease(bundle_path); - CFRelease(bundle_url); #endif #endif return ret; diff --git a/frontend/frontend_driver.c b/frontend/frontend_driver.c index 33cc8c3f67..047d14218e 100644 --- a/frontend/frontend_driver.c +++ b/frontend/frontend_driver.c @@ -185,6 +185,18 @@ bool frontend_driver_get_core_extension(char *s, size_t len) s[2] = 'l'; s[3] = '\0'; return true; +#elif defined(IOS) + s[0] = 'f'; + s[1] = 'r'; + s[2] = 'a'; + s[3] = 'm'; + s[4] = 'e'; + s[5] = 'w'; + s[6] = 'o'; + s[7] = 'r'; + s[8] = 'k'; + s[9] = '\0'; + return true; #elif defined(__APPLE__) || defined(__MACH__) s[0] = 'd'; s[1] = 'y'; diff --git a/gfx/common/vulkan_common.c b/gfx/common/vulkan_common.c index fbfa861878..9ffb1cd9a2 100644 --- a/gfx/common/vulkan_common.c +++ b/gfx/common/vulkan_common.c @@ -2295,6 +2295,8 @@ bool vulkan_context_init(gfx_ctx_vulkan_data_t *vk, { #ifdef _WIN32 vulkan_library = dylib_load("vulkan-1.dll"); +#elif IOS + vulkan_library = dylib_load("libMoltenVK_libretro.framework"); #elif __APPLE__ vulkan_library = dylib_load("libMoltenVK.dylib"); #else diff --git a/libretro-common/dynamic/dylib.c b/libretro-common/dynamic/dylib.c index 248c61283a..c64a6ca22e 100644 --- a/libretro-common/dynamic/dylib.c +++ b/libretro-common/dynamic/dylib.c @@ -127,6 +127,22 @@ dylib_t dylib_load(const char *path) #elif defined(ORBIS) int res; dylib_t lib = (dylib_t)sceKernelLoadStartModule(path, 0, NULL, 0, NULL, &res); +#elif IOS + dylib_t lib; + static const char fwSuffix[] = ".framework"; + if (string_ends_with(path, fwSuffix)) + { + char fwPath[PATH_MAX_LENGTH] = {0}; + strlcat(fwPath, path, sizeof(fwPath)); + size_t sz = strlcat(fwPath, "/", sizeof(fwPath)); + const char *fwName = path_basename(path); + // Assume every framework binary is named for the framework. Not always + // a great assumption but correct enough for our uses. + strlcpy(fwPath + sz, fwName, strlen(fwName) - STRLEN_CONST(fwSuffix) + 1); + lib = dlopen(fwPath, RTLD_LAZY | RTLD_LOCAL); + } + else + lib = dlopen(path, RTLD_LAZY | RTLD_LOCAL); #else dylib_t lib = dlopen(path, RTLD_LAZY | RTLD_LOCAL); #endif diff --git a/libretro-common/lists/dir_list.c b/libretro-common/lists/dir_list.c index f51fdeff4f..c24e2c2490 100644 --- a/libretro-common/lists/dir_list.c +++ b/libretro-common/lists/dir_list.c @@ -188,6 +188,15 @@ static int dir_list_read(const char *dir, #ifndef _WIN32 if (!include_hidden && strcmp(name, "System Volume Information") == 0) continue; +#endif +#ifdef IOS + if (string_ends_with(name, ".framework")) + { + attr.i = RARCH_PLAIN_FILE; + if (!string_list_append(list, file_path, attr)) + goto error; + continue; + } #endif if (recursive) dir_list_read(file_path, list, ext_list, include_dirs, diff --git a/menu/cbs/menu_cbs_get_value.c b/menu/cbs/menu_cbs_get_value.c index 1fa79fdf56..a4a6cf989e 100644 --- a/menu/cbs/menu_cbs_get_value.c +++ b/menu/cbs/menu_cbs_get_value.c @@ -1257,8 +1257,15 @@ static void menu_action_setting_disp_set_label_menu_file_directory( const char *path, char *s2, size_t len2) { +#if IOS + char tmp[PATH_MAX_LENGTH] = {0}; + fill_pathname_abbreviate_special(tmp, path, sizeof(tmp)); + MENU_ACTION_SETTING_GENERIC_DISP_SET_LABEL_2(w, s, len, + tmp, "(DIR)", STRLEN_CONST("(DIR)"), s2, len2); +#else MENU_ACTION_SETTING_GENERIC_DISP_SET_LABEL_2(w, s, len, path, "(DIR)", STRLEN_CONST("(DIR)"), s2, len2); +#endif } static void menu_action_setting_disp_set_label_generic( diff --git a/menu/cbs/menu_cbs_ok.c b/menu/cbs/menu_cbs_ok.c index 1108ed3b09..4f48571273 100644 --- a/menu/cbs/menu_cbs_ok.c +++ b/menu/cbs/menu_cbs_ok.c @@ -6718,8 +6718,15 @@ int action_ok_push_filebrowser_list_dir_select(const char *path, /* Start browsing from current directory */ get_current_menu_value(menu_st, current_value, sizeof(current_value)); +#if IOS + char tmp[PATH_MAX_LENGTH]; + fill_pathname_expand_special(tmp, current_value, sizeof(tmp)); + if (!path_is_directory(tmp)) + current_value[0] = '\0'; +#else if (!path_is_directory(current_value)) current_value[0] = '\0'; +#endif filebrowser_set_type(FILEBROWSER_SELECT_DIR); strlcpy(menu->filebrowser_label, label, sizeof(menu->filebrowser_label)); diff --git a/menu/cbs/menu_cbs_title.c b/menu/cbs/menu_cbs_title.c index 52a0976f44..82ea16c7bd 100644 --- a/menu/cbs/menu_cbs_title.c +++ b/menu/cbs/menu_cbs_title.c @@ -876,7 +876,11 @@ static int action_get_title_default(const char *path, const char *label, s[ _len] = ':'; s[++_len] = ' '; s[++_len] = '\0'; +#if IOS + fill_pathname_abbreviate_special(s + _len, path, len - _len); +#else strlcpy(s + _len, path, len - _len); +#endif } menu_entries_search_append_terms_string(s, len); diff --git a/menu/menu_displaylist.c b/menu/menu_displaylist.c index 8432497435..0583e3bbf2 100644 --- a/menu/menu_displaylist.c +++ b/menu/menu_displaylist.c @@ -207,6 +207,12 @@ static int filebrowser_parse( bool path_is_compressed = !string_is_empty(path) ? path_is_compressed_file(path) : false; menu_search_terms_t *search_terms = menu_entries_search_get_terms(); +#ifdef IOS + char full_path[PATH_MAX_LENGTH]; + fill_pathname_expand_special(full_path, path, sizeof(full_path)); +#else + const char *full_path = path; +#endif if (path_is_compressed) { @@ -242,6 +248,10 @@ static int filebrowser_parse( filter_ext = false; if ( string_is_equal(label, "database_manager_list") +#if IOS + || string_is_equal(label, "video_filter") + || string_is_equal(label, "audio_dsp_plugin") +#endif || string_is_equal(label, "cursor_manager_list")) allow_parent_directory = false; @@ -260,16 +270,16 @@ static int filebrowser_parse( && (runloop_st->subsystem_current_count > 0) && (content_get_subsystem_rom_id() < subsystem->num_roms)) ret = dir_list_initialize(&str_list, - path, + full_path, filter_ext ? subsystem->roms[content_get_subsystem_rom_id()].valid_extensions : NULL, true, show_hidden_files, true, false); } else if ((type_default == FILE_TYPE_MANUAL_SCAN_DAT) || (type_default == FILE_TYPE_SIDELOAD_CORE)) - ret = dir_list_initialize(&str_list, path, + ret = dir_list_initialize(&str_list, full_path, exts, true, show_hidden_files, false, false); else - ret = dir_list_initialize(&str_list, path, + ret = dir_list_initialize(&str_list, full_path, filter_ext ? exts : NULL, true, show_hidden_files, true, false); } @@ -474,6 +484,32 @@ static int filebrowser_parse( MENU_ENUM_LABEL_NO_ITEMS, MENU_SETTING_NO_ITEM, 0, 0, NULL); +#ifdef IOS + { + // check if we're allowed to escape our sandbox + struct string_list *str_list = string_list_new(); + dir_list_append(str_list, "/private/var", NULL, true, false, false, false); + if (str_list->size <= 0) + { + char dir[PATH_MAX_LENGTH]; + fill_pathname_application_dir(dir, sizeof(dir)); + if (string_ends_with(full_path, "/") && !string_ends_with(dir, "/")) + strlcat(dir, "/", sizeof(dir)); + if (string_is_equal(dir, full_path)) + allow_parent_directory = false; + else + { + fill_pathname_home_dir(dir, sizeof(dir)); + if (string_ends_with(full_path, "/") && !string_ends_with(dir, "/")) + strlcat(dir, "/", sizeof(dir)); + if (string_is_equal(dir, full_path)) + allow_parent_directory = false; + } + } + string_list_free(str_list); + } +#endif + end: if (!path_is_compressed && allow_parent_directory) menu_entries_prepend(info_list, @@ -491,6 +527,9 @@ static int menu_displaylist_parse_core_info( settings_t *settings) { char tmp[PATH_MAX_LENGTH]; +#if IOS + char shortened_path[PATH_MAX_LENGTH] = {0}; +#endif unsigned i, count = 0; core_info_t *core_info = NULL; const char *core_path = NULL; @@ -786,9 +825,17 @@ static int menu_displaylist_parse_core_info( } /* Show the path that was checked */ +#ifdef IOS + shortened_path[0] = '\0'; + fill_pathname_abbreviate_special(shortened_path, firmware_info.directory.system, sizeof(shortened_path)); + snprintf(tmp, sizeof(tmp), + msg_hash_to_str(MENU_ENUM_LABEL_VALUE_CORE_INFO_FIRMWARE_PATH), + shortened_path); +#else snprintf(tmp, sizeof(tmp), msg_hash_to_str(MENU_ENUM_LABEL_VALUE_CORE_INFO_FIRMWARE_PATH), firmware_info.directory.system); +#endif if (menu_entries_append(list, tmp, "", MENU_ENUM_LABEL_CORE_INFO_ENTRY, MENU_SETTINGS_CORE_INFO_NONE, 0, 0, NULL)) count++; @@ -849,7 +896,13 @@ static int menu_displaylist_parse_core_info( tmp[ _len] = ':'; tmp[++_len] = ' '; tmp[++_len] = '\0'; +#if IOS + shortened_path[0] = '\0'; + fill_pathname_abbreviate_special(shortened_path, core_path, sizeof(shortened_path)); + strlcpy(tmp + _len, shortened_path, sizeof(tmp) - _len); +#else strlcpy(tmp + _len, core_path, sizeof(tmp) - _len); +#endif if (menu_entries_append(list, tmp, "", MENU_ENUM_LABEL_CORE_INFO_ENTRY, MENU_SETTINGS_CORE_INFO_NONE, 0, 0, NULL)) @@ -884,6 +937,7 @@ end: } #endif +#if !defined(IOS) || !IOS /* should this be allowed on jailbroken iOS devices? */ if (!string_is_empty(core_path)) { /* Check whether core is currently locked */ @@ -953,6 +1007,7 @@ end: count++; #endif } +#endif } return count; @@ -1141,6 +1196,7 @@ static unsigned menu_displaylist_parse_core_manager_list(file_list_t *list, } } +#ifndef IOS /* Add 'sideload core' entry */ if (!kiosk_mode_enable) if (menu_entries_append(list, @@ -1149,6 +1205,7 @@ static unsigned menu_displaylist_parse_core_manager_list(file_list_t *list, MENU_ENUM_LABEL_SIDELOAD_CORE_LIST, MENU_SETTING_ACTION, 0, 0, NULL)) count++; +#endif return count; } @@ -4488,7 +4545,7 @@ static unsigned menu_displaylist_parse_cores( #ifdef IOS /* For various reasons on iOS/tvOS, MoltenVK shows up * in the cores directory; exclude it here */ - if (string_is_equal(path, "libMoltenVK.dylib")) + if (string_starts_with(path, "libMoltenVK")) continue; #endif @@ -6025,11 +6082,13 @@ bool menu_displaylist_process(menu_displaylist_info_t *info) MENU_ENUM_LABEL_CORE_UPDATER_LIST, MENU_SETTING_ACTION, 0, 0, NULL); #endif +#ifndef IOS menu_entries_append(info_list, msg_hash_to_str(MENU_ENUM_LABEL_VALUE_SIDELOAD_CORE_LIST), msg_hash_to_str(MENU_ENUM_LABEL_SIDELOAD_CORE_LIST), MENU_ENUM_LABEL_SIDELOAD_CORE_LIST, MENU_SETTING_ACTION, 0, 0, NULL); +#endif } } #endif diff --git a/menu/menu_setting.c b/menu/menu_setting.c index 60ebc17794..6e438583bd 100644 --- a/menu/menu_setting.c +++ b/menu/menu_setting.c @@ -1256,19 +1256,32 @@ static void setting_get_string_representation_st_dir(rarch_setting_t *setting, char *s, size_t len) { if (setting) +#if IOS + { + if (*setting->value.target.string) + fill_pathname_abbreviate_special(s, setting->value.target.string, len); + else + strlcpy(s, setting->dir.empty_path, len); + } +#else strlcpy(s, *setting->value.target.string ? setting->value.target.string : setting->dir.empty_path, len); +#endif } static void setting_get_string_representation_st_path(rarch_setting_t *setting, char *s, size_t len) { if (setting) +#if IOS + fill_pathname_abbreviate_special(s, path_basename(setting->value.target.string), len); +#else fill_pathname(s, path_basename(setting->value.target.string), "", len); +#endif } static void setting_get_string_representation_st_string(rarch_setting_t *setting, @@ -21962,6 +21975,7 @@ static bool setting_append_list( START_SUB_GROUP(list, list_info, "State", &group_info, &subgroup_info, parent_group); #ifdef HAVE_NETWORKING +#ifdef HAVE_UPDATE_CORES #if defined(ANDROID) /* Play Store builds do not fetch cores * from the buildbot */ @@ -21986,6 +22000,7 @@ static bool setting_append_list( (*list)[list_info->index - 1].ui_type = ST_UI_TYPE_STRING_LINE_EDIT; (*list)[list_info->index - 1].action_start = setting_generic_action_start_default; } +#endif CONFIG_STRING( list, list_info, @@ -22949,6 +22964,7 @@ static bool setting_append_list( #endif #ifdef HAVE_NETWORKING +#if !IOS CONFIG_ACTION( list, list_info, MENU_ENUM_LABEL_ACCOUNTS_YOUTUBE, @@ -22972,6 +22988,7 @@ static bool setting_append_list( &group_info, &subgroup_info, parent_group); +#endif #endif END_SUB_GROUP(list, list_info, parent_group); diff --git a/pkg/apple/.gitignore b/pkg/apple/.gitignore index a14b4825d4..cbf700b9d6 100644 --- a/pkg/apple/.gitignore +++ b/pkg/apple/.gitignore @@ -1,4 +1,6 @@ xcuserdata/ xcshareddata/ iOS/filters/ +iOS/Frameworks/ tvOS/filters/ +tvOS/Frameworks/ diff --git a/pkg/apple/JITSupport.m b/pkg/apple/JITSupport.m index cc5bb5321b..3cf807d715 100644 --- a/pkg/apple/JITSupport.m +++ b/pkg/apple/JITSupport.m @@ -25,6 +25,7 @@ #endif #include +#include #include "../../verbosity.h" extern int csops(pid_t pid, unsigned int ops, void * useraddr, size_t usersize); @@ -102,6 +103,11 @@ void jb_start_altkit(void) { if (jit_available()) return; + char fwpath[PATH_MAX_LENGTH] = {0}; + fill_pathname_expand_special(fwpath, ":/Frameworks/flycast_libretro.framework", sizeof(fwpath)); + if (!path_is_valid(fwpath)) + return; + [[ALTServerManager sharedManager] autoconnectWithCompletionHandler:^(ALTServerConnection *connection, NSError *error) { if (error) return; diff --git a/pkg/apple/RetroArch_iOS13.xcodeproj/project.pbxproj b/pkg/apple/RetroArch_iOS13.xcodeproj/project.pbxproj index a6e62ca88b..544144df2f 100644 --- a/pkg/apple/RetroArch_iOS13.xcodeproj/project.pbxproj +++ b/pkg/apple/RetroArch_iOS13.xcodeproj/project.pbxproj @@ -25,14 +25,14 @@ 0712A7722B807AE400C9765F /* TVServices.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 0712A7712B807AE400C9765F /* TVServices.framework */; }; 0712A7762B807AE400C9765F /* ContentProvider.m in Sources */ = {isa = PBXBuildFile; fileRef = 0712A7752B807AE400C9765F /* ContentProvider.m */; }; 0712A77A2B807AE400C9765F /* RetroArchTopShelfExtension.appex in Embed Foundation Extensions */ = {isa = PBXBuildFile; fileRef = 0712A7702B807AE400C9765F /* RetroArchTopShelfExtension.appex */; settings = {ATTRIBUTES = (RemoveHeadersOnCopy, ); }; }; - 0714E7152983A5E500E6B45B /* libMoltenVK.dylib in Embed Libraries */ = {isa = PBXBuildFile; fileRef = 0714E7132983A5AC00E6B45B /* libMoltenVK.dylib */; settings = {ATTRIBUTES = (CodeSignOnCopy, ); }; }; 0718BC632ABBAFB6001F2CBE /* Network.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 0718BC5F2ABBA807001F2CBE /* Network.framework */; }; - 0734BB242ADB7FEE00EBDCAD /* libMoltenVK.dylib in Embed Libraries */ = {isa = PBXBuildFile; fileRef = 92EDD1622982E40C00AD33B4 /* libMoltenVK.dylib */; settings = {ATTRIBUTES = (CodeSignOnCopy, ); }; }; 073734A42A093A5700BF7397 /* JITSupport.m in Sources */ = {isa = PBXBuildFile; fileRef = 92A1F81727006CAE00DEAD2A /* JITSupport.m */; }; 073734A62A093ACA00BF7397 /* AltKit in Frameworks */ = {isa = PBXBuildFile; productRef = 073734A52A093ACA00BF7397 /* AltKit */; }; 076CA50D2B695C2C00840EA5 /* libz.tbd in Frameworks */ = {isa = PBXBuildFile; fileRef = 076CA50C2B695C2C00840EA5 /* libz.tbd */; }; + 077A8E202BCE31F3000ECA41 /* Frameworks in Resources */ = {isa = PBXBuildFile; fileRef = 077A8E1F2BCE31E5000ECA41 /* Frameworks */; }; 0789FC302A07847E00D042B7 /* AltKit in Frameworks */ = {isa = PBXBuildFile; productRef = 0789FC2F2A07847E00D042B7 /* AltKit */; }; 07B7872D29E8FE8F0088B74F /* filters in Resources */ = {isa = PBXBuildFile; fileRef = 07B7872C29E8FE8F0088B74F /* filters */; }; + 07E8EBE32BCCD1E10070B42D /* Frameworks in Resources */ = {isa = PBXBuildFile; fileRef = 07E8EBE22BCCD1E10070B42D /* Frameworks */; }; 07F7FB022A2DA8B800037C04 /* filters in Resources */ = {isa = PBXBuildFile; fileRef = 07F7FB012A2DA8B800037C04 /* filters */; }; 9204BE0D1D319EF300BD49DB /* griffin_objc.m in Sources */ = {isa = PBXBuildFile; fileRef = 50521A431AA23BF500185CC9 /* griffin_objc.m */; }; 9204BE101D319EF300BD49DB /* griffin.c in Sources */ = {isa = PBXBuildFile; fileRef = 501232C9192E5FC40063A359 /* griffin.c */; settings = {COMPILER_FLAGS = "-include $(DERIVED_FILE_DIR)/git_version.h"; }; }; @@ -52,7 +52,6 @@ 9204BE1F1D319EF300BD49DB /* GLKit.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 96AFAE2F16C1D4EA009DE44C /* GLKit.framework */; }; 9204BE201D319EF300BD49DB /* OpenGLES.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 96AFAE3116C1D4EA009DE44C /* OpenGLES.framework */; }; 9204BE231D319EF300BD49DB /* InfoPlist.strings in Resources */ = {isa = PBXBuildFile; fileRef = 967894611788EBD800D6CA69 /* InfoPlist.strings */; }; - 9204BE261D319EF300BD49DB /* iOS/modules in Resources */ = {isa = PBXBuildFile; fileRef = 83EB675F19EEAF050096F441 /* iOS/modules */; }; 9210C2F224B3A19100E6FE7C /* MetalKit.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 9210C2F024B3A19100E6FE7C /* MetalKit.framework */; }; 9210C2F324B3A19100E6FE7C /* Metal.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 9210C2F124B3A19100E6FE7C /* Metal.framework */; }; 9210C2F624B3A32D00E6FE7C /* griffin_cpp.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 9210C2F424B3A32D00E6FE7C /* griffin_cpp.cpp */; }; @@ -128,7 +127,6 @@ 92CC05C521FEDC9F00FF79F0 /* CFNetwork.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 92CC05C421FEDC9F00FF79F0 /* CFNetwork.framework */; }; 92CC05C721FEDD0B00FF79F0 /* MobileCoreServices.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 92CC05C621FEDD0B00FF79F0 /* MobileCoreServices.framework */; }; 92DAF33F277A370600FE2A9E /* EmulatorTouchMouse.swift in Sources */ = {isa = PBXBuildFile; fileRef = 92DAF33E277A370600FE2A9E /* EmulatorTouchMouse.swift */; }; - 92E5DCD4231A5786006491BF /* modules in Resources */ = {isa = PBXBuildFile; fileRef = 92E5DCD3231A5786006491BF /* modules */; }; /* End PBXBuildFile section */ /* Begin PBXContainerItemProxy section */ @@ -160,28 +158,6 @@ name = "Embed Foundation Extensions"; runOnlyForDeploymentPostprocessing = 0; }; - 0714E7162983A5E500E6B45B /* Embed Libraries */ = { - isa = PBXCopyFilesBuildPhase; - buildActionMask = 2147483647; - dstPath = ""; - dstSubfolderSpec = 10; - files = ( - 0714E7152983A5E500E6B45B /* libMoltenVK.dylib in Embed Libraries */, - ); - name = "Embed Libraries"; - runOnlyForDeploymentPostprocessing = 0; - }; - 0734BB252ADB7FEE00EBDCAD /* Embed Libraries */ = { - isa = PBXCopyFilesBuildPhase; - buildActionMask = 2147483647; - dstPath = ""; - dstSubfolderSpec = 10; - files = ( - 0734BB242ADB7FEE00EBDCAD /* libMoltenVK.dylib in Embed Libraries */, - ); - name = "Embed Libraries"; - runOnlyForDeploymentPostprocessing = 0; - }; 9292D6F528F549D500E47A75 /* Embed Foundation Extensions */ = { isa = PBXCopyFilesBuildPhase; buildActionMask = 2147483647; @@ -207,8 +183,10 @@ 0718BC5F2ABBA807001F2CBE /* Network.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = Network.framework; path = Platforms/AppleTVOS.platform/Developer/SDKs/AppleTVOS17.0.sdk/System/Library/Frameworks/Network.framework; sourceTree = DEVELOPER_DIR; }; 073DB2892B8706490001BA32 /* RetroArchTV.entitlements */ = {isa = PBXFileReference; lastKnownFileType = text.plist.entitlements; path = RetroArchTV.entitlements; sourceTree = ""; }; 076CA50C2B695C2C00840EA5 /* libz.tbd */ = {isa = PBXFileReference; lastKnownFileType = "sourcecode.text-based-dylib-definition"; name = libz.tbd; path = Platforms/AppleTVOS.platform/Developer/SDKs/AppleTVOS17.2.sdk/usr/lib/libz.tbd; sourceTree = DEVELOPER_DIR; }; + 077A8E1F2BCE31E5000ECA41 /* Frameworks */ = {isa = PBXFileReference; lastKnownFileType = folder; path = Frameworks; sourceTree = ""; }; 0789FC2E2A07845300D042B7 /* AltKit */ = {isa = PBXFileReference; lastKnownFileType = wrapper; name = AltKit; path = Frameworks/AltKit; sourceTree = ""; }; 07B7872C29E8FE8F0088B74F /* filters */ = {isa = PBXFileReference; lastKnownFileType = folder; path = filters; sourceTree = ""; }; + 07E8EBE22BCCD1E10070B42D /* Frameworks */ = {isa = PBXFileReference; lastKnownFileType = folder; name = Frameworks; path = iOS/Frameworks; sourceTree = SOURCE_ROOT; }; 07F7FB012A2DA8B800037C04 /* filters */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text; name = filters; path = iOS/filters; sourceTree = SOURCE_ROOT; }; 501232C9192E5FC40063A359 /* griffin.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; name = griffin.c; path = ../../griffin/griffin.c; sourceTree = SOURCE_ROOT; }; 501881EB184BAD6D006F665D /* AVFoundation.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = AVFoundation.framework; path = System/Library/Frameworks/AVFoundation.framework; sourceTree = SDKROOT; }; @@ -578,6 +556,7 @@ 83D632D719ECFCC4009E3161 /* iOS */ = { isa = PBXGroup; children = ( + 07E8EBE22BCCD1E10070B42D /* Frameworks */, 07F7FB012A2DA8B800037C04 /* filters */, 9222F20A2315DD3D0097C0FD /* retroarch_logo.png */, 83EB675F19EEAF050096F441 /* iOS/modules */, @@ -590,6 +569,7 @@ 926C77D821FD1E6500103EDE /* tvOS */ = { isa = PBXGroup; children = ( + 077A8E1F2BCE31E5000ECA41 /* Frameworks */, 07B7872C29E8FE8F0088B74F /* filters */, 92E5DCD3231A5786006491BF /* modules */, 926C77E221FD1E6700103EDE /* Assets.xcassets */, @@ -1341,7 +1321,6 @@ 9204BE271D319EF300BD49DB /* ShellScript */, 9204BE211D319EF300BD49DB /* Resources */, 9292D6F528F549D500E47A75 /* Embed Foundation Extensions */, - 0734BB252ADB7FEE00EBDCAD /* Embed Libraries */, ); buildRules = ( ); @@ -1365,7 +1344,6 @@ 926C77D421FD1E6500103EDE /* Frameworks */, 92CC057521FE2D4900FF79F0 /* ShellScript */, 926C77D521FD1E6500103EDE /* Resources */, - 0714E7162983A5E500E6B45B /* Embed Libraries */, 0712A77B2B807AE400C9765F /* Embed Foundation Extensions */, ); buildRules = ( @@ -1468,7 +1446,7 @@ 92CC05BC21FE3C1700FF79F0 /* GCDWebUploader.bundle in Resources */, 9222F20B2315DD3D0097C0FD /* retroarch_logo.png in Resources */, 929784502200EEE400989A60 /* iOS/Resources/Icons.xcassets in Resources */, - 9204BE261D319EF300BD49DB /* iOS/modules in Resources */, + 07E8EBE32BCCD1E10070B42D /* Frameworks in Resources */, 9222F1FF2314BA7C0097C0FD /* assets.zip in Resources */, ); runOnlyForDeploymentPostprocessing = 0; @@ -1477,9 +1455,9 @@ isa = PBXResourcesBuildPhase; buildActionMask = 2147483647; files = ( + 077A8E202BCE31F3000ECA41 /* Frameworks in Resources */, 07B7872D29E8FE8F0088B74F /* filters in Resources */, 92CC05BD21FE3C1700FF79F0 /* GCDWebUploader.bundle in Resources */, - 92E5DCD4231A5786006491BF /* modules in Resources */, 9222F2002314BA7C0097C0FD /* assets.zip in Resources */, 926C77E321FD1E6700103EDE /* Assets.xcassets in Resources */, ); @@ -1568,7 +1546,7 @@ ); runOnlyForDeploymentPostprocessing = 0; shellPath = /bin/sh; - shellScript = "./code-sign-cores.sh\n\nmkdir -p ${SRCROOT}/iOS/filters/audio\ncp -f ${SRCBASE}/libretro-common/audio/dsp_filters/*.dsp ${SRCROOT}/iOS/filters/audio/\nmkdir -p ${SRCROOT}/iOS/filters/video\ncp -f ${SRCBASE}/gfx/video_filters/*.filt ${SRCROOT}/iOS/filters/video/\n"; + shellScript = "./make-frameworks.sh\n#./code-sign-cores.sh\n\nmkdir -p ${SRCROOT}/iOS/filters/audio\ncp -f ${SRCBASE}/libretro-common/audio/dsp_filters/*.dsp ${SRCROOT}/iOS/filters/audio/\nmkdir -p ${SRCROOT}/iOS/filters/video\ncp -f ${SRCBASE}/gfx/video_filters/*.filt ${SRCROOT}/iOS/filters/video/\n"; }; 92CC057521FE2D4900FF79F0 /* ShellScript */ = { isa = PBXShellScriptBuildPhase; @@ -1586,7 +1564,7 @@ ); runOnlyForDeploymentPostprocessing = 0; shellPath = /bin/sh; - shellScript = "./code-sign-cores.sh tvos\n\nmkdir -p ${SRCROOT}/tvOS/filters/audio\ncp -f ${SRCBASE}/libretro-common/audio/dsp_filters/*.dsp ${SRCROOT}/tvOS/filters/audio/\nmkdir -p ${SRCROOT}/tvOS/filters/video\ncp -f ${SRCBASE}/gfx/video_filters/*.filt ${SRCROOT}/tvOS/filters/video/\n"; + shellScript = "./make-frameworks.sh tvos\n#./code-sign-cores.sh tvos\n\nmkdir -p ${SRCROOT}/tvOS/filters/audio\ncp -f ${SRCBASE}/libretro-common/audio/dsp_filters/*.dsp ${SRCROOT}/tvOS/filters/audio/\nmkdir -p ${SRCROOT}/tvOS/filters/video\ncp -f ${SRCBASE}/gfx/video_filters/*.filt ${SRCROOT}/tvOS/filters/video/\n"; }; /* End PBXShellScriptBuildPhase section */ @@ -1895,13 +1873,11 @@ ../../gfx/include, ); INFOPLIST_FILE = "$(SRCROOT)/iOS/Info.plist"; - INFOPLIST_KEY_LSApplicationCategoryType = "public.app-category.games"; IPHONEOS_DEPLOYMENT_TARGET = 13.0; LD_NO_PIE = NO; LD_RUNPATH_SEARCH_PATHS = ( "$(inherited)", "@executable_path/Frameworks", - "@executable_path/modules", ); LIBRARY_SEARCH_PATHS = "$(PROJECT_DIR)/iOS/modules"; MARKETING_VERSION = 1.18.0; @@ -1970,13 +1946,11 @@ ../../gfx/include, ); INFOPLIST_FILE = "$(SRCROOT)/iOS/Info.plist"; - INFOPLIST_KEY_LSApplicationCategoryType = "public.app-category.games"; IPHONEOS_DEPLOYMENT_TARGET = 13.0; LD_NO_PIE = NO; LD_RUNPATH_SEARCH_PATHS = ( "$(inherited)", "@executable_path/Frameworks", - "@executable_path/modules", ); LIBRARY_SEARCH_PATHS = "$(PROJECT_DIR)/iOS/modules"; MARKETING_VERSION = 1.18.0; @@ -2068,7 +2042,6 @@ ../../gfx/include, ); INFOPLIST_FILE = "$(SRCROOT)/tvOS/Info.plist"; - INFOPLIST_KEY_LSApplicationCategoryType = "public.app-category.games"; LD_RUNPATH_SEARCH_PATHS = ( "$(inherited)", "@executable_path/Frameworks", @@ -2157,7 +2130,6 @@ ../../gfx/include, ); INFOPLIST_FILE = "$(SRCROOT)/tvOS/Info.plist"; - INFOPLIST_KEY_LSApplicationCategoryType = "public.app-category.games"; LD_RUNPATH_SEARCH_PATHS = ( "$(inherited)", "@executable_path/Frameworks", @@ -2237,7 +2209,6 @@ LD_RUNPATH_SEARCH_PATHS = ( "$(inherited)", "@executable_path/../../Frameworks", - "@executable_path/../../modules", ); LIBRARY_SEARCH_PATHS = "$(PROJECT_DIR)/iOS/modules"; MARKETING_VERSION = 1.18.0; @@ -2308,7 +2279,6 @@ LD_RUNPATH_SEARCH_PATHS = ( "$(inherited)", "@executable_path/../../Frameworks", - "@executable_path/../../modules", ); LIBRARY_SEARCH_PATHS = "$(PROJECT_DIR)/iOS/modules"; MARKETING_VERSION = 1.18.0; @@ -2349,6 +2319,7 @@ GCC_WARN_UNINITIALIZED_AUTOS = YES; GCC_WARN_UNUSED_VARIABLE = YES; HEADER_SEARCH_PATHS = ../; + INFOPLIST_KEY_LSApplicationCategoryType = "public.app-category.games"; IPHONEOS_DEPLOYMENT_TARGET = 11.0; LIBRARY_SEARCH_PATHS = ( "$(PROJECT_DIR)/iOS/modules", @@ -2476,6 +2447,7 @@ GCC_WARN_UNINITIALIZED_AUTOS = YES; GCC_WARN_UNUSED_VARIABLE = YES; HEADER_SEARCH_PATHS = ../; + INFOPLIST_KEY_LSApplicationCategoryType = "public.app-category.games"; IPHONEOS_DEPLOYMENT_TARGET = 11.0; LIBRARY_SEARCH_PATHS = ( "$(PROJECT_DIR)/iOS/modules", diff --git a/pkg/apple/iOS/Info.plist b/pkg/apple/iOS/Info.plist index 08d4756af5..11d753a048 100644 --- a/pkg/apple/iOS/Info.plist +++ b/pkg/apple/iOS/Info.plist @@ -4,12 +4,22 @@ ALTBundleIdentifier $(PRODUCT_BUNDLE_IDENTIFIER) + ALTDeviceID + $(TARGET_DEVICE_IDENTIFIER) CFBundleDevelopmentRegion en CFBundleDisplayName RetroArch CFBundleDocumentTypes + + CFBundleTypeName + ROM + LSItemContentTypes + + com.libretro.rom + + CFBundleTypeName All Files @@ -36,8 +46,6 @@ APPL CFBundleShortVersionString $(MARKETING_VERSION) - CFBundleSignature - ???? CFBundleVersion $(CURRENT_PROJECT_VERSION) LSApplicationCategoryType @@ -52,11 +60,7 @@ _ra_netplay._tcp NSLocalNetworkUsageDescription - RetroArch uses the local network to find and communicate with AltServer to enable JIT. - ALTDeviceID - $(TARGET_DEVICE_IDENTIFIER) - NSCameraUsageDescription - YES + RetroArch uses the local network to find local Netplay participants. UIApplicationExitsOnSuspend UIFileSharingEnabled @@ -65,7 +69,7 @@ Launch Screen UIRequiredDeviceCapabilities - armv7 + arm64 UIRequiresFullScreen @@ -87,5 +91,256 @@ UIViewControllerBasedStatusBarAppearance + GCSupportedGameControllers + + + ProfileName + ExtendedGamepad + + + ProfileName + DirectionalGamepad + + + ProfileName + MicroGamepad + + + GCSupportsControllerUserInteraction + + UTImportedTypeDeclarations + + + UTTypeConformsTo + + public.data + + UTTypeDescription + ROM file + UTTypeIconFiles + + UTTypeIdentifier + com.libretro.rom + UTTypeTagSpecification + + public.filename-extension + + . + 128 + 20 + 2hd + 32x + 40 + 60 + 68k + 7z + 88d + 8xg + 8xk + 8xp + 98d + V32 + a0 + a26 + a52 + a78 + adf + adz + atr + atx + ay + b0 + bas + bin + bms + bs + bsx + car + cas + cbn + ccd + cdf + cdg + cdt + cgb + chd + chf + cmd + col + com + cpr + crt + cso + cue + d2m + d4m + d64 + d6z + d71 + d7z + d80 + d81 + d82 + d88 + d8z + d98 + dat + dcm + dim + dirksimple + dmg + dms + dsi + dsk + dtf + dup + dx2 + easyrpg + elf + exe + fd + fdd + fdi + fds + fig + g41 + g4z + g64 + g6z + game + gb + gba + gbc + gbs + gd3 + gd7 + gen + gg + gym + gz + hdd + hdf + hdi + hdm + hdn + hdz + hes + ids + img + info + int + ipf + iso + k7 + kcr + kss + ldb + lha + lnx + lyx + m3u + m5 + m7 + md + mdf + mds + mdx + mgw + mx1 + mx2 + n64 + nbz + ndd + nds + neo + nes + ngc + ngp + ngpc + nhd + nib + npc + nrg + nsf + nsfe + o + ogv + p00 + pak + pbp + pc2 + pce + pco + pcv2 + prg + prx + ri + rom + rp9 + rzx + sap + sc + scl + sf + sfc + sg + sgb + sgd + sgx + slave + smc + smd + sms + sna + spc + st + sv + swc + t64 + tap + tfd + thd + tic + toc + trd + trn + tvcwav + tzx + u1 + uae + unf + unif + v32 + v64 + vb + vboy + vec + vfl + vgm + vgz + voc + vsf + wasm + wav + ws + wsc + x64 + x6z + xdf + xex + xfd + z1 + z3 + z64 + z80 + zip + + public.mime-type + + com.libretro.rom + + + + diff --git a/pkg/apple/iOS/fw.tmpl b/pkg/apple/iOS/fw.tmpl new file mode 100644 index 0000000000..509712694d --- /dev/null +++ b/pkg/apple/iOS/fw.tmpl @@ -0,0 +1,22 @@ + + + + + CFBundleExecutable + %CORE% + CFBundleName + %CORE% + CFBundleIdentifier + %IDENTIFIER% + CFBundleShortVersionString + 1.0.0 + CFBundleVersion + 1.0.0 + MinimumOSVersion + 1.0 + CFBundlePackageType + FMWK + CFBundleInfoDictionaryVersion + 6.0 + + diff --git a/pkg/apple/make-frameworks.sh b/pkg/apple/make-frameworks.sh new file mode 100755 index 0000000000..b16409395b --- /dev/null +++ b/pkg/apple/make-frameworks.sh @@ -0,0 +1,41 @@ +#!/bin/bash + +# Prefer the expanded name, if available. +CODE_SIGN_IDENTITY_FOR_ITEMS="${EXPANDED_CODE_SIGN_IDENTITY_NAME}" +if [ "${CODE_SIGN_IDENTITY_FOR_ITEMS}" = "" ] ; then + # Fall back to old behavior. + CODE_SIGN_IDENTITY_FOR_ITEMS="${CODE_SIGN_IDENTITY}" +fi + +echo "Identity:" +echo "${CODE_SIGN_IDENTITY_FOR_ITEMS}" + +if [ "$1" = "tvos" ] ; then + BASE_DIR="tvOS" + SUFFIX="_tvos" +else + BASE_DIR="iOS" + SUFFIX="_ios" +fi + +mkdir -p "$BASE_DIR"/Frameworks + +for dylib in "$BASE_DIR"/modules/*.dylib ; do + intermediate=$(basename "$dylib") + intermediate="${intermediate/%.dylib/}" + identifier="${intermediate/%$SUFFIX/}" + intermediate="${identifier/%_libretro/}" + fwName="${intermediate}_libretro" + echo Making framework $fwName from $dylib + + fwDir="$BASE_DIR/Frameworks/${fwName}.framework" + mkdir -p "$fwDir" + lipo -create "$dylib" -output "$fwDir/$fwName" + if codesign --display -r- "$fwDir/$fwName" 2>&1 | grep -q "${CODE_SIGN_IDENTITY_FOR_ITEMS}" ; then + echo "$fwName already signed" + else + echo "signing $fwName" + codesign --force --verbose --sign "${CODE_SIGN_IDENTITY_FOR_ITEMS}" "$fwDir/$fwName" + fi + sed -e "s,%CORE%,$fwName," -e "s,%IDENTIFIER%,$identifier," iOS/fw.tmpl > "$fwDir/Info.plist" +done diff --git a/pkg/apple/tvOS/Info.plist b/pkg/apple/tvOS/Info.plist index a0ebe6cb14..ed1ecc42f6 100644 --- a/pkg/apple/tvOS/Info.plist +++ b/pkg/apple/tvOS/Info.plist @@ -43,7 +43,114 @@ arm64 - UIUserInterfaceStyle - Automatic + GCSupportedGameControllers + + + ProfileName + ExtendedGamepad + + + ProfileName + DirectionalGamepad + + + ProfileName + MicroGamepad + + + GCSupportsControllerUserInteraction + + CFBundleDocumentTypes + + + CFBundleTypeName + ROM + LSItemContentTypes + + com.libretro.rom + + + + CFBundleTypeName + All Files + LSItemContentTypes + + public.data + public.content + + + + UTImportedTypeDeclarations + + + UTTypeConformsTo + + public.data + + UTTypeDescription + ROM file + UTTypeIconFiles + + UTTypeIdentifier + com.libretro.rom + UTTypeTagSpecification + + public.filename-extension + + ROM + rom + cue + bin + a78 + a26 + a52 + sms + smc + sfc + fig + sfc + gb + gbc + sgb + gba + nes + fds + lnx + ngp + ngc + ngpc + npc + pce + ws + wsc + vb + n64 + z64 + gen + md + gg + smd + 32x + 32X + min + 7z + cdi + gdi + bios + msx + col + rar + z80 + tzx + chd + rvz + + public.mime-type + + com.libretro.rom + + + + diff --git a/pkg/apple/update-cores.sh b/pkg/apple/update-cores.sh index 4187c67300..b7c4708b44 100755 --- a/pkg/apple/update-cores.sh +++ b/pkg/apple/update-cores.sh @@ -70,22 +70,120 @@ function update_dylib() { allcores= function get_all_cores() { - if [ -z "$allcores"] ; then + if [ -z "$allcores" ] ; then allcores=($(curl $CURL_DEBUG $URL_BASE/ | sed -e 's/>[^<]\+\.dylib.zip<' | sed -e 's/.*>\(.*\)\.zip<.*/\1/')) fi } dylibs=() -if [ -n "$1" ]; then +function find_dylib() { + if [[ "${allcores[*]}" =~ "${1}_libretro_${PLATFORM}.dylib" ]] ; then + dylibs+=("${1}_libretro_${PLATFORM}.dylib") + elif [[ "${allcores[*]}" =~ "${1}_libretro.dylib" ]] ; then + dylibs+=("${1}_libretro.dylib") + elif [[ "${allcores[*]}" =~ "${1}" ]] ; then + dylibs+=("${1}") + fi +} + +if [ "$1" = "appstore" ] ; then + get_all_cores + exports=( + mupen64plus_next + #kronos + pcsx_rearmed + easyrpg + dinothawr + sameboy + mgba + gpsp + mesen + mesen-s + genesis_plus_gx + genesis_plus_gx_wide + fbneo + bsnes + bsnes_hd_beta + #flycast + desmume + ppsspp + stella + stella2014 + snes9x + snes9x2005 + snes9x2010 + vbam + vba_next + picodrive + np2kai + atari800 + prosystem + cap32 + crocods + pocketcdg + neocd + nestopia + fceumm + race + quicknes + smsplus + #blastem + vice_x128 + vice_x64 + vice_x64sc + vice_xcbm2 + vice_xcbm5x0 + vice_xpet + vice_xplus4 + vice_xscpu64 + vice_xvic + puae + mednafen_pce + mednafen_pce_fast + mednafen_supergrafx + mednafen_vb + mednafen_wswan + mednafen_psx + mednafen_psx_hw + mednafen_saturn + potator + vecx + tgbdual + gw + fuse + freechaf + gambatte + freeintv + gearsystem + gearboy + handy + tic80 + wasm4 + gme + tyrquake + theodore + a5200 + #play + bluemsx + px68k + xrick + ep128emu_core + mojozork + numero + dirksimple + scummvm + virtualxt + geolith + vircon32 + melondsds + ) + for dylib in "${exports[@]}" ; do + find_dylib $dylib + done +elif [ -n "$1" ]; then get_all_cores while [ -n "$1" ] ; do - if [[ "${allcores[*]}" =~ "${1}_libretro_${PLATFORM}.dylib" ]] ; then - dylibs+=("${1}_libretro_${PLATFORM}.dylib") - elif [[ "${allcores[*]}" =~ "${1}_libretro.dylib" ]] ; then - dylibs+=("${1}_libretro.dylib") - elif [[ "${allcores[*]}" =~ "${1}" ]] ; then - dylibs+=("${1}") - fi + find_dylib "$1" shift done elif find . -iname \*_libretro\*.dylib | grep -q ^. ; then diff --git a/playlist.c b/playlist.c index 9e3a4cc3a5..eb946f90a5 100644 --- a/playlist.c +++ b/playlist.c @@ -1127,8 +1127,23 @@ void playlist_resolve_path(enum playlist_file_mode mode, if (mode == PLAYLIST_LOAD) { - fill_pathname_expand_special(tmp, path, sizeof(tmp)); - strlcpy(path, tmp, len); + if (is_core && + string_starts_with(path, ":/modules/") && + string_ends_with(path, ".dylib")) + { + path[string_index_last_occurance(path, '.')] = '\0'; + if (string_ends_with(path, "_ios")) + path[string_index_last_occurance(path, '_')] = '\0'; + strlcpy(tmp, ":/Frameworks/", STRLEN_CONST(":/Frameworks/") + 1); + strlcpy(tmp + STRLEN_CONST(":/Frameworks/"), path + STRLEN_CONST(":/modules/"), sizeof(tmp) - STRLEN_CONST(":/Frameworks/")); + strlcat(tmp, ".framework", sizeof(tmp)); + fill_pathname_expand_special(path, tmp, len); + } + else + { + fill_pathname_expand_special(tmp, path, sizeof(tmp)); + strlcpy(path, tmp, len); + } } else { diff --git a/retroarch.c b/retroarch.c index 5dc30d4583..302275a358 100644 --- a/retroarch.c +++ b/retroarch.c @@ -6435,7 +6435,12 @@ static void retroarch_parse_input_libretro_path(const char *path, size_t path_le path_stats = path_stat(path); /* Check if path is a directory */ - if ((path_stats & RETRO_VFS_STAT_IS_DIRECTORY) != 0) + if ( + ((path_stats & RETRO_VFS_STAT_IS_DIRECTORY) != 0) +#if IOS + && !string_ends_with(path, ".framework") +#endif + ) { path_clear(RARCH_PATH_CORE); diff --git a/ui/drivers/ui_cocoatouch.m b/ui/drivers/ui_cocoatouch.m index 1462e62477..b343431ff8 100644 --- a/ui/drivers/ui_cocoatouch.m +++ b/ui/drivers/ui_cocoatouch.m @@ -656,8 +656,11 @@ enum NSFileManager *manager = [NSFileManager defaultManager]; NSString *filename = (NSString*)url.path.lastPathComponent; NSError *error = nil; - NSString *destination = [self.documentsDirectory stringByAppendingPathComponent:filename]; - /* Copy file to documents directory if it's not already + 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]; + /* Copy file to documents directory if it's not already * inside Documents directory */ if ([url startAccessingSecurityScopedResource]) { if (![[url path] containsString: self.documentsDirectory]) @@ -665,6 +668,13 @@ enum [manager copyItemAtPath:[url path] toPath:destination error:&error]; [url stopAccessingSecurityScopedResource]; } + task_push_dbscan( + settings->paths.directory_playlist, + settings->paths.path_content_database, + fullpath, + false, + false, + NULL); return true; }