diff --git a/gfx/gfx_thumbnail.c b/gfx/gfx_thumbnail.c index 17cbb52dce..9ced52242b 100644 --- a/gfx/gfx_thumbnail.c +++ b/gfx/gfx_thumbnail.c @@ -228,6 +228,47 @@ void gfx_thumbnail_cancel_pending_requests(void) p_gfx_thumb->list_id++; } +/* Fetches the current thumbnail file path of the + * specified thumbnail 'type'. + * Returns true if path is valid. */ +static bool gfx_thumbnail_get_path( + gfx_thumbnail_path_data_t *path_data, + enum gfx_thumbnail_id thumbnail_id, + const char **path) +{ + if (path_data && path) + { + switch (thumbnail_id) + { + case GFX_THUMBNAIL_RIGHT: + if (!string_is_empty(path_data->right_path)) + { + *path = path_data->right_path; + return true; + } + break; + case GFX_THUMBNAIL_LEFT: + if (!string_is_empty(path_data->left_path)) + { + *path = path_data->left_path; + return true; + } + case GFX_THUMBNAIL_ICON: + if (!string_is_empty(path_data->icon_path)) + { + *path = path_data->icon_path; + return true; + } + break; + default: + break; + } + } + + return false; +} + + /* Requests loading of the specified thumbnail * - If operation fails, 'thumbnail->status' will be set to * GFX_THUMBNAIL_STATUS_MISSING @@ -291,16 +332,10 @@ void gfx_thumbnail_request( { enum playlist_thumbnail_name_flags curr_flag; const char *system = NULL; - const char *img_name = NULL; - static char last_img_name[NAME_MAX_LENGTH] = {0}; + static char last_img_name[PATH_MAX_LENGTH] = {0}; settings_t *settings = config_get_ptr(); if (!playlist) goto end; - - /* Validate entry */ - if (!gfx_thumbnail_get_img_name(path_data, &img_name, PLAYLIST_THUMBNAIL_FLAG_STD_NAME)) - goto end; - /* Only trigger a thumbnail download if image * name has changed since the last call of * gfx_thumbnail_request() @@ -313,13 +348,14 @@ void gfx_thumbnail_request( * checks required for this involve significant * overheads. We can avoid this entirely with * a simple string comparison) */ - if (string_is_equal(img_name, last_img_name)) - goto end; + if ((!string_is_empty(path_data->content_img))) + if (string_is_equal(path_data->content_img, last_img_name)) + goto end; - strlcpy(last_img_name, img_name, sizeof(last_img_name)); + strlcpy(last_img_name, path_data->content_img, sizeof(last_img_name)); /* Get system name */ - if (!gfx_thumbnail_get_system(path_data, &system)) + if (string_is_empty(path_data->system)) goto end; /* Since task_push_pl_entry_download will shift the flag, do not attempt if it is already @@ -337,7 +373,7 @@ void gfx_thumbnail_request( /* Trigger thumbnail download * * Note: download will grab all 3 possible thumbnails, no matter * what left/right thumbnails are set at the moment */ - task_push_pl_entry_thumbnail_download(system, playlist, + task_push_pl_entry_thumbnail_download(path_data->system, playlist, (unsigned)idx, false, true); } #endif diff --git a/gfx/gfx_thumbnail_path.c b/gfx/gfx_thumbnail_path.c index 31e8c1fbdb..5ac7251098 100644 --- a/gfx/gfx_thumbnail_path.c +++ b/gfx/gfx_thumbnail_path.c @@ -35,37 +35,6 @@ #include "gfx_thumbnail_path.h" -/* Fills content_img field of path_data using existing - * content_label field (for internal use only) */ -static void gfx_thumbnail_fill_content_img(char *s, size_t len, const char *src, bool shorten) -{ - char *scrub_char_ptr = NULL; - /* Copy source label string */ - size_t _len = strlcpy(s, src, len); - - /* Shortening logic: up to first space + bracket */ - if (shorten) - { - int bracketpos = -1; - if ((bracketpos = string_find_index_substring_string(src, " (")) > 0) - _len = bracketpos; - /* Explicit zero if short name is same as standard name - saves some queries later. */ - else - { - s[0] = '\0'; - return; - } - } - /* Scrub characters that are not cross-platform and/or violate the - * No-Intro filename standard: - * https://datomatic.no-intro.org/stuff/The%20Official%20No-Intro%20Convention%20(20071030).pdf - * Replace these characters in the entry name with underscores */ - while ((scrub_char_ptr = strpbrk(s, "&*/:`\"<>?\\|"))) - *scrub_char_ptr = '_'; - /* Add PNG extension */ - strlcpy(s + _len, ".png", len - _len); -} - /* Returns currently set thumbnail 'type' (Named_Snaps, * Named_Titles, Named_Boxarts, Named_Logos) for specified thumbnail * identifier (right, left) */ @@ -120,6 +89,37 @@ end: return msg_hash_to_str(MENU_ENUM_LABEL_VALUE_OFF); } +/* Fills content_img field of path_data using existing + * content_label field (for internal use only) */ +void gfx_thumbnail_fill_content_img(char *s, size_t len, const char *src, bool shorten) +{ + char *scrub_char_ptr = NULL; + /* Copy source label string */ + size_t _len = strlcpy(s, src, len); + + /* Shortening logic: up to first space + bracket */ + if (shorten) + { + int bracketpos = -1; + if ((bracketpos = string_find_index_substring_string(src, " (")) > 0) + _len = bracketpos; + /* Explicit zero if short name is same as standard name - saves some queries later. */ + else + { + s[0] = '\0'; + return; + } + } + /* Scrub characters that are not cross-platform and/or violate the + * No-Intro filename standard: + * https://datomatic.no-intro.org/stuff/The%20Official%20No-Intro%20Convention%20(20071030).pdf + * Replace these characters in the entry name with underscores */ + while ((scrub_char_ptr = strpbrk(s, "&*/:`\"<>?\\|"))) + *scrub_char_ptr = '_'; + /* Add PNG extension */ + strlcpy(s + _len, ".png", len - _len); +} + /* Resets thumbnail path data * (blanks all internal string containers) */ void gfx_thumbnail_path_reset(gfx_thumbnail_path_data_t *path_data) @@ -127,8 +127,10 @@ void gfx_thumbnail_path_reset(gfx_thumbnail_path_data_t *path_data) if (!path_data) return; + path_data->system_len = 0; path_data->system[0] = '\0'; path_data->content_path[0] = '\0'; + path_data->content_label_len = 0; path_data->content_label[0] = '\0'; path_data->content_core_name[0] = '\0'; path_data->content_db_name[0] = '\0'; @@ -216,6 +218,7 @@ bool gfx_thumbnail_set_system(gfx_thumbnail_path_data_t *path_data, path_data->left_path[0] = '\0'; /* 'Reset' path_data system string */ + path_data->system_len = 0; path_data->system[0] = '\0'; /* Must also reset playlist thumbnail display modes */ @@ -228,9 +231,9 @@ bool gfx_thumbnail_set_system(gfx_thumbnail_path_data_t *path_data, /* Hack: There is only one MAME thumbnail repo, * so filter any input starting with 'MAME...' */ if (strncmp(system, "MAME", 4) == 0) - strlcpy(path_data->system, "MAME", sizeof(path_data->system)); + path_data->system_len = strlcpy(path_data->system, "MAME", sizeof(path_data->system)); else - strlcpy(path_data->system, system, sizeof(path_data->system)); + path_data->system_len = strlcpy(path_data->system, system, sizeof(path_data->system)); /* Addendum: Now that we have per-playlist thumbnail display * modes, we must extract them here - otherwise @@ -296,6 +299,7 @@ bool gfx_thumbnail_set_content(gfx_thumbnail_path_data_t *path_data, const char /* 'Reset' path_data content strings */ path_data->content_path[0] = '\0'; + path_data->content_label_len = 0; path_data->content_label[0] = '\0'; path_data->content_core_name[0] = '\0'; path_data->content_db_name[0] = '\0'; @@ -312,7 +316,8 @@ bool gfx_thumbnail_set_content(gfx_thumbnail_path_data_t *path_data, const char return false; /* Cache content label */ - strlcpy(path_data->content_label, label, sizeof(path_data->content_label)); + path_data->content_label_len = strlcpy(path_data->content_label, + label, sizeof(path_data->content_label)); /* Determine content image name */ gfx_thumbnail_fill_content_img(path_data->content_img, @@ -344,6 +349,7 @@ bool gfx_thumbnail_set_content_image( /* 'Reset' path_data content strings */ path_data->content_path[0] = '\0'; + path_data->content_label_len = 0; path_data->content_label[0] = '\0'; path_data->content_core_name[0] = '\0'; path_data->content_db_name[0] = '\0'; @@ -366,7 +372,8 @@ bool gfx_thumbnail_set_content_image( strlcpy(path_data->content_img, img_name, sizeof(path_data->content_img)); - fill_pathname(path_data->content_label, + path_data->content_label_len = fill_pathname( + path_data->content_label, path_data->content_img, "", sizeof(path_data->content_label)); @@ -415,6 +422,7 @@ bool gfx_thumbnail_set_content_playlist( /* 'Reset' path_data content strings */ path_data->content_path[0] = '\0'; + path_data->content_label_len = 0; path_data->content_label[0] = '\0'; path_data->content_core_name[0] = '\0'; path_data->content_db_name[0] = '\0'; @@ -461,10 +469,10 @@ bool gfx_thumbnail_set_content_playlist( /* Get content label */ if (!string_is_empty(content_label)) - strlcpy(path_data->content_label, + path_data->content_label_len = strlcpy(path_data->content_label, content_label, sizeof(path_data->content_label)); else - fill_pathname(path_data->content_label, + path_data->content_label_len = fill_pathname(path_data->content_label, path_basename(content_path), "", sizeof(path_data->content_label)); @@ -477,14 +485,14 @@ bool gfx_thumbnail_set_content_playlist( gfx_thumbnail_fill_content_img(path_data->content_img_full, sizeof(path_data->content_img_full), tmp_buf, false); gfx_thumbnail_fill_content_img(path_data->content_img, - sizeof(path_data->content_img), path_data->content_label,false); + sizeof(path_data->content_img), path_data->content_label, false); /* Explicit zero if full name is same as standard name - saves some queries later. */ if(string_is_equal(path_data->content_img, path_data->content_img_full)) path_data->content_img_full[0] = '\0'; gfx_thumbnail_fill_content_img(path_data->content_img_short, - sizeof(path_data->content_img_short), path_data->content_label,true); + sizeof(path_data->content_img_short), path_data->content_label, true); } /* Store playlist index */ @@ -537,146 +545,6 @@ bool gfx_thumbnail_set_content_playlist( return true; } -bool gfx_thumbnail_set_icon_playlist( - gfx_thumbnail_path_data_t *path_data, playlist_t *playlist, size_t idx) -{ - const char *content_path = NULL; - const char *content_label = NULL; - const char *core_name = NULL; - const char *db_name = NULL; - const struct playlist_entry *entry = NULL; - - if (!path_data) - return false; - - - /* When content is updated, must regenerate icon - * thumbnail paths */ - path_data->icon_path[0] = '\0'; - - /* 'Reset' path_data content strings */ - path_data->content_path[0] = '\0'; - path_data->content_label[0] = '\0'; - path_data->content_core_name[0] = '\0'; - path_data->content_db_name[0] = '\0'; - path_data->content_img[0] = '\0'; - path_data->content_img_full[0] = '\0'; - path_data->content_img_short[0] = '\0'; - - /* Must also reset playlist thumbnail display modes */ - path_data->playlist_icon_mode = PLAYLIST_THUMBNAIL_MODE_DEFAULT; - path_data->playlist_index = 0; - - if (!playlist) - return false; - - if (idx >= playlist_get_size(playlist)) - return false; - - /* Read playlist values */ - playlist_get_index(playlist, idx, &entry); - - if (!entry) - return false; - - content_path = entry->path; - content_label = entry->label; - core_name = entry->core_name; - db_name = entry->db_name; - - /* Content without a path is invalid by definition */ - if (string_is_empty(content_path)) - return false; - - /* Cache content path - * (This is required for imageviewer, history and favourites content) */ - strlcpy(path_data->content_path, - content_path, sizeof(path_data->content_path)); - - /* Cache core name - * (This is required for imageviewer content) */ - if (!string_is_empty(core_name)) - strlcpy(path_data->content_core_name, - core_name, sizeof(path_data->content_core_name)); - - /* Get content label */ - if (!string_is_empty(content_label)) - strlcpy(path_data->content_label, - content_label, sizeof(path_data->content_label)); - else - fill_pathname(path_data->content_label, - path_basename(content_path), - "", sizeof(path_data->content_label)); - - /* Determine content image name */ - { - char tmp_buf[NAME_MAX_LENGTH]; - fill_pathname(tmp_buf, path_basename(path_data->content_path), "", - sizeof(tmp_buf)); - - gfx_thumbnail_fill_content_img(path_data->content_img_full, - sizeof(path_data->content_img_full), tmp_buf, false); - gfx_thumbnail_fill_content_img(path_data->content_img, - sizeof(path_data->content_img), path_data->content_label,false); - - /* Explicit zero if full name is same as standard name - saves some queries later. */ - if(string_is_equal(path_data->content_img, path_data->content_img_full)) - path_data->content_img_full[0] = '\0'; - - gfx_thumbnail_fill_content_img(path_data->content_img_short, - sizeof(path_data->content_img_short), path_data->content_label,true); - } - - /* Store playlist index */ - path_data->playlist_index = idx; - - /* Redundant error check... */ - if (string_is_empty(path_data->content_img)) - return false; - - /* Thumbnail image name is done -> now check if - * per-content database name is defined */ - if (string_is_empty(db_name)) - playlist_get_db_name(playlist, idx, &db_name); - if (!string_is_empty(db_name)) - { - /* Hack: There is only one MAME thumbnail repo, - * so filter any input starting with 'MAME...' */ - if (strncmp(db_name, "MAME", 4) == 0) - { - path_data->content_db_name[0] = path_data->content_db_name[2] = 'M'; - path_data->content_db_name[1] = 'A'; - path_data->content_db_name[3] = 'E'; - path_data->content_db_name[4] = '\0'; - } - else - { - char tmp_buf[NAME_MAX_LENGTH]; - const char* pos = strchr(db_name, '|'); - - /* If db_name comes from core info, and there are multiple - * databases mentioned separated by |, use only first one */ - if (pos && (size_t) (pos - db_name)+1 < sizeof(tmp_buf)) - strlcpy(tmp_buf, db_name, (size_t) (pos - db_name)+1); - else - strlcpy(tmp_buf, db_name, sizeof(tmp_buf)); - - fill_pathname(path_data->content_db_name, - tmp_buf, "", - sizeof(path_data->content_db_name)); - } - } - - gfx_thumbnail_update_path(path_data, GFX_THUMBNAIL_ICON); - - /* Playlist entry is valid -> it is now 'safe' to - * extract any remaining playlist metadata - * (i.e. thumbnail display modes) */ - path_data->playlist_icon_mode = PLAYLIST_THUMBNAIL_MODE_DEFAULT; - - return true; -} - /* Updaters */ /* Updates path for specified thumbnail identifier (right, left). @@ -850,151 +718,22 @@ bool gfx_thumbnail_update_path( /* Getters */ -/* Fetches the current thumbnail file path of the - * specified thumbnail 'type'. - * Returns true if path is valid. */ -bool gfx_thumbnail_get_path( - gfx_thumbnail_path_data_t *path_data, - enum gfx_thumbnail_id thumbnail_id, - const char **path) -{ - char *thumbnail_path = NULL; - - if (!path_data || !path) - return false; - - switch (thumbnail_id) - { - case GFX_THUMBNAIL_RIGHT: - if (!string_is_empty(path_data->right_path)) - { - thumbnail_path = path_data->right_path; - *path = thumbnail_path; - return true; - } - break; - case GFX_THUMBNAIL_LEFT: - if (!string_is_empty(path_data->left_path)) - { - thumbnail_path = path_data->left_path; - *path = thumbnail_path; - return true; - } - case GFX_THUMBNAIL_ICON: - if (!string_is_empty(path_data->icon_path)) - { - thumbnail_path = path_data->icon_path; - *path = thumbnail_path; - return true; - } - break; - default: - break; - } - - return false; -} - -/* Fetches current 'system' (default database name). - * Returns true if 'system' is valid. */ -bool gfx_thumbnail_get_system( - gfx_thumbnail_path_data_t *path_data, const char **system) -{ - if (!path_data || !system) - return false; - if (string_is_empty(path_data->system)) - return false; - - *system = path_data->system; - - return true; -} - -/* Fetches current thumbnail label. - * Returns true if label is valid. */ -bool gfx_thumbnail_get_label( - gfx_thumbnail_path_data_t *path_data, const char **label) -{ - if (!path_data || !label) - return false; - if (string_is_empty(path_data->content_label)) - return false; - - *label = path_data->content_label; - - return true; -} - -/* Fetches current thumbnail core name. - * Returns true if core name is valid. */ -bool gfx_thumbnail_get_core_name( - gfx_thumbnail_path_data_t *path_data, const char **core_name) -{ - if (!path_data || !core_name) - return false; - if (string_is_empty(path_data->content_core_name)) - return false; - - *core_name = path_data->content_core_name; - - return true; -} - -/* Fetches current thumbnail image name according to name flag - * (name is the same for all thumbnail types). - * Returns true if image name is valid. */ -bool gfx_thumbnail_get_img_name( - gfx_thumbnail_path_data_t *path_data, const char **img_name, - enum playlist_thumbnail_name_flags name_flags) -{ - if (!path_data || !img_name || name_flags == PLAYLIST_THUMBNAIL_FLAG_NONE) - return false; - - if (name_flags & PLAYLIST_THUMBNAIL_FLAG_SHORT_NAME) - { - if (string_is_empty(path_data->content_img_short)) - return false; - *img_name = path_data->content_img_short; - } - else if (name_flags & PLAYLIST_THUMBNAIL_FLAG_STD_NAME) - { - if (string_is_empty(path_data->content_img)) - return false; - *img_name = path_data->content_img; - } - else if (name_flags & PLAYLIST_THUMBNAIL_FLAG_FULL_NAME) - { - if (string_is_empty(path_data->content_img_full)) - return false; - *img_name = path_data->content_img_full; - } - else - return false; - - return true; -} - /* Fetches current content directory. * Returns true if content directory is valid. */ bool gfx_thumbnail_get_content_dir( gfx_thumbnail_path_data_t *path_data, char *content_dir, size_t len) { - size_t path_length; char *last_slash; - const char *slash; - const char *backslash; + size_t path_length; char tmp_buf[NAME_MAX_LENGTH]; if (!path_data || string_is_empty(path_data->content_path)) return false; - slash = strrchr(path_data->content_path, '/'); - backslash = strrchr(path_data->content_path, '\\'); - last_slash = (!slash || (backslash > slash)) ? (char*)backslash : (char*)slash; - if (!last_slash) + if (!(last_slash = find_last_slash(path_data->content_path))) return false; - path_length = last_slash + 1 - path_data->content_path; + path_length = last_slash + 1 - path_data->content_path; if (!((path_length > 1) && (path_length < PATH_MAX_LENGTH))) return false; diff --git a/gfx/gfx_thumbnail_path.h b/gfx/gfx_thumbnail_path.h index 1cdb8ee1f2..28ad9d3bf1 100644 --- a/gfx/gfx_thumbnail_path.h +++ b/gfx/gfx_thumbnail_path.h @@ -61,6 +61,8 @@ struct gfx_thumbnail_path_data enum playlist_thumbnail_mode playlist_left_mode; enum playlist_thumbnail_mode playlist_icon_mode; size_t playlist_index; + size_t system_len; + size_t content_label_len; char content_label[NAME_MAX_LENGTH]; char content_core_name[NAME_MAX_LENGTH]; char system[NAME_MAX_LENGTH]; @@ -94,6 +96,10 @@ bool gfx_thumbnail_is_enabled(gfx_thumbnail_path_data_t *path_data, enum gfx_thu /* Setters */ +/* Fills content_img field of path_data using existing + * content_label field (for internal use only) */ +void gfx_thumbnail_fill_content_img(char *s, size_t len, const char *src, bool shorten); + /* Sets current 'system' (default database name). * Returns true if 'system' is valid. * If playlist is provided, extracts system-specific @@ -120,8 +126,6 @@ bool gfx_thumbnail_set_content_image(gfx_thumbnail_path_data_t *path_data, const * core name). 'Real' labels should be extracted from source */ bool gfx_thumbnail_set_content_playlist(gfx_thumbnail_path_data_t *path_data, playlist_t *playlist, size_t idx); -bool gfx_thumbnail_set_icon_playlist( - gfx_thumbnail_path_data_t *path_data, playlist_t *playlist, size_t idx); /* Updaters */ /* Updates path for specified thumbnail identifier (right, left). @@ -135,28 +139,6 @@ bool gfx_thumbnail_update_path(gfx_thumbnail_path_data_t *path_data, enum gfx_th /* Getters */ -/* Fetches the current thumbnail file path of the - * specified thumbnail 'type'. - * Returns true if path is valid. */ -bool gfx_thumbnail_get_path(gfx_thumbnail_path_data_t *path_data, enum gfx_thumbnail_id thumbnail_id, const char **path); - -/* Fetches current 'system' (default database name). - * Returns true if 'system' is valid. */ -bool gfx_thumbnail_get_system(gfx_thumbnail_path_data_t *path_data, const char **system); - -/* Fetches current thumbnail label. - * Returns true if label is valid. */ -bool gfx_thumbnail_get_label(gfx_thumbnail_path_data_t *path_data, const char **label); - -/* Fetches current thumbnail core name. - * Returns true if core name is valid. */ -bool gfx_thumbnail_get_core_name(gfx_thumbnail_path_data_t *path_data, const char **core_name); - -/* Fetches current thumbnail image name - * (name is the same for all thumbnail types). - * Returns true if image name is valid. */ -bool gfx_thumbnail_get_img_name(gfx_thumbnail_path_data_t *path_data, const char **img_name, enum playlist_thumbnail_name_flags name_flags); - /* Fetches current content directory. * Returns true if content directory is valid. */ bool gfx_thumbnail_get_content_dir(gfx_thumbnail_path_data_t *path_data, char *content_dir, size_t len); diff --git a/menu/cbs/menu_cbs_ok.c b/menu/cbs/menu_cbs_ok.c index d92e48bba8..f016a819e0 100644 --- a/menu/cbs/menu_cbs_ok.c +++ b/menu/cbs/menu_cbs_ok.c @@ -8474,24 +8474,15 @@ static int action_ok_pl_content_thumbnails(const char *path, static int action_ok_pl_entry_content_thumbnails(const char *path, const char *label, unsigned type, size_t idx, size_t entry_idx) { - char system[PATH_MAX_LENGTH]; - const char *tmp = NULL; struct menu_state *menu_st = menu_state_get_ptr(); playlist_t *playlist = playlist_get_cached(); menu_handle_t *menu = menu_st->driver_data; - if (!playlist || !menu) return -1; - - system[0] = '\0'; - - if (gfx_thumbnail_get_system(menu_st->thumbnail_path_data, &tmp)) - strlcpy(system, tmp, sizeof(system)); - - task_push_pl_entry_thumbnail_download(system, + task_push_pl_entry_thumbnail_download( + menu_st->thumbnail_path_data->system, playlist, menu->rpl_entry_selection_ptr, true, false); - return 0; } #endif diff --git a/menu/drivers/ozone.c b/menu/drivers/ozone.c index 9a63156c12..a192310989 100644 --- a/menu/drivers/ozone.c +++ b/menu/drivers/ozone.c @@ -4101,7 +4101,6 @@ static void linebreak_after_colon(char (*str)[NAME_MAX_LENGTH]) static void ozone_update_content_metadata(ozone_handle_t *ozone) { - const char *core_name = NULL; struct menu_state *menu_st = menu_state_get_ptr(); menu_list_t *menu_list = menu_st->entries.list; size_t selection = menu_st->selection_ptr; @@ -4124,11 +4123,18 @@ static void ozone_update_content_metadata(ozone_handle_t *ozone) /* Must check whether core corresponds to 'viewer' * content even when not using a playlist, otherwise * file browser image updates are mishandled */ - if (gfx_thumbnail_get_core_name(menu_st->thumbnail_path_data, &core_name)) + + if (!string_is_empty(menu_st->thumbnail_path_data->content_core_name)) { - if ( string_is_equal(core_name, "imageviewer") - || string_is_equal(core_name, "musicplayer") - || string_is_equal(core_name, "movieplayer")) + if ( string_is_equal( + menu_st->thumbnail_path_data->content_core_name, + "imageviewer") + || string_is_equal( + menu_st->thumbnail_path_data->content_core_name, + "musicplayer") + || string_is_equal( + menu_st->thumbnail_path_data->content_core_name, + "movieplayer")) ozone->flags2 |= OZONE_FLAG2_SELECTION_CORE_IS_VIEWER; else ozone->flags2 &= ~OZONE_FLAG2_SELECTION_CORE_IS_VIEWER; @@ -4229,10 +4235,11 @@ static void ozone_update_content_metadata(ozone_handle_t *ozone) } else { - if (!core_name || string_is_equal(core_name, "DETECT")) + if ( string_is_empty(menu_st->thumbnail_path_data->content_core_name) + || string_is_equal(menu_st->thumbnail_path_data->content_core_name, "DETECT")) core_label = msg_hash_to_str(MSG_AUTODETECT); else - core_label = core_name; + core_label = menu_st->thumbnail_path_data->content_core_name; } _len = strlcpy(ozone->selection_core_name, @@ -4980,43 +4987,25 @@ static void ozone_context_reset_horizontal_list(ozone_handle_t *ozone) if (string_ends_with_size(path, ".lpl", strlen(path), STRLEN_CONST(".lpl"))) { - size_t len, syslen; + size_t __len, syslen; struct texture_image ti; char sysname[NAME_MAX_LENGTH]; char texturepath[PATH_MAX_LENGTH]; - char content_texturepath[PATH_MAX_LENGTH]; /* Add current node to playlist database name map */ RHMAP_SET_STR(ozone->playlist_db_node_map, path, node); - syslen = fill_pathname_base(sysname, path, sizeof(sysname)); - /* Manually strip the extension (and dot) from sysname */ - sysname[syslen-4] = - sysname[syslen-3] = - sysname[syslen-2] = - sysname[syslen-1] = '\0'; - syslen -= 4; - len = fill_pathname_join_special(texturepath, + syslen = fill_pathname(sysname, path_basename(path), "", sizeof(sysname)); + __len = fill_pathname_join_special(texturepath, ozone->icons_path, sysname, sizeof(texturepath)); - texturepath[ len] = '.'; - texturepath[++len] = 'p'; - texturepath[++len] = 'n'; - texturepath[++len] = 'g'; - texturepath[++len] = '\0'; + __len += strlcpy(texturepath + __len, ".png", sizeof(texturepath) - __len); /* If the playlist icon doesn't exist, return default */ if (!path_is_valid(texturepath)) - { - len = fill_pathname_join_special( - texturepath, ozone->icons_path, "default", + __len = fill_pathname_join_special( + texturepath, ozone->icons_path, "default.png", sizeof(texturepath)); - texturepath[ len] = '.'; - texturepath[++len] = 'p'; - texturepath[++len] = 'n'; - texturepath[++len] = 'g'; - texturepath[++len] = '\0'; - } ti.width = 0; ti.height = 0; @@ -5038,15 +5027,15 @@ static void ozone_context_reset_horizontal_list(ozone_handle_t *ozone) strlcpy(sysname + syslen, "-content.png", sizeof(sysname) - syslen); /* Assemble new icon path */ fill_pathname_join_special( - content_texturepath, ozone->icons_path, sysname, - sizeof(content_texturepath)); + texturepath, ozone->icons_path, sysname, + sizeof(texturepath)); /* If the content icon doesn't exist, return default-content */ - if (!path_is_valid(content_texturepath)) - fill_pathname_join_delim(content_texturepath, ozone->icons_path_default, - "content.png", '-', sizeof(content_texturepath)); + if (!path_is_valid(texturepath)) + fill_pathname_join_delim(texturepath, ozone->icons_path_default, + "content.png", '-', sizeof(texturepath)); - if (image_texture_load(&ti, content_texturepath)) + if (image_texture_load(&ti, texturepath)) { if (ti.pixels) { diff --git a/menu/drivers/rgui.c b/menu/drivers/rgui.c index 35f13042e3..4b130a39d6 100644 --- a/menu/drivers/rgui.c +++ b/menu/drivers/rgui.c @@ -4946,6 +4946,21 @@ static bool rgui_set_aspect_ratio( bool delay_update); #endif +/* Fetches current thumbnail label. + * Returns true if label is valid. */ +static bool gfx_thumbnail_get_label( + gfx_thumbnail_path_data_t *path_data, const char **label) +{ + if (!path_data || !label) + return false; + if (string_is_empty(path_data->content_label)) + return false; + + *label = path_data->content_label; + + return true; +} + static void rgui_render( void *data, unsigned width, @@ -6760,8 +6775,7 @@ static void rgui_load_current_thumbnails(rgui_t *rgui, struct menu_state *menu_s bool thumbnails_missing = false; /* Right (or fullscreen) thumbnail */ - if (gfx_thumbnail_get_path(menu_st->thumbnail_path_data, - GFX_THUMBNAIL_RIGHT, &thumbnail_path)) + if (!string_is_empty(menu_st->thumbnail_path_data->right_path)) { if (rgui_request_thumbnail( (rgui->flags & RGUI_FLAG_SHOW_FULLSCREEN_THUMBNAIL) @@ -6769,7 +6783,7 @@ static void rgui_load_current_thumbnails(rgui_t *rgui, struct menu_state *menu_s : &rgui->mini_thumbnail, GFX_THUMBNAIL_RIGHT, &rgui->thumbnail_queue_size, - thumbnail_path, + menu_st->thumbnail_path_data->right_path, &thumbnails_missing)) rgui->flags |= RGUI_FLAG_ENTRY_HAS_THUMBNAIL; else @@ -6782,14 +6796,13 @@ static void rgui_load_current_thumbnails(rgui_t *rgui, struct menu_state *menu_s if ( !(rgui->flags & RGUI_FLAG_SHOW_FULLSCREEN_THUMBNAIL) && string_is_empty(rgui->savestate_thumbnail_file_path)) { - if (gfx_thumbnail_get_path(menu_st->thumbnail_path_data, - GFX_THUMBNAIL_LEFT, &left_thumbnail_path)) + if (!string_is_empty(menu_st->thumbnail_path_data->left_path)) { if (rgui_request_thumbnail( &rgui->mini_left_thumbnail, GFX_THUMBNAIL_LEFT, &rgui->left_thumbnail_queue_size, - left_thumbnail_path, + menu_st->thumbnail_path_data->left_path, &thumbnails_missing)) rgui->flags |= RGUI_FLAG_ENTRY_HAS_LEFT_THUMBNAIL; else @@ -6798,8 +6811,7 @@ static void rgui_load_current_thumbnails(rgui_t *rgui, struct menu_state *menu_s } else if (!string_is_empty(rgui->savestate_thumbnail_file_path)) { - if (gfx_thumbnail_get_path(menu_st->thumbnail_path_data, - GFX_THUMBNAIL_LEFT, &left_thumbnail_path)) + if (!string_is_empty(menu_st->thumbnail_path_data->left_path)) { if (rgui_request_thumbnail( &rgui->mini_left_thumbnail, @@ -6823,7 +6835,6 @@ static void rgui_load_current_thumbnails(rgui_t *rgui, struct menu_state *menu_s /* On demand thumbnail downloads */ if (thumbnails_missing && download_missing) { - const char *system = NULL; playlist_t *playlist = playlist_get_cached(); struct menu_state *menu_st = menu_state_get_ptr(); size_t selection = menu_st->selection_ptr; @@ -6834,8 +6845,9 @@ static void rgui_load_current_thumbnails(rgui_t *rgui, struct menu_state *menu_s ? menu_st->thumbnail_path_data->playlist_index : 0; - if (gfx_thumbnail_get_system(menu_st->thumbnail_path_data, &system)) - task_push_pl_entry_thumbnail_download(system, + if (!string_is_empty(menu_st->thumbnail_path_data->system)) + task_push_pl_entry_thumbnail_download( + menu_st->thumbnail_path_data->system, playlist, (unsigned)selection, false, true); } diff --git a/menu/drivers/xmb.c b/menu/drivers/xmb.c index b6d4c3955c..8d78f66c93 100644 --- a/menu/drivers/xmb.c +++ b/menu/drivers/xmb.c @@ -1304,7 +1304,6 @@ static void xmb_update_thumbnail_image(void *data) { xmb_handle_t *xmb = (xmb_handle_t*)data; struct menu_state *menu_st = menu_state_get_ptr(); - const char *core_name = NULL; if (!xmb) return; @@ -1319,9 +1318,10 @@ static void xmb_update_thumbnail_image(void *data) } /* imageviewer content requires special treatment... */ - gfx_thumbnail_get_core_name(menu_st->thumbnail_path_data, &core_name); - - if (string_is_equal(core_name, "imageviewer")) + if ( + !string_is_empty(menu_st->thumbnail_path_data->content_core_name) + && string_is_equal(menu_st->thumbnail_path_data->content_core_name, + "imageviewer")) { /* Right thumbnail */ if (gfx_thumbnail_is_enabled(menu_st->thumbnail_path_data, GFX_THUMBNAIL_RIGHT)) @@ -1525,6 +1525,148 @@ static void xmb_set_thumbnail_content(void *data, const char *s) } } +static bool gfx_thumbnail_set_icon_playlist( + gfx_thumbnail_path_data_t *path_data, playlist_t *playlist, size_t idx) +{ + const char *content_path = NULL; + const char *content_label = NULL; + const char *core_name = NULL; + const char *db_name = NULL; + const struct playlist_entry *entry = NULL; + + if (!path_data) + return false; + + /* When content is updated, must regenerate icon + * thumbnail paths */ + path_data->icon_path[0] = '\0'; + + /* 'Reset' path_data content strings */ + path_data->content_path[0] = '\0'; + path_data->content_label_len = 0; + path_data->content_label[0] = '\0'; + path_data->content_core_name[0] = '\0'; + path_data->content_db_name[0] = '\0'; + path_data->content_img[0] = '\0'; + path_data->content_img_full[0] = '\0'; + path_data->content_img_short[0] = '\0'; + + /* Must also reset playlist thumbnail display modes */ + path_data->playlist_icon_mode = PLAYLIST_THUMBNAIL_MODE_DEFAULT; + path_data->playlist_index = 0; + + if (!playlist) + return false; + + if (idx >= playlist_get_size(playlist)) + return false; + + /* Read playlist values */ + playlist_get_index(playlist, idx, &entry); + + if (!entry) + return false; + + content_path = entry->path; + content_label = entry->label; + core_name = entry->core_name; + db_name = entry->db_name; + + /* Content without a path is invalid by definition */ + if (string_is_empty(content_path)) + return false; + + /* Cache content path + * (This is required for imageviewer, history and favourites content) */ + strlcpy(path_data->content_path, + content_path, sizeof(path_data->content_path)); + + /* Cache core name + * (This is required for imageviewer content) */ + if (!string_is_empty(core_name)) + strlcpy(path_data->content_core_name, + core_name, sizeof(path_data->content_core_name)); + + /* Get content label */ + if (!string_is_empty(content_label)) + path_data->content_label_len = strlcpy(path_data->content_label, + content_label, sizeof(path_data->content_label)); + else + path_data->content_label_len = fill_pathname( + path_data->content_label, + path_basename(content_path), + "", sizeof(path_data->content_label)); + + /* Determine content image name */ + { + char tmp_buf[NAME_MAX_LENGTH]; + fill_pathname(tmp_buf, path_basename(path_data->content_path), "", + sizeof(tmp_buf)); + + gfx_thumbnail_fill_content_img(path_data->content_img_full, + sizeof(path_data->content_img_full), tmp_buf, false); + gfx_thumbnail_fill_content_img(path_data->content_img, + sizeof(path_data->content_img), path_data->content_label, false); + + /* Explicit zero if full name is same as standard name - saves some queries later. */ + if(string_is_equal(path_data->content_img, path_data->content_img_full)) + path_data->content_img_full[0] = '\0'; + + gfx_thumbnail_fill_content_img(path_data->content_img_short, + sizeof(path_data->content_img_short), path_data->content_label, true); + } + + /* Store playlist index */ + path_data->playlist_index = idx; + + /* Redundant error check... */ + if (string_is_empty(path_data->content_img)) + return false; + + /* Thumbnail image name is done -> now check if + * per-content database name is defined */ + if (string_is_empty(db_name)) + playlist_get_db_name(playlist, idx, &db_name); + if (!string_is_empty(db_name)) + { + /* Hack: There is only one MAME thumbnail repo, + * so filter any input starting with 'MAME...' */ + if (strncmp(db_name, "MAME", 4) == 0) + { + path_data->content_db_name[0] = path_data->content_db_name[2] = 'M'; + path_data->content_db_name[1] = 'A'; + path_data->content_db_name[3] = 'E'; + path_data->content_db_name[4] = '\0'; + } + else + { + char tmp_buf[NAME_MAX_LENGTH]; + const char* pos = strchr(db_name, '|'); + + /* If db_name comes from core info, and there are multiple + * databases mentioned separated by |, use only first one */ + if (pos && (size_t) (pos - db_name)+1 < sizeof(tmp_buf)) + strlcpy(tmp_buf, db_name, (size_t) (pos - db_name)+1); + else + strlcpy(tmp_buf, db_name, sizeof(tmp_buf)); + + fill_pathname(path_data->content_db_name, + tmp_buf, "", + sizeof(path_data->content_db_name)); + } + } + + gfx_thumbnail_update_path(path_data, GFX_THUMBNAIL_ICON); + + /* Playlist entry is valid -> it is now 'safe' to + * extract any remaining playlist metadata + * (i.e. thumbnail display modes) */ + path_data->playlist_icon_mode = PLAYLIST_THUMBNAIL_MODE_DEFAULT; + + return true; +} + + static void xmb_set_dynamic_icon_content( void *xmb_handle_ptr, const char *s, @@ -1552,14 +1694,14 @@ static void xmb_set_dynamic_icon_content( /* Get playlist index corresponding * to the selected entry */ if ( list - && (selection < list_size) - && (list->list[selection].type == FILE_TYPE_RPL_ENTRY)) + && (selection < list_size) + && (list->list[selection].type == FILE_TYPE_RPL_ENTRY)) { playlist_valid = true; playlist_index = list->list[selection].entry_idx; } - gfx_thumbnail_set_icon_playlist(thumbnail_path_data, - playlist_valid ? playlist_get_cached() : NULL, playlist_index); + gfx_thumbnail_set_icon_playlist(thumbnail_path_data, + playlist_valid ? playlist_get_cached() : NULL, playlist_index); } } } @@ -2599,41 +2741,27 @@ static void xmb_context_reset_horizontal_list(xmb_handle_t *xmb) if (string_ends_with_size(path, ".lpl", strlen(path), STRLEN_CONST(".lpl"))) { - size_t len, syslen; + size_t __len, syslen; struct texture_image ti; char sysname[NAME_MAX_LENGTH]; char texturepath[PATH_MAX_LENGTH]; - char content_texturepath[PATH_MAX_LENGTH]; const char *console_name = NULL; /* Add current node to playlist database name map */ RHMAP_SET_STR(xmb->playlist_db_node_map, path, node); - syslen = fill_pathname_base(sysname, path, sizeof(sysname)); - /* Manually strip the extension (and dot) from sysname */ - sysname[syslen-4] = - sysname[syslen-3] = - sysname[syslen-2] = - sysname[syslen-1] = '\0'; - syslen -= 4; - len = fill_pathname_join_special(texturepath, iconpath, sysname, + syslen = fill_pathname(sysname, path_basename(path), "", + sizeof(sysname)); + __len = fill_pathname_join_special(texturepath, iconpath, sysname, sizeof(texturepath)); - texturepath[ len] = '.'; - texturepath[++len] = 'p'; - texturepath[++len] = 'n'; - texturepath[++len] = 'g'; - texturepath[++len] = '\0'; + __len += strlcpy(texturepath + __len, ".png", sizeof(texturepath) - __len); /* If the playlist icon doesn't exist return default */ if (!path_is_valid(texturepath)) { - len = fill_pathname_join_special(texturepath, iconpath, "default", + __len = fill_pathname_join_special(texturepath, iconpath, "default", sizeof(texturepath)); - texturepath[ len] = '.'; - texturepath[++len] = 'p'; - texturepath[++len] = 'n'; - texturepath[++len] = 'g'; - texturepath[++len] = '\0'; + __len += strlcpy(texturepath + __len, ".png", sizeof(texturepath) - __len); } ti.width = 0; @@ -2654,15 +2782,15 @@ static void xmb_context_reset_horizontal_list(xmb_handle_t *xmb) strlcpy(sysname + syslen, "-content.png", sizeof(sysname) - syslen); /* Assemble new icon path */ - fill_pathname_join_special(content_texturepath, iconpath, sysname, - sizeof(content_texturepath)); + fill_pathname_join_special(texturepath, iconpath, sysname, + sizeof(texturepath)); /* If the content icon doesn't exist, return default-content */ - if (!path_is_valid(content_texturepath)) - fill_pathname_join_delim(content_texturepath, icons_path_default, - FILE_PATH_CONTENT_BASENAME, '-', sizeof(content_texturepath)); + if (!path_is_valid(texturepath)) + fill_pathname_join_delim(texturepath, icons_path_default, + FILE_PATH_CONTENT_BASENAME, '-', sizeof(texturepath)); - if (image_texture_load(&ti, content_texturepath)) + if (image_texture_load(&ti, texturepath)) { if (ti.pixels) { @@ -2675,7 +2803,8 @@ static void xmb_context_reset_horizontal_list(xmb_handle_t *xmb) /* Console name */ console_name = xmb->horizontal_list.list[i].alt - ? xmb->horizontal_list.list[i].alt : xmb->horizontal_list.list[i].path; + ? xmb->horizontal_list.list[i].alt + : xmb->horizontal_list.list[i].path; if (node->console_name) free(node->console_name); @@ -2692,7 +2821,7 @@ static void xmb_context_reset_horizontal_list(xmb_handle_t *xmb) strlen(xmb->horizontal_list.list[i].label), STRLEN_CONST(".lvw"))) { node->console_name = strdup(path + strlen(msg_hash_to_str(MENU_ENUM_LABEL_EXPLORE_VIEW)) + 2); - node->icon = xmb->textures.list[XMB_TEXTURE_CURSOR]; + node->icon = xmb->textures.list[XMB_TEXTURE_CURSOR]; } } @@ -2718,7 +2847,7 @@ static void xmb_refresh_horizontal_list(xmb_handle_t *xmb) static int xmb_environ(enum menu_environ_cb type, void *data, void *userdata) { - xmb_handle_t *xmb = (xmb_handle_t*)userdata; + xmb_handle_t *xmb = (xmb_handle_t*)userdata; if (!xmb) return -1; @@ -2846,7 +2975,7 @@ static void xmb_populate_entries(void *data, xmb->skip_thumbnail_reset = true; xmb_system_tab = xmb_get_system_tab(xmb, (unsigned)xmb->categories_selection_ptr); - xmb_horizontal_type = (xmb_system_tab == UINT_MAX ? xmb_get_horizontal_selection_type(xmb) : 0); + xmb_horizontal_type = ((xmb_system_tab == UINT_MAX) ? xmb_get_horizontal_selection_type(xmb) : 0); /* Determine whether this is a playlist */ xmb->is_playlist = @@ -2893,7 +3022,7 @@ static void xmb_populate_entries(void *data, } /* Determine whether this is the contentless cores menu */ - xmb->is_contentless_cores = + xmb->is_contentless_cores = string_is_equal(label, msg_hash_to_str(MENU_ENUM_LABEL_CONTENTLESS_CORES_TAB)) || string_is_equal(label, msg_hash_to_str(MENU_ENUM_LABEL_DEFERRED_CONTENTLESS_CORES_LIST)); @@ -2928,7 +3057,7 @@ static void xmb_populate_entries(void *data, MENU_ENTRY_INITIALIZE(entry); entry.flags |= MENU_ENTRY_FLAG_LABEL_ENABLED - | MENU_ENTRY_FLAG_RICH_LABEL_ENABLED; + | MENU_ENTRY_FLAG_RICH_LABEL_ENABLED; menu_entry_get(&entry, 0, 0, NULL, true); /* Quick Menu under Explore list must also be Quick Menu */ @@ -5199,7 +5328,6 @@ static void xmb_show_fullscreen_thumbnails( size_t selection) { gfx_animation_ctx_entry_t animation_entry; - const char *core_name = NULL; bool animate = !xmb->want_fullscreen_thumbnails; uintptr_t alpha_tag = (uintptr_t)&xmb->fullscreen_thumbnail_alpha; @@ -5207,8 +5335,9 @@ static void xmb_show_fullscreen_thumbnails( * current selection has at least one valid thumbnail * and all thumbnails for current selection are already * loaded/available */ - gfx_thumbnail_get_core_name(menu_st->thumbnail_path_data, &core_name); - if ( string_is_equal(core_name, "imageviewer") + if ( (!string_is_empty(menu_st->thumbnail_path_data->content_core_name) + && string_is_equal(menu_st->thumbnail_path_data->content_core_name, + "imageviewer")) || !string_is_empty(xmb->savestate_thumbnail_file_path)) { /* imageviewer content requires special treatment, diff --git a/menu/menu_contentless_cores.c b/menu/menu_contentless_cores.c index 037f65cfcf..ae177a70ff 100644 --- a/menu/menu_contentless_cores.c +++ b/menu/menu_contentless_cores.c @@ -133,14 +133,10 @@ static void contentless_cores_init_info_entries( /* Populate licences string */ if (core_info->licenses_list) - { - char tmp_str[MENU_LABEL_MAX_LENGTH - 2]; - tmp_str[0] = '\0'; - string_list_join_concat(tmp_str, sizeof(tmp_str), + string_list_join_concat_special( + licenses_str + _len, + sizeof(licenses_str) - _len, core_info->licenses_list, ", "); - strlcpy(licenses_str + _len, tmp_str, - sizeof(licenses_str) - _len); - } /* No license found - set to N/A */ else strlcpy(licenses_str + _len, diff --git a/menu/menu_displaylist.c b/menu/menu_displaylist.c index 8ec94cd12d..1e138d6c23 100644 --- a/menu/menu_displaylist.c +++ b/menu/menu_displaylist.c @@ -781,14 +781,13 @@ static int menu_displaylist_parse_core_info( firmware_info.directory.system = settings->paths.directory_system; else { - size_t len = strlen(tmp_path); - + size_t __len = strlen(tmp_path); /* Removes trailing slash (unless root dir), doesn't really matter * but it's more consistent with how the path is stored and * displayed without 'System Files are in Content Directory' */ if ( string_count_occurrences_single_character(tmp_path, PATH_DEFAULT_SLASH_C()) > 1 - && tmp_path[len - 1] == PATH_DEFAULT_SLASH_C()) - tmp_path[len - 1] = '\0'; + && tmp_path[__len - 1] == PATH_DEFAULT_SLASH_C()) + tmp_path[__len - 1] = '\0'; firmware_info.directory.system = tmp_path; } @@ -811,12 +810,12 @@ static int menu_displaylist_parse_core_info( const char *present_required = msg_hash_to_str(MENU_ENUM_LABEL_VALUE_PRESENT_REQUIRED); const char *rdb_entry_name = msg_hash_to_str(MENU_ENUM_LABEL_VALUE_RDB_ENTRY_NAME); - size_t len = strlcpy(tmp, + size_t __len = strlcpy(tmp, msg_hash_to_str(MENU_ENUM_LABEL_VALUE_CORE_INFO_FIRMWARE), sizeof(tmp)); - tmp[ len] = ':'; - tmp[++len] = ' '; - tmp[++len] = '\0'; + tmp[ __len] = ':'; + tmp[++__len] = ' '; + tmp[++__len] = '\0'; if (menu_entries_append(list, tmp, "", MENU_ENUM_LABEL_CORE_INFO_ENTRY, MENU_SETTINGS_CORE_INFO_NONE, 0, 0, NULL)) count++; @@ -885,8 +884,8 @@ static int menu_displaylist_parse_core_info( pos = string_find_index_substring_string(core_info->note_list->elems[j].data, "(md5)"); core_info_list_hide[j] = true; - len = strlcpy(tmp, "- ", sizeof(tmp)); - strlcpy(tmp + len, core_info->note_list->elems[j].data + pos, sizeof(tmp) - len); + __len = strlcpy(tmp, "- ", sizeof(tmp)); + strlcpy(tmp + __len, core_info->note_list->elems[j].data + pos, sizeof(tmp) - __len); if (menu_entries_append(list, tmp, "", MENU_ENUM_LABEL_CORE_INFO_ENTRY, @@ -2667,8 +2666,8 @@ static int create_string_list_rdb_entry_string( static int create_string_list_rdb_entry_int( enum msg_hash_enums enum_idx, const char *desc, const char *label, - int actual_int, const char *path, - size_t path_len, + int actual_int, + const char *path, size_t path_len, file_list_t *list) { size_t _len; @@ -4101,19 +4100,12 @@ static int menu_displaylist_parse_horizontal_content_actions( break; case PLAYLIST_ENTRY_REMOVE_ENABLE_HIST_FAV: { - const char *tmp; - char sys_thumb[64]; - size_t __len = 0; - - if (gfx_thumbnail_get_system(menu_st->thumbnail_path_data, &tmp)) - __len = strlcpy(sys_thumb, tmp, sizeof(sys_thumb)); - - if (!string_is_empty(sys_thumb)) + if (!string_is_empty(menu_st->thumbnail_path_data->system)) remove_entry_enabled = - string_is_equal(sys_thumb, "history") - || string_is_equal(sys_thumb, "favorites") - || string_ends_with_size(sys_thumb, "_history", - __len, STRLEN_CONST("_history")); + string_is_equal(menu_st->thumbnail_path_data->system, "history") + || string_is_equal(menu_st->thumbnail_path_data->system, "favorites") + || string_ends_with_size(menu_st->thumbnail_path_data->system, "_history", + menu_st->thumbnail_path_data->system_len, STRLEN_CONST("_history")); /* An annoyance: if the user navigates to the information menu, * then to the database entry, the thumbnail system will be changed. @@ -4200,16 +4192,12 @@ static int menu_displaylist_parse_horizontal_content_actions( if (download_enabled) { /* Only show 'Download Thumbnails' on supported playlists */ - char sys_thumb[64]; - const char *tmp = NULL; - size_t __len = 0; - - if (gfx_thumbnail_get_system(menu_st->thumbnail_path_data, &tmp)) - __len = strlcpy(sys_thumb, tmp, sizeof(sys_thumb)); - - if (!string_is_empty(sys_thumb)) + if (!string_is_empty(menu_st->thumbnail_path_data->system)) download_enabled = !string_ends_with_size( - sys_thumb, "_history", __len, STRLEN_CONST("_history")); + menu_st->thumbnail_path_data->system, + "_history", + menu_st->thumbnail_path_data->system_len, + STRLEN_CONST("_history")); else download_enabled = false; } diff --git a/tasks/task_pl_thumbnail_download.c b/tasks/task_pl_thumbnail_download.c index 115b38ce6a..c3f53fd0f8 100644 --- a/tasks/task_pl_thumbnail_download.c +++ b/tasks/task_pl_thumbnail_download.c @@ -136,6 +136,41 @@ static void gfx_thumbnail_get_db_name( *db_name = path_data->content_db_name; } +/* Fetches current thumbnail image name according to name flag + * (name is the same for all thumbnail types). + * Returns true if image name is valid. */ +static bool gfx_thumbnail_get_img_name( + gfx_thumbnail_path_data_t *path_data, const char **img_name, + enum playlist_thumbnail_name_flags name_flags) +{ + if (!path_data || !img_name || name_flags == PLAYLIST_THUMBNAIL_FLAG_NONE) + return false; + + if (name_flags & PLAYLIST_THUMBNAIL_FLAG_SHORT_NAME) + { + if (string_is_empty(path_data->content_img_short)) + return false; + *img_name = path_data->content_img_short; + } + else if (name_flags & PLAYLIST_THUMBNAIL_FLAG_STD_NAME) + { + if (string_is_empty(path_data->content_img)) + return false; + *img_name = path_data->content_img; + } + else if (name_flags & PLAYLIST_THUMBNAIL_FLAG_FULL_NAME) + { + if (string_is_empty(path_data->content_img_full)) + return false; + *img_name = path_data->content_img_full; + } + else + return false; + + return true; +} + + /* Fetches local and remote paths for current thumbnail * of current type */ static bool task_pl_thumbnail_get_thumbnail_paths( @@ -147,22 +182,23 @@ static bool task_pl_thumbnail_get_thumbnail_paths( char tmp_buf[PATH_MAX_LENGTH]; size_t raw_url_len = sizeof(char) * 8192; /* TODO/FIXME - check size */ char *raw_url = NULL; - const char *system = NULL; const char *db_name = NULL; const char *img_name = NULL; const char *sub_dir = NULL; const char *system_name = NULL; + const char *system = NULL; content_dir[0] = '\0'; if (!pl_thumb->thumbnail_path_data) return false; + system = pl_thumb->thumbnail_path_data->system; + if (string_is_empty(pl_thumb->dir_thumbnails)) return false; /* Extract required strings */ - gfx_thumbnail_get_system( pl_thumb->thumbnail_path_data, &system); gfx_thumbnail_get_db_name(pl_thumb->thumbnail_path_data, &db_name); if (!gfx_thumbnail_get_img_name(pl_thumb->thumbnail_path_data, &img_name, pl_thumb->name_flags)) return false; @@ -302,7 +338,8 @@ static void download_pl_thumbnail(pl_thumb_handle_t *pl_thumb) url, sizeof(url))) { /* Only download missing thumbnails */ - if (!path_is_valid(path) || (pl_thumb->flags & PL_THUMB_FLAG_OVERWRITE)) + if ( !path_is_valid(path) + || (pl_thumb->flags & PL_THUMB_FLAG_OVERWRITE)) { file_transfer_t *transf = (file_transfer_t*)malloc(sizeof(file_transfer_t)); if (!transf) @@ -419,12 +456,10 @@ static void task_pl_thumbnail_download_handler(retro_task_t *task) if (gfx_thumbnail_set_content_playlist( pl_thumb->thumbnail_path_data, pl_thumb->playlist, pl_thumb->list_index)) { - const char *label = NULL; - /* Update progress display */ task_free_title(task); - if (gfx_thumbnail_get_label(pl_thumb->thumbnail_path_data, &label)) - task_set_title(task, strdup(label)); + if (!string_is_empty(pl_thumb->thumbnail_path_data->content_label)) + task_set_title(task, strdup(pl_thumb->thumbnail_path_data->content_label)); else task_set_title(task, strdup("")); task_set_progress(task, (pl_thumb->list_index * 100) / pl_thumb->list_size); @@ -618,8 +653,6 @@ static void cb_task_pl_entry_thumbnail_refresh_menu( { #if defined(RARCH_INTERNAL) && defined(HAVE_MENU) pl_thumb_handle_t *pl_thumb = NULL; - const char *thumbnail_path = NULL; - const char *left_thumbnail_path = NULL; bool do_refresh = false; playlist_t *current_playlist = playlist_get_cached(); menu_handle_t *menu = menu_state_get_ptr()->driver_data; @@ -671,15 +704,21 @@ static void cb_task_pl_entry_thumbnail_refresh_menu( if ( !(pl_thumb->flags & PL_THUMB_FLAG_RIGHT_THUMB_EXISTS) ||(pl_thumb->flags & PL_THUMB_FLAG_OVERWRITE)) if (gfx_thumbnail_update_path(pl_thumb->thumbnail_path_data, GFX_THUMBNAIL_RIGHT)) - if (gfx_thumbnail_get_path(pl_thumb->thumbnail_path_data, GFX_THUMBNAIL_RIGHT, &thumbnail_path)) - do_refresh = path_is_valid(thumbnail_path); + { + if (!string_is_empty(pl_thumb->thumbnail_path_data->right_path)) + do_refresh = path_is_valid(pl_thumb->thumbnail_path_data->right_path); + } if (!do_refresh) if ( !(pl_thumb->flags & PL_THUMB_FLAG_LEFT_THUMB_EXISTS) || (pl_thumb->flags & PL_THUMB_FLAG_OVERWRITE)) + { if (gfx_thumbnail_update_path(pl_thumb->thumbnail_path_data, GFX_THUMBNAIL_LEFT)) - if (gfx_thumbnail_get_path(pl_thumb->thumbnail_path_data, GFX_THUMBNAIL_LEFT, &left_thumbnail_path)) - do_refresh = path_is_valid(left_thumbnail_path); + { + if (!string_is_empty(pl_thumb->thumbnail_path_data->left_path)) + do_refresh = path_is_valid(pl_thumb->thumbnail_path_data->left_path); + } + } if (do_refresh) { @@ -721,52 +760,38 @@ static void task_pl_entry_thumbnail_download_handler(retro_task_t *task) switch (pl_thumb->status) { case PL_THUMB_BEGIN: + /* Check whether current right/left thumbnails + * already exist (required for menu refresh callback) */ + pl_thumb->flags &= ~PL_THUMB_FLAG_RIGHT_THUMB_EXISTS; + pl_thumb->flags &= ~PL_THUMB_FLAG_LEFT_THUMB_EXISTS; + + if (gfx_thumbnail_update_path(pl_thumb->thumbnail_path_data, + GFX_THUMBNAIL_RIGHT)) { - const char *label = NULL; - const char *right_thumbnail_path = NULL; - const char *left_thumbnail_path = NULL; - - /* Check whether current right/left thumbnails - * already exist (required for menu refresh callback) */ - pl_thumb->flags &= ~PL_THUMB_FLAG_RIGHT_THUMB_EXISTS; - pl_thumb->flags &= ~PL_THUMB_FLAG_LEFT_THUMB_EXISTS; - - if (gfx_thumbnail_update_path( - pl_thumb->thumbnail_path_data, GFX_THUMBNAIL_RIGHT)) - { - if (gfx_thumbnail_get_path( - pl_thumb->thumbnail_path_data, - GFX_THUMBNAIL_RIGHT, &right_thumbnail_path)) - { - if (path_is_valid(right_thumbnail_path)) - pl_thumb->flags |= PL_THUMB_FLAG_RIGHT_THUMB_EXISTS; - } - } - - if (gfx_thumbnail_update_path( - pl_thumb->thumbnail_path_data, GFX_THUMBNAIL_LEFT)) - { - if (gfx_thumbnail_get_path( - pl_thumb->thumbnail_path_data, - GFX_THUMBNAIL_LEFT, &left_thumbnail_path)) - { - if (path_is_valid(left_thumbnail_path)) - pl_thumb->flags |= PL_THUMB_FLAG_LEFT_THUMB_EXISTS; - } - } - - /* Set task title */ - task_free_title(task); - if (gfx_thumbnail_get_label( - pl_thumb->thumbnail_path_data, &label)) - task_set_title(task, strdup(label)); - else - task_set_title(task, strdup("")); - task_set_progress(task, 0); - - /* All good - can start iterating */ - pl_thumb->status = PL_THUMB_ITERATE_TYPE; + if ( !string_is_empty(pl_thumb->thumbnail_path_data->right_path) + && path_is_valid(pl_thumb->thumbnail_path_data->right_path)) + pl_thumb->flags |= PL_THUMB_FLAG_RIGHT_THUMB_EXISTS; } + + if (gfx_thumbnail_update_path(pl_thumb->thumbnail_path_data, + GFX_THUMBNAIL_LEFT)) + { + if ( !string_is_empty(pl_thumb->thumbnail_path_data->left_path) + && path_is_valid(pl_thumb->thumbnail_path_data->left_path)) + pl_thumb->flags |= PL_THUMB_FLAG_LEFT_THUMB_EXISTS; + } + + /* Set task title */ + task_free_title(task); + if (!string_is_empty( + pl_thumb->thumbnail_path_data->content_label)) + task_set_title(task, strdup(pl_thumb->thumbnail_path_data->content_label)); + else + task_set_title(task, strdup("")); + task_set_progress(task, 0); + + /* All good - can start iterating */ + pl_thumb->status = PL_THUMB_ITERATE_TYPE; break; case PL_THUMB_ITERATE_TYPE: { @@ -856,9 +881,9 @@ bool task_push_pl_entry_thumbnail_download( dir_thumbnails = settings->paths.directory_thumbnails; - if (string_is_empty(system) || - string_is_empty(dir_thumbnails) || - string_is_empty(playlist_get_conf_path(playlist))) + if ( string_is_empty(system) + || string_is_empty(dir_thumbnails) + || string_is_empty(playlist_get_conf_path(playlist))) goto error; if (idx >= playlist_size(playlist)) diff --git a/ui/drivers/cocoa/cocoa_common.m b/ui/drivers/cocoa/cocoa_common.m index 9d9ae21a8b..c760fdf2d4 100644 --- a/ui/drivers/cocoa/cocoa_common.m +++ b/ui/drivers/cocoa/cocoa_common.m @@ -1059,8 +1059,8 @@ static NSDictionary *topshelfDictForEntry(const struct playlist_entry *entry, gf }]; if (!string_is_empty(path_data->content_db_name)) { - const char *img_name = NULL; - if (gfx_thumbnail_get_img_name(path_data, &img_name, PLAYLIST_THUMBNAIL_FLAG_STD_NAME)) + const char *img_name = path_data->content_img; + if (!string_is_empty(img_name)) dict[@"img"] = [NSString stringWithFormat:@"https://thumbnails.libretro.com/%s/Named_Boxarts/%s", path_data->content_db_name, img_name]; }