iOS QOL improvements (#16444)

* iOS/tvOS: bundle cores as frameworks as opposed to dylibs

* iOS/tvOS: update plist to indicate controller support

* iOS/tvOS: living within the sandbox

* iOS/tvOS: import content through share sheet

* iOS/tvOS: default audio sync off due to crash on background

* iOS/tvOS: don't try altkit if there's no reason to

* iOS/tvOS: enumerate cores for appstore distribution
This commit is contained in:
Eric Warmenhoven 2024-04-18 06:01:39 -04:00 committed by GitHub
parent 2ef8bb4eb4
commit 5fd4eb905c
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
24 changed files with 769 additions and 93 deletions

View file

@ -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;
}

View file

@ -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)

View file

@ -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)

View file

@ -54,6 +54,7 @@
#include <streams/file_stream.h>
#include <features/features_cpu.h>
#include <string/stdstring.h>
#include <lists/dir_list.h>
#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;

View file

@ -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';

View file

@ -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

View file

@ -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

View file

@ -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,

View file

@ -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(

View file

@ -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));

View file

@ -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);

View file

@ -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

View file

@ -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);

View file

@ -1,4 +1,6 @@
xcuserdata/
xcshareddata/
iOS/filters/
iOS/Frameworks/
tvOS/filters/
tvOS/Frameworks/

View file

@ -25,6 +25,7 @@
#endif
#include <string/stdstring.h>
#include <file/file_path.h>
#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;

View file

@ -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 = "<group>"; };
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 = "<group>"; };
0789FC2E2A07845300D042B7 /* AltKit */ = {isa = PBXFileReference; lastKnownFileType = wrapper; name = AltKit; path = Frameworks/AltKit; sourceTree = "<group>"; };
07B7872C29E8FE8F0088B74F /* filters */ = {isa = PBXFileReference; lastKnownFileType = folder; path = filters; sourceTree = "<group>"; };
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",

View file

