From 8bb6038855386dcaf9fa95c29372db7581ec17c6 Mon Sep 17 00:00:00 2001 From: Eric Warmenhoven Date: Mon, 8 Jan 2024 12:37:26 -0500 Subject: [PATCH 1/2] Download various asset files on startup if necessary. --- menu/menu_driver.c | 72 ++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 72 insertions(+) diff --git a/menu/menu_driver.c b/menu/menu_driver.c index 1ca1194768c..492f8d7f7a1 100644 --- a/menu/menu_driver.c +++ b/menu/menu_driver.c @@ -40,6 +40,8 @@ #ifdef HAVE_NETWORKING #include "../network/netplay/netplay.h" +#include "../tasks/task_file_transfer.h" +#include #endif #include "../audio/audio_driver.h" @@ -3625,6 +3627,53 @@ static void bundle_decompressed(retro_task_t *task, command_event(CMD_EVENT_MENU_SAVE_CURRENT_CONFIG, NULL); } +#if defined(HAVE_ONLINE_UPDATER) && defined(HAVE_NETWORKING) && defined(HAVE_COMPRESSION) && defined(HAVE_ZLIB) +static void menu_download(enum msg_hash_enums enum_idx) +{ + char s[PATH_MAX_LENGTH]; + char s2[PATH_MAX_LENGTH]; + char s3[PATH_MAX_LENGTH]; + const char *path; + file_transfer_t *transf = NULL; + settings_t *settings = config_get_ptr(); + const char *network_buildbot_assets_url = + settings->paths.network_buildbot_assets_url; + + fill_pathname_join_special(s, + network_buildbot_assets_url, + "frontend", sizeof(s)); + + switch (enum_idx) + { + case MENU_ENUM_LABEL_CB_UPDATE_ASSETS: + path = FILE_PATH_ASSETS_ZIP; + break; + case MENU_ENUM_LABEL_CB_UPDATE_AUTOCONFIG_PROFILES: + path = FILE_PATH_AUTOCONFIG_ZIP; + break; + case MENU_ENUM_LABEL_CB_UPDATE_CORE_INFO_FILES: + path = FILE_PATH_CORE_INFO_ZIP; + break; + case MENU_ENUM_LABEL_CB_UPDATE_DATABASES: + path = FILE_PATH_DATABASE_RDB_ZIP; + break; + case MENU_ENUM_LABEL_CB_UPDATE_OVERLAYS: + path = FILE_PATH_OVERLAYS_ZIP; + break; + default: + return; + } + + transf = (file_transfer_t*)calloc(1, sizeof(*transf)); + transf->enum_idx = enum_idx; + strlcpy(transf->path, path, sizeof(transf->path)); + fill_pathname_join_special(s2, s, path, sizeof(s2)); + net_http_urlencode_full(s3, s2, sizeof(s3)); + task_push_http_transfer_file(s3, false, + msg_hash_to_str(enum_idx), cb_generic_download, transf); +} +#endif + static bool rarch_menu_init( struct menu_state *menu_st, menu_dialog_t *p_dialog, @@ -3696,6 +3745,29 @@ static bool rarch_menu_init( configuration_set_int(settings, settings->uints.bundle_assets_extract_last_version, 1); } +#if defined(HAVE_ONLINE_UPDATER) && defined(HAVE_NETWORKING) && defined(HAVE_ZLIB) + else + { +#ifdef HAVE_UPDATE_ASSETS + if (!path_is_directory(settings->paths.directory_assets)) + menu_download(MENU_ENUM_LABEL_CB_UPDATE_ASSETS); +#endif + if (!path_is_directory(settings->paths.directory_autoconfig)) + menu_download(MENU_ENUM_LABEL_CB_UPDATE_AUTOCONFIG_PROFILES); +#ifdef HAVE_UPDATE_CORE_INFO + if (!path_is_directory(settings->paths.path_libretro_info)) + menu_download(MENU_ENUM_LABEL_CB_UPDATE_CORE_INFO_FILES); +#endif +#ifdef HAVE_LIBRETRODB + if (!path_is_directory(settings->paths.path_content_database)) + menu_download(MENU_ENUM_LABEL_CB_UPDATE_DATABASES); +#endif +#if defined(RARCH_MOBILE) && defined(HAVE_OVERLAY) + if (!path_is_directory(settings->paths.directory_overlay)) + menu_download(MENU_ENUM_LABEL_CB_UPDATE_OVERLAYS); +#endif + } +#endif #endif return true; From 9aff56206d287cefc6fc1f193aeb5445c15a647d Mon Sep 17 00:00:00 2001 From: Craig Carnell <1188869+cscd98@users.noreply.github.com> Date: Mon, 30 Mar 2026 16:38:44 +0100 Subject: [PATCH 2/2] make assets update optional on first run and enable by default for webOS --- file_path_special.h | 4 ++ libretro-common/file/file_path_io.c | 50 ++++++++++++++++++++++++ libretro-common/include/file/file_path.h | 4 ++ menu/menu_driver.c | 36 +++++++++++++---- 4 files changed, 86 insertions(+), 8 deletions(-) diff --git a/file_path_special.h b/file_path_special.h index 7d06db4c683..c0b665af154 100644 --- a/file_path_special.h +++ b/file_path_special.h @@ -126,6 +126,10 @@ RETRO_BEGIN_DECLS #define FILE_PATH_CORE_INFO_CACHE "core_info.cache" #define FILE_PATH_CORE_INFO_CACHE_REFRESH "core_info.refresh" +/* sizes of zip plus decompression space required rounded up to nearest 50MB */ +#define ASSETS_ZIP_PLUS_DECOMPRESSION_SIZE 209715200 /* 200MB */ +#define DATABASE_RDB_ZIP_PLUS_DECOMPRESSION_SIZE 262144000 /* 250MB */ + #ifdef HAVE_LAKKA #ifdef HAVE_LAKKA_SERVER #define FILE_PATH_LAKKA_URL HAVE_LAKKA_SERVER diff --git a/libretro-common/file/file_path_io.c b/libretro-common/file/file_path_io.c index 4dc63386acf..42711c016f2 100644 --- a/libretro-common/file/file_path_io.c +++ b/libretro-common/file/file_path_io.c @@ -37,10 +37,15 @@ #ifdef _WIN32 #include +#include #else #include /* stat() is defined here */ #endif +#if defined(__unix__) || defined(__APPLE__) +#include +#endif + /* TODO/FIXME - globals */ static retro_vfs_stat_t path_stat32_cb = retro_vfs_stat_impl; static retro_vfs_stat_64_t path_stat64_cb = retro_vfs_stat_64_impl; @@ -88,6 +93,33 @@ bool path_is_directory(const char *path) return (path_stat32_cb(path, NULL) & RETRO_VFS_STAT_IS_DIRECTORY) != 0; } +bool path_is_empty_directory(const char *dir) +{ + struct retro_vfs_dir_handle *d; + const char *name; + + d = retro_vfs_opendir_impl(dir, false); + if (!d) + return false; + + while (retro_vfs_readdir_impl(d)) + { + name = retro_vfs_dirent_get_name_impl(d); + + /* Skip . and .. */ + if (name && + strcmp(name, ".") != 0 && + strcmp(name, "..") != 0) + { + retro_vfs_closedir_impl(d); + return false; + } + } + + retro_vfs_closedir_impl(d); + return true; +} + bool path_is_character_special(const char *path) { if (path_stat64_cb) @@ -166,3 +198,21 @@ bool path_mkdir(const char *dir) } return false; } + +int64_t path_get_free_space(const char *path) +{ +#if defined(_WIN32) + ULARGE_INTEGER free_bytes_available; + if (GetDiskFreeSpaceExA(path, &free_bytes_available, NULL, NULL)) + return (int64_t)free_bytes_available.QuadPart; + return -1; +#elif defined(__unix__) || defined(__APPLE__) + struct statvfs fs; + if (statvfs(path, &fs) == 0) + return (int64_t)fs.f_bavail * (int64_t)fs.f_frsize; + return -1; +#else + /* Unsupported platform */ + return -1; +#endif +} diff --git a/libretro-common/include/file/file_path.h b/libretro-common/include/file/file_path.h index e733de18e0d..ec4c29ec570 100644 --- a/libretro-common/include/file/file_path.h +++ b/libretro-common/include/file/file_path.h @@ -665,6 +665,10 @@ bool path_mkdir(const char *dir); */ bool path_is_directory(const char *path); +bool path_is_empty_directory(const char *dir); + +int64_t path_get_free_space(const char *path); + /* Time format strings with AM-PM designation require special * handling due to platform dependence * @return Length of the string written to @s diff --git a/menu/menu_driver.c b/menu/menu_driver.c index 492f8d7f7a1..f9abc93e41e 100644 --- a/menu/menu_driver.c +++ b/menu/menu_driver.c @@ -49,6 +49,7 @@ #include "menu_driver.h" #include "menu_cbs.h" #include "../driver.h" +#include "../file_path_special.h" #include "../list_special.h" #include "../msg_hash_lbl_str.h" #include "../paths.h" @@ -3687,6 +3688,9 @@ static bool rarch_menu_init( bool menu_show_start_screen = settings->bools.menu_show_start_screen; bool config_save_on_exit = settings->bools.config_save_on_exit; #endif +#ifdef HAVE_COMPRESSION + bool have_bundled_assets = false; +#endif /* thumbnail initialization */ if (!(menu_st->thumbnail_path_data = gfx_thumbnail_path_init())) @@ -3729,6 +3733,7 @@ static bool rarch_menu_init( != settings->uints.bundle_assets_extract_last_version) ) { + have_bundled_assets = true; p_dialog->current_type = MENU_DIALOG_HELP_EXTRACT; task_push_decompress( settings->paths.bundle_assets_src, @@ -3748,22 +3753,37 @@ static bool rarch_menu_init( #if defined(HAVE_ONLINE_UPDATER) && defined(HAVE_NETWORKING) && defined(HAVE_ZLIB) else { +#ifdef HAVE_CONFIGFILE + if (!menu_show_start_screen) + return true; +#endif +#ifdef HAVE_COMPRESSION + if (have_bundled_assets) + return true; +#endif + #ifdef HAVE_UPDATE_ASSETS - if (!path_is_directory(settings->paths.directory_assets)) - menu_download(MENU_ENUM_LABEL_CB_UPDATE_ASSETS); + if (!path_is_directory(settings->paths.directory_assets) || path_is_empty_directory(settings->paths.directory_assets)) + { + if (path_get_free_space(settings->paths.directory_assets) >= ASSETS_ZIP_PLUS_DECOMPRESSION_SIZE) + menu_download(MENU_ENUM_LABEL_CB_UPDATE_ASSETS); + } #endif - if (!path_is_directory(settings->paths.directory_autoconfig)) + if (!path_is_directory(settings->paths.directory_autoconfig) || path_is_empty_directory(settings->paths.directory_autoconfig)) menu_download(MENU_ENUM_LABEL_CB_UPDATE_AUTOCONFIG_PROFILES); #ifdef HAVE_UPDATE_CORE_INFO - if (!path_is_directory(settings->paths.path_libretro_info)) + if (!path_is_directory(settings->paths.path_libretro_info) || path_is_empty_directory(settings->paths.path_libretro_info)) menu_download(MENU_ENUM_LABEL_CB_UPDATE_CORE_INFO_FILES); #endif -#ifdef HAVE_LIBRETRODB - if (!path_is_directory(settings->paths.path_content_database)) - menu_download(MENU_ENUM_LABEL_CB_UPDATE_DATABASES); +#if defined(HAVE_LIBRETRODB) + if (!path_is_directory(settings->paths.path_content_database) || path_is_empty_directory(settings->paths.path_content_database)) + { + if (path_get_free_space(settings->paths.path_content_database) >= DATABASE_RDB_ZIP_PLUS_DECOMPRESSION_SIZE) + menu_download(MENU_ENUM_LABEL_CB_UPDATE_DATABASES); + } #endif #if defined(RARCH_MOBILE) && defined(HAVE_OVERLAY) - if (!path_is_directory(settings->paths.directory_overlay)) + if (!path_is_directory(settings->paths.directory_overlay) || path_is_empty_directory(settings->paths.directory_overlay)) menu_download(MENU_ENUM_LABEL_CB_UPDATE_OVERLAYS); #endif }