diff --git a/.vscode/launch.json b/.vscode/launch.json index e7552247cc..d55f87de4e 100644 --- a/.vscode/launch.json +++ b/.vscode/launch.json @@ -13,7 +13,7 @@ "stopAtEntry": false, "cwd": "${workspaceFolder}", "environment": [], - "externalConsole": false, + "externalConsole": true, "MIMode": "gdb", "miDebuggerPath": "c:\\msys64\\mingw64\\bin\\gdb.exe", "setupCommands": [ diff --git a/intl/msg_hash_lbl.h b/intl/msg_hash_lbl.h index 7f0af3e3ab..7d2b670981 100644 --- a/intl/msg_hash_lbl.h +++ b/intl/msg_hash_lbl.h @@ -223,6 +223,8 @@ MSG_HASH(MENU_ENUM_LABEL_INPUT_SPLIT_JOYCON, "input_split_joycon") MSG_HASH(MENU_ENUM_LABEL_CORE_LIST, "load_core") +MSG_HASH(MENU_ENUM_LABEL_SIDELOAD_CORE_LIST, + "sideload_core") MSG_HASH(MENU_ENUM_LABEL_CORE_OPTIONS, "core_options") MSG_HASH(MENU_ENUM_LABEL_CORE_OPTION_ENTRY, diff --git a/intl/msg_hash_us.h b/intl/msg_hash_us.h index 63db7a205c..a31e28f937 100644 --- a/intl/msg_hash_us.h +++ b/intl/msg_hash_us.h @@ -673,6 +673,18 @@ MSG_HASH( MENU_ENUM_LABEL_VALUE_CORE_LIST, "Load Core" ) +MSG_HASH( + MENU_ENUM_LABEL_VALUE_SIDELOAD_CORE_LIST, + "Install or Restore a Core" + ) +MSG_HASH( + MENU_ENUM_LABEL_VALUE_SIDELOAD_CORE_ERROR, + "Core installation failed" + ) +MSG_HASH( + MENU_ENUM_LABEL_VALUE_SIDELOAD_CORE_SUCCESS, + "Core installation succesful" + ) MSG_HASH( MENU_ENUM_LABEL_VALUE_CORE_OPTIONS, "Options" @@ -4890,6 +4902,10 @@ MSG_HASH( MENU_ENUM_SUBLABEL_CORE_LIST, "Select which core to use." ) +MSG_HASH( + MENU_ENUM_SUBLABEL_SIDELOAD_CORE_LIST, + "Install or restore a core from the downloads directory." + ) MSG_HASH( MENU_ENUM_SUBLABEL_LOAD_CONTENT_LIST, "Select which content to start." diff --git a/menu/cbs/menu_cbs_ok.c b/menu/cbs/menu_cbs_ok.c index e87d73ca34..187bb281dc 100644 --- a/menu/cbs/menu_cbs_ok.c +++ b/menu/cbs/menu_cbs_ok.c @@ -87,6 +87,7 @@ enum ACTION_OK_SUBSYSTEM_ADD, ACTION_OK_LOAD_CONFIG_FILE, ACTION_OK_LOAD_CORE, + ACTION_OK_SIDELOAD_CORE, ACTION_OK_LOAD_WALLPAPER, ACTION_OK_SET_PATH, ACTION_OK_SET_PATH_AUDIO_FILTER, @@ -588,6 +589,14 @@ int generic_action_ok_displaylist_push(const char *path, info_label = label; dl_type = DISPLAYLIST_FILE_BROWSER_SELECT_CORE; break; + case ACTION_OK_DL_SIDELOAD_CORE_LIST: + filebrowser_clear_type(); + info.type = type; + info.directory_ptr = idx; + info_path = settings->paths.directory_core_assets; + info_label = label; + dl_type = DISPLAYLIST_FILE_BROWSER_SELECT_SIDELOAD_CORE; + break; case ACTION_OK_DL_CONTENT_COLLECTION_LIST: info.type = type; info.directory_ptr = idx; @@ -1234,6 +1243,54 @@ static int generic_action_ok_command(enum event_command cmd) return 0; } +/* TO-DO: Localization for errors */ +static bool file_copy(char* src_path, char* dst_path, char* msg, size_t size) +{ + + FILE *src, *dst; + char buffer[100]; + int numr, numw; + bool ret = true; + + src = fopen(src_path, "rb"); + + if (!src) + { + strlcpy(msg, "unable to open source file", size); + ret = false; + } + + dst = fopen(dst_path, "wb"); + if (!dst) + { + strlcpy(msg, "unable to open destination file", size); + ret = false; + } + + while (!feof(src)) + { + memset(buffer, 0, sizeof(buffer)); + numr = fread(buffer, 1, 100, src); + if (ferror(dst) != 0) + { + strlcpy(msg, "error reading file\n", size); + ret = false; + break; + } + + numw = fwrite(buffer, sizeof(char), numr, dst); + if (numw != numr) + { + strlcpy(msg, "error writing to file\n", size); + ret = false; + break; + } + } + fclose(src); + fclose(dst); + return ret; +} + static int generic_action_ok(const char *path, const char *label, unsigned type, size_t idx, size_t entry_idx, unsigned id, enum msg_hash_enums flush_id) @@ -1300,6 +1357,30 @@ static int generic_action_ok(const char *path, } } break; + case ACTION_OK_SIDELOAD_CORE: + { + settings_t *settings = config_get_ptr(); + char destination_path[PATH_MAX_LENGTH]; + char message[PATH_MAX_LENGTH]; + + fill_pathname_join(destination_path, settings->paths.directory_libretro, path_basename(action_path), sizeof(destination_path)); + + if(!file_copy(action_path, destination_path, message, sizeof(message))) + { + runloop_msg_queue_push(msg_hash_to_str( + MENU_ENUM_LABEL_VALUE_SIDELOAD_CORE_ERROR), 1, 100, true); + RARCH_LOG("[sideload] %s: %s\n", msg_hash_to_str( + MENU_ENUM_LABEL_VALUE_SIDELOAD_CORE_ERROR), message); + RARCH_LOG(msg_hash_to_str(MENU_ENUM_LABEL_VALUE_SIDELOAD_CORE_ERROR)); + } + else + { + runloop_msg_queue_push(msg_hash_to_str( + MENU_ENUM_LABEL_VALUE_SIDELOAD_CORE_SUCCESS), 1, 100, true); + RARCH_LOG("[sideload] %s\n", msg_hash_to_str(MENU_ENUM_LABEL_VALUE_SIDELOAD_CORE_SUCCESS)); + } + } + break; case ACTION_OK_LOAD_CONFIG_FILE: { settings_t *settings = config_get_ptr(); @@ -1470,6 +1551,7 @@ default_action_ok_set(action_ok_set_path_videofilter, ACTION_OK_SET_PATH_AUDIO_F default_action_ok_set(action_ok_set_path_overlay, ACTION_OK_SET_PATH_OVERLAY, MSG_UNKNOWN) default_action_ok_set(action_ok_set_path, ACTION_OK_SET_PATH, MSG_UNKNOWN) default_action_ok_set(action_ok_load_core, ACTION_OK_LOAD_CORE, MSG_UNKNOWN) +default_action_ok_set(action_ok_sideload_core, ACTION_OK_SIDELOAD_CORE, MSG_UNKNOWN) default_action_ok_set(action_ok_config_load, ACTION_OK_LOAD_CONFIG_FILE, MSG_UNKNOWN) default_action_ok_set(action_ok_disk_image_append, ACTION_OK_APPEND_DISK_IMAGE, MSG_UNKNOWN) default_action_ok_set(action_ok_subsystem_add, ACTION_OK_SUBSYSTEM_ADD, MSG_UNKNOWN) @@ -3832,6 +3914,7 @@ default_action_ok_func(action_ok_rdb_entry, ACTION_OK_DL_RDB_ENTRY) default_action_ok_func(action_ok_mixer_stream_actions, ACTION_OK_DL_MIXER_STREAM_SETTINGS_LIST) default_action_ok_func(action_ok_browse_url_list, ACTION_OK_DL_BROWSE_URL_LIST) default_action_ok_func(action_ok_core_list, ACTION_OK_DL_CORE_LIST) +default_action_ok_func(action_ok_sideload_core_list, ACTION_OK_DL_SIDELOAD_CORE_LIST) default_action_ok_func(action_ok_cheat_file, ACTION_OK_DL_CHEAT_FILE) default_action_ok_func(action_ok_cheat_file_append, ACTION_OK_DL_CHEAT_FILE_APPEND) default_action_ok_func(action_ok_playlist_collection, ACTION_OK_DL_PLAYLIST_COLLECTION) @@ -4990,6 +5073,9 @@ static int menu_cbs_init_bind_ok_compare_label(menu_file_list_cbs_t *cbs, case MENU_ENUM_LABEL_FILE_BROWSER_CORE: BIND_ACTION_OK(cbs, action_ok_load_core); break; + case MENU_ENUM_LABEL_FILE_BROWSER_SIDELOAD_CORE: + BIND_ACTION_OK(cbs, action_ok_sideload_core); + break; case MENU_ENUM_LABEL_FILE_BROWSER_CORE_SELECT_FROM_COLLECTION: case MENU_ENUM_LABEL_FILE_BROWSER_CORE_SELECT_FROM_COLLECTION_CURRENT_CORE: BIND_ACTION_OK(cbs, action_ok_core_deferred_set); @@ -5299,6 +5385,9 @@ static int menu_cbs_init_bind_ok_compare_label(menu_file_list_cbs_t *cbs, case MENU_ENUM_LABEL_CORE_LIST: BIND_ACTION_OK(cbs, action_ok_core_list); break; + case MENU_ENUM_LABEL_SIDELOAD_CORE_LIST: + BIND_ACTION_OK(cbs, action_ok_sideload_core_list); + break; case MENU_ENUM_LABEL_DISK_IMAGE_APPEND: BIND_ACTION_OK(cbs, action_ok_disk_image_append_list); break; @@ -5775,6 +5864,9 @@ static int menu_cbs_init_bind_ok_compare_type(menu_file_list_cbs_t *cbs, case MENU_LABEL_CORE_LIST: BIND_ACTION_OK(cbs, action_ok_load_core); break; + case MENU_LABEL_SIDELOAD_CORE_LIST: + BIND_ACTION_OK(cbs, action_ok_sideload_core); + break; } } break; diff --git a/menu/cbs/menu_cbs_sublabel.c b/menu/cbs/menu_cbs_sublabel.c index 56f2efa9bb..0f3a27756c 100644 --- a/menu/cbs/menu_cbs_sublabel.c +++ b/menu/cbs/menu_cbs_sublabel.c @@ -188,6 +188,7 @@ default_sublabel_macro(action_bind_sublabel_cheevos_username, MENU_ default_sublabel_macro(action_bind_sublabel_cheevos_password, MENU_ENUM_SUBLABEL_CHEEVOS_PASSWORD) default_sublabel_macro(action_bind_sublabel_video_post_filter_record, MENU_ENUM_SUBLABEL_VIDEO_POST_FILTER_RECORD) default_sublabel_macro(action_bind_sublabel_core_list, MENU_ENUM_SUBLABEL_CORE_LIST) +default_sublabel_macro(action_bind_sublabel_sideload_core_list, MENU_ENUM_SUBLABEL_SIDELOAD_CORE_LIST) default_sublabel_macro(action_bind_sublabel_content_list, MENU_ENUM_SUBLABEL_LOAD_CONTENT_LIST) default_sublabel_macro(action_bind_sublabel_content_special, MENU_ENUM_SUBLABEL_LOAD_CONTENT_SPECIAL) default_sublabel_macro(action_bind_sublabel_network_information, MENU_ENUM_SUBLABEL_NETWORK_INFORMATION) @@ -1673,6 +1674,9 @@ int menu_cbs_init_bind_sublabel(menu_file_list_cbs_t *cbs, case MENU_ENUM_LABEL_CORE_LIST: BIND_ACTION_SUBLABEL(cbs, action_bind_sublabel_core_list); break; + case MENU_ENUM_LABEL_SIDELOAD_CORE_LIST: + BIND_ACTION_SUBLABEL(cbs, action_bind_sublabel_sideload_core_list); + break; case MENU_ENUM_LABEL_VIDEO_POST_FILTER_RECORD: BIND_ACTION_SUBLABEL(cbs, action_bind_sublabel_video_post_filter_record); break; diff --git a/menu/cbs/menu_cbs_title.c b/menu/cbs/menu_cbs_title.c index 9b3e3be0b7..c619758930 100644 --- a/menu/cbs/menu_cbs_title.c +++ b/menu/cbs/menu_cbs_title.c @@ -99,6 +99,7 @@ default_title_macro(action_get_download_core_content_list, MENU_ENUM_LABEL_ default_title_macro(action_get_user_accounts_list, MENU_ENUM_LABEL_VALUE_ACCOUNTS_LIST) default_title_macro(action_get_core_information_list, MENU_ENUM_LABEL_VALUE_CORE_INFORMATION) default_title_macro(action_get_core_list, MENU_ENUM_LABEL_VALUE_CORE_LIST) +default_title_macro(action_get_sideload_core_list, MENU_ENUM_LABEL_VALUE_SIDELOAD_CORE_LIST) default_title_macro(action_get_online_updater_list, MENU_ENUM_LABEL_VALUE_ONLINE_UPDATER) default_title_macro(action_get_netplay_list, MENU_ENUM_LABEL_VALUE_NETPLAY) default_title_macro(action_get_online_thumbnails_updater_list, MENU_ENUM_LABEL_VALUE_THUMBNAILS_UPDATER_LIST) @@ -718,6 +719,9 @@ static int menu_cbs_init_bind_title_compare_label(menu_file_list_cbs_t *cbs, case MENU_ENUM_LABEL_CORE_LIST: BIND_ACTION_GET_TITLE(cbs, action_get_core_list); break; + case MENU_ENUM_LABEL_SIDELOAD_CORE_LIST: + BIND_ACTION_GET_TITLE(cbs, action_get_sideload_core_list); + break; case MENU_ENUM_LABEL_LOAD_CONTENT_SPECIAL: BIND_ACTION_GET_TITLE(cbs, action_get_load_content_special); break; @@ -1047,6 +1051,9 @@ static int menu_cbs_init_bind_title_compare_label(menu_file_list_cbs_t *cbs, case MENU_LABEL_CORE_LIST: BIND_ACTION_GET_TITLE(cbs, action_get_core_list); break; + case MENU_LABEL_SIDELOAD_CORE_LIST: + BIND_ACTION_GET_TITLE(cbs, action_get_core_list); + break; case MENU_ENUM_LABEL_LOAD_CONTENT_SPECIAL: BIND_ACTION_GET_TITLE(cbs, action_get_load_content_special); break; diff --git a/menu/drivers/ozone/ozone.c b/menu/drivers/ozone/ozone.c index 1ef225cfd5..3f1abdf97b 100644 --- a/menu/drivers/ozone/ozone.c +++ b/menu/drivers/ozone/ozone.c @@ -590,6 +590,12 @@ static int ozone_list_push(void *data, void *userdata, { entry.enum_idx = MENU_ENUM_LABEL_CORE_LIST; menu_displaylist_setting(&entry); + if (settings->bools.menu_show_advanced_settings) + { + entry.enum_idx = MENU_ENUM_LABEL_SIDELOAD_CORE_LIST; + menu_displaylist_setting(&entry); + } + } } diff --git a/menu/drivers/ozone/ozone_texture.c b/menu/drivers/ozone/ozone_texture.c index b1a34532a8..3b3414dcdc 100644 --- a/menu/drivers/ozone/ozone_texture.c +++ b/menu/drivers/ozone/ozone_texture.c @@ -103,6 +103,7 @@ menu_texture_item ozone_entries_icon_get_texture(ozone_handle_t *ozone, case MENU_ENUM_LABEL_CHEAT_START_OR_CONT: return ozone->icons_textures[OZONE_ENTRIES_ICONS_TEXTURE_RUN]; case MENU_ENUM_LABEL_CORE_LIST: + case MENU_ENUM_LABEL_SIDELOAD_CORE_LIST: case MENU_ENUM_LABEL_CORE_SETTINGS: case MENU_ENUM_LABEL_CORE_UPDATER_LIST: case MENU_ENUM_LABEL_VIDEO_SHADER_PRESET_SAVE_CORE: diff --git a/menu/drivers/xmb.c b/menu/drivers/xmb.c index 4b0fd88e60..9c5b37b24e 100755 --- a/menu/drivers/xmb.c +++ b/menu/drivers/xmb.c @@ -2347,6 +2347,7 @@ static uintptr_t xmb_icon_get_id(xmb_handle_t *xmb, case MENU_ENUM_LABEL_CHEAT_START_OR_CONT: return xmb->textures.list[XMB_TEXTURE_RUN]; case MENU_ENUM_LABEL_CORE_LIST: + case MENU_ENUM_LABEL_SIDELOAD_CORE_LIST: case MENU_ENUM_LABEL_CORE_SETTINGS: case MENU_ENUM_LABEL_CORE_UPDATER_LIST: case MENU_ENUM_LABEL_VIDEO_SHADER_PRESET_SAVE_CORE: @@ -5540,6 +5541,11 @@ static int xmb_list_push(void *data, void *userdata, { entry.enum_idx = MENU_ENUM_LABEL_CORE_LIST; menu_displaylist_setting(&entry); + if (settings->bools.menu_show_advanced_settings) + { + entry.enum_idx = MENU_ENUM_LABEL_SIDELOAD_CORE_LIST; + menu_displaylist_setting(&entry); + } } } diff --git a/menu/menu_cbs.h b/menu/menu_cbs.h index ed34b73021..717ca7a302 100644 --- a/menu/menu_cbs.h +++ b/menu/menu_cbs.h @@ -102,6 +102,7 @@ enum ACTION_OK_DL_CHEAT_FILE, ACTION_OK_DL_CHEAT_FILE_APPEND, ACTION_OK_DL_CORE_LIST, + ACTION_OK_DL_SIDELOAD_CORE_LIST, ACTION_OK_DL_LAKKA_LIST, ACTION_OK_DL_CONFIGURATIONS_LIST, ACTION_OK_DL_COMPRESSED_ARCHIVE_PUSH, diff --git a/menu/menu_displaylist.c b/menu/menu_displaylist.c index 1e0ce6e0a2..be6393fff4 100644 --- a/menu/menu_displaylist.c +++ b/menu/menu_displaylist.c @@ -3706,7 +3706,10 @@ static unsigned menu_displaylist_parse_cores( else { file_type = FILE_TYPE_CORE; - enum_idx = MENU_ENUM_LABEL_FILE_BROWSER_CORE; + if (string_is_equal(info->label, msg_hash_to_str(MENU_ENUM_LABEL_SIDELOAD_CORE_LIST))) + enum_idx = MENU_ENUM_LABEL_FILE_BROWSER_SIDELOAD_CORE; + else + enum_idx = MENU_ENUM_LABEL_FILE_BROWSER_CORE; } items_found++; @@ -7399,6 +7402,9 @@ bool menu_displaylist_ctl(enum menu_displaylist_ctl_state type, menu_displaylist if (settings->bools.menu_show_load_core) menu_displaylist_parse_settings_enum(menu, info, MENU_ENUM_LABEL_CORE_LIST, PARSE_ACTION, false); + if (settings->bools.menu_show_load_core) + menu_displaylist_parse_settings_enum(menu, info, + MENU_ENUM_LABEL_SIDELOAD_CORE_LIST, PARSE_ACTION, false); } if (settings->bools.menu_show_load_content) @@ -7645,6 +7651,7 @@ bool menu_displaylist_ctl(enum menu_displaylist_ctl_state type, menu_displaylist case DISPLAYLIST_FILE_BROWSER_SELECT_DIR: case DISPLAYLIST_FILE_BROWSER_SELECT_FILE: case DISPLAYLIST_FILE_BROWSER_SELECT_CORE: + case DISPLAYLIST_FILE_BROWSER_SELECT_SIDELOAD_CORE: case DISPLAYLIST_FILE_BROWSER_SELECT_COLLECTION: case DISPLAYLIST_GENERIC: { diff --git a/menu/menu_displaylist.h b/menu/menu_displaylist.h index 4d8f165351..64e03870ce 100644 --- a/menu/menu_displaylist.h +++ b/menu/menu_displaylist.h @@ -78,6 +78,7 @@ enum menu_displaylist_ctl_state DISPLAYLIST_FILE_BROWSER_SCAN_DIR, DISPLAYLIST_FILE_BROWSER_SELECT_FILE, DISPLAYLIST_FILE_BROWSER_SELECT_CORE, + DISPLAYLIST_FILE_BROWSER_SELECT_SIDELOAD_CORE, DISPLAYLIST_FILE_BROWSER_SELECT_COLLECTION, DISPLAYLIST_CORES, DISPLAYLIST_CORES_SUPPORTED, diff --git a/menu/menu_setting.c b/menu/menu_setting.c index 12fd5d46c0..8b7c30f7c0 100644 --- a/menu/menu_setting.c +++ b/menu/menu_setting.c @@ -3567,6 +3567,17 @@ static bool setting_append_list( } } +#ifdef HAVE_DYNAMIC + if (settings->bools.menu_show_advanced_settings) + CONFIG_ACTION( + list, list_info, + MENU_ENUM_LABEL_SIDELOAD_CORE_LIST, + MENU_ENUM_LABEL_VALUE_SIDELOAD_CORE_LIST, + &group_info, + &subgroup_info, + parent_group); +#endif + CONFIG_ACTION( list, list_info, MENU_ENUM_LABEL_LOAD_CONTENT_LIST, @@ -3575,6 +3586,7 @@ static bool setting_append_list( &subgroup_info, parent_group); + if (settings->bools.history_list_enable) { CONFIG_ACTION( diff --git a/msg_hash.h b/msg_hash.h index 23cbea53de..5cb184c924 100644 --- a/msg_hash.h +++ b/msg_hash.h @@ -894,6 +894,7 @@ enum msg_hash_enums MENU_ENUM_LABEL_FILE_BROWSER_SHADER, MENU_ENUM_LABEL_FILE_BROWSER_REMAP, MENU_ENUM_LABEL_FILE_BROWSER_CORE, + MENU_ENUM_LABEL_FILE_BROWSER_SIDELOAD_CORE, MENU_ENUM_LABEL_FILE_BROWSER_OVERLAY, MENU_ENUM_LABEL_FILE_BROWSER_CHEAT, MENU_ENUM_LABEL_FILE_BROWSER_FONT, @@ -1570,6 +1571,9 @@ enum msg_hash_enums MENU_LABEL(SUBSYSTEM_ADD), MENU_LABEL(SUBSYSTEM_LOAD), MENU_LABEL(CORE_LIST), + MENU_LABEL(SIDELOAD_CORE_LIST), + MENU_LABEL(SIDELOAD_CORE_ERROR), + MENU_LABEL(SIDELOAD_CORE_SUCCESS), MENU_LABEL(MANAGEMENT), MENU_LABEL(ONLINE), MENU_LABEL(ONLINE_UPDATER), @@ -2358,6 +2362,7 @@ enum msg_hash_enums #define MENU_LABEL_DETECT_CORE_LIST 0xaa07c341U #define MENU_LABEL_DETECT_CORE_LIST_OK 0xabba2a7aU #define MENU_LABEL_CORE_LIST 0xa22bb14dU +#define MENU_LABEL_SIDELOAD_CORE_LIST 0x88ef1cf2U #define MENU_LABEL_MANAGEMENT 0x2516c88aU #define MENU_LABEL_FRONTEND_COUNTERS 0xe5696877U #define MENU_LABEL_CORE_COUNTERS 0x64cc83e0U