@ -4,12 +4,22 @@
<dict>
<key>ALTBundleIdentifier</key>
<string>$(PRODUCT_BUNDLE_IDENTIFIER)</string>
<key>ALTDeviceID</key>
<string>$(TARGET_DEVICE_IDENTIFIER)</string>
<key>CFBundleDevelopmentRegion</key>
<string>en</string>
<key>CFBundleDisplayName</key>
<string>RetroArch</string>
<key>CFBundleDocumentTypes</key>
<array>
<dict>
<key>CFBundleTypeName</key>
<string>ROM</string>
<key>LSItemContentTypes</key>
<array>
<string>com.libretro.rom</string>
</array>
</dict>
<dict>
<key>CFBundleTypeName</key>
<string>All Files</string>
@ -36,8 +46,6 @@
<string>APPL</string>
<key>CFBundleShortVersionString</key>
<string>$(MARKETING_VERSION)</string>
<key>CFBundleSignature</key>
<string>????</string>
<key>CFBundleVersion</key>
<string>$(CURRENT_PROJECT_VERSION)</string>
<key>LSApplicationCategoryType</key>
@ -52,11 +60,7 @@
<string>_ra_netplay._tcp</string>
</array>
<key>NSLocalNetworkUsageDescription</key>
<string>RetroArch uses the local network to find and communicate with AltServer to enable JIT.</string>
<key>ALTDeviceID</key>
<string>$(TARGET_DEVICE_IDENTIFIER)</string>
<key>NSCameraUsageDescription</key>
<string>YES</string>
<string>RetroArch uses the local network to find local Netplay participants.</string>
<key>UIApplicationExitsOnSuspend</key>
<false/>
<key>UIFileSharingEnabled</key>
@ -65,7 +69,7 @@
<string>Launch Screen</string>
<key>UIRequiredDeviceCapabilities</key>
<array>
<string>armv7</string>
<string>arm64</string>
</array>
<key>UIRequiresFullScreen</key>
<true/>
@ -87,5 +91,256 @@
</array>
<key>UIViewControllerBasedStatusBarAppearance</key>
<false/>
<key>GCSupportedGameControllers</key>
<array>
<dict>
<key>ProfileName</key>
<string>ExtendedGamepad</string>
</dict>
<dict>
<key>ProfileName</key>
<string>DirectionalGamepad</string>
</dict>
<dict>
<key>ProfileName</key>
<string>MicroGamepad</string>
</dict>
</array>
<key>GCSupportsControllerUserInteraction</key>
<true/>
<key>UTImportedTypeDeclarations</key>
<array>
<dict>
<key>UTTypeConformsTo</key>
<array>
<string>public.data</string>
</array>
<key>UTTypeDescription</key>
<string>ROM file</string>
<key>UTTypeIconFiles</key>
<array/>
<key>UTTypeIdentifier</key>
<string>com.libretro.rom</string>
<key>UTTypeTagSpecification</key>
<dict>
<key>public.filename-extension</key>
<array>
<string>.</string>
<string>128</string>
<string>20</string>
<string>2hd</string>
<string>32x</string>
<string>40</string>
<string>60</string>
<string>68k</string>
<string>7z</string>
<string>88d</string>
<string>8xg</string>
<string>8xk</string>
<string>8xp</string>
<string>98d</string>
<string>V32</string>
<string>a0</string>
<string>a26</string>
<string>a52</string>
<string>a78</string>
<string>adf</string>
<string>adz</string>
<string>atr</string>
<string>atx</string>
<string>ay</string>
<string>b0</string>
<string>bas</string>
<string>bin</string>
<string>bms</string>
<string>bs</string>
<string>bsx</string>
<string>car</string>
<string>cas</string>
<string>cbn</string>
<string>ccd</string>
<string>cdf</string>
<string>cdg</string>
<string>cdt</string>
<string>cgb</string>
<string>chd</string>
<string>chf</string>
<string>cmd</string>
<string>col</string>
<string>com</string>
<string>cpr</string>
<string>crt</string>
<string>cso</string>
<string>cue</string>
<string>d2m</string>
<string>d4m</string>
<string>d64</string>
<string>d6z</string>
<string>d71</string>
<string>d7z</string>
<string>d80</string>
<string>d81</string>
<string>d82</string>
<string>d88</string>
<string>d8z</string>
<string>d98</string>
<string>dat</string>
<string>dcm</string>
<string>dim</string>
<string>dirksimple</string>
<string>dmg</string>
<string>dms</string>
<string>dsi</string>
<string>dsk</string>
<string>dtf</string>
<string>dup</string>
<string>dx2</string>
<string>easyrpg</string>
<string>elf</string>
<string>exe</string>
<string>fd</string>
<string>fdd</string>
<string>fdi</string>
<string>fds</string>
<string>fig</string>
<string>g41</string>
<string>g4z</string>
<string>g64</string>
<string>g6z</string>
<string>game</string>
<string>gb</string>
<string>gba</string>
<string>gbc</string>
<string>gbs</string>
<string>gd3</string>
<string>gd7</string>
<string>gen</string>
<string>gg</string>
<string>gym</string>
<string>gz</string>
<string>hdd</string>
<string>hdf</string>
<string>hdi</string>
<string>hdm</string>
<string>hdn</string>
<string>hdz</string>
<string>hes</string>
<string>ids</string>
<string>img</string>
<string>info</string>
<string>int</string>
<string>ipf</string>
<string>iso</string>
<string>k7</string>
<string>kcr</string>
<string>kss</string>
<string>ldb</string>
<string>lha</string>
<string>lnx</string>
<string>lyx</string>
<string>m3u</string>
<string>m5</string>
<string>m7</string>
<string>md</string>
<string>mdf</string>
<string>mds</string>
<string>mdx</string>
<string>mgw</string>
<string>mx1</string>
<string>mx2</string>
<string>n64</string>
<string>nbz</string>
<string>ndd</string>
<string>nds</string>
<string>neo</string>
<string>nes</string>
<string>ngc</string>
<string>ngp</string>
<string>ngpc</string>
<string>nhd</string>
<string>nib</string>
<string>npc</string>
<string>nrg</string>
<string>nsf</string>
<string>nsfe</string>
<string>o</string>
<string>ogv</string>
<string>p00</string>
<string>pak</string>
<string>pbp</string>
<string>pc2</string>
<string>pce</string>
<string>pco</string>
<string>pcv2</string>
<string>prg</string>
<string>prx</string>
<string>ri</string>
<string>rom</string>
<string>rp9</string>
<string>rzx</string>
<string>sap</string>
<string>sc</string>
<string>scl</string>
<string>sf</string>
<string>sfc</string>
<string>sg</string>
<string>sgb</string>
<string>sgd</string>
<string>sgx</string>
<string>slave</string>
<string>smc</string>
<string>smd</string>
<string>sms</string>
<string>sna</string>
<string>spc</string>
<string>st</string>
<string>sv</string>
<string>swc</string>
<string>t64</string>
<string>tap</string>
<string>tfd</string>
<string>thd</string>
<string>tic</string>
<string>toc</string>
<string>trd</string>
<string>trn</string>
<string>tvcwav</string>
<string>tzx</string>
<string>u1</string>
<string>uae</string>
<string>unf</string>
<string>unif</string>
<string>v32</string>
<string>v64</string>
<string>vb</string>
<string>vboy</string>
<string>vec</string>
<string>vfl</string>
<string>vgm</string>
<string>vgz</string>
<string>voc</string>
<string>vsf</string>
<string>wasm</string>
<string>wav</string>
<string>ws</string>
<string>wsc</string>
<string>x64</string>
<string>x6z</string>
<string>xdf</string>
<string>xex</string>
<string>xfd</string>
<string>z1</string>
<string>z3</string>
<string>z64</string>
<string>z80</string>
<string>zip</string>
</array>
<key>public.mime-type</key>
<array>
<string>com.libretro.rom</string>
</array>
</dict>
</dict>
</array>
</dict>
</plist>

22
pkg/apple/iOS/fw.tmpl Normal file
View file

@ -0,0 +1,22 @@
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
<key>CFBundleExecutable</key>
<string>%CORE%</string>
<key>CFBundleName</key>
<string>%CORE%</string>
<key>CFBundleIdentifier</key>
<string>%IDENTIFIER%</string>
<key>CFBundleShortVersionString</key>
<string>1.0.0</string>
<key>CFBundleVersion</key>
<string>1.0.0</string>
<key>MinimumOSVersion</key>
<string>1.0</string>
<key>CFBundlePackageType</key>
<string>FMWK</string>
<key>CFBundleInfoDictionaryVersion</key>
<string>6.0</string>
</dict>
</plist>

41
pkg/apple/make-frameworks.sh Executable file
View file

@ -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

View file

@ -43,7 +43,114 @@
<array>
<string>arm64</string>
</array>
<key>UIUserInterfaceStyle</key>
<string>Automatic</string>
<key>GCSupportedGameControllers</key>
<array>
<dict>
<key>ProfileName</key>
<string>ExtendedGamepad</string>
</dict>
<dict>
<key>ProfileName</key>
<string>DirectionalGamepad</string>
</dict>
<dict>
<key>ProfileName</key>
<string>MicroGamepad</string>
</dict>
</array>
<key>GCSupportsControllerUserInteraction</key>
<true/>
<key>CFBundleDocumentTypes</key>
<array>
<dict>
<key>CFBundleTypeName</key>
<string>ROM</string>
<key>LSItemContentTypes</key>
<array>
<string>com.libretro.rom</string>
</array>
</dict>
<dict>
<key>CFBundleTypeName</key>
<string>All Files</string>
<key>LSItemContentTypes</key>
<array>
<string>public.data</string>
<string>public.content</string>
</array>
</dict>
</array>
<key>UTImportedTypeDeclarations</key>
<array>
<dict>
<key>UTTypeConformsTo</key>
<array>
<string>public.data</string>
</array>
<key>UTTypeDescription</key>
<string>ROM file</string>
<key>UTTypeIconFiles</key>
<array/>
<key>UTTypeIdentifier</key>
<string>com.libretro.rom</string>
<key>UTTypeTagSpecification</key>
<dict>
<key>public.filename-extension</key>
<array>
<string>ROM</string>
<string>rom</string>
<string>cue</string>
<string>bin</string>
<string>a78</string>
<string>a26</string>
<string>a52</string>
<string>sms</string>
<string>smc</string>
<string>sfc</string>
<string>fig</string>
<string>sfc</string>
<string>gb</string>
<string>gbc</string>
<string>sgb</string>
<string>gba</string>
<string>nes</string>
<string>fds</string>
<string>lnx</string>
<string>ngp</string>
<string>ngc</string>
<string>ngpc</string>
<string>npc</string>
<string>pce</string>
<string>ws</string>
<string>wsc</string>
<string>vb</string>
<string>n64</string>
<string>z64</string>
<string>gen</string>
<string>md</string>
<string>gg</string>
<string>smd</string>
<string>32x</string>
<string>32X</string>
<string>min</string>
<string>7z</string>
<string>cdi</string>
<string>gdi</string>
<string>bios</string>
<string>msx</string>
<string>col</string>
<string>rar</string>
<string>z80</string>
<string>tzx</string>
<string>chd</string>
<string>rvz</string>
</array>
<key>public.mime-type</key>
<array>
<string>com.libretro.rom</string>
</array>
</dict>
</dict>
</array>
</dict>
</plist>

View file

@ -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/></\n/g' | grep '>[^<]\+\.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

View file

@ -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
{

View file

@ -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);

View file

@ -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;
}