Skip to content

Commit

Permalink
This change allows playlist icons to be replaced with Logos. (libretr…
Browse files Browse the repository at this point in the history
…o#16758)

* This change allows playlist icons to be replaced with Logos. the art is loaded to the Thumbnail Named_Logos folder. It is treated the same as other thumbnails for naming and for automatic download. There is a settings menu option to turn it on and off. It is off by default. This only applies to the xmb menu driver.

* Removed commented out code against the style guide.

* Code cleanup for C89 compatibitity

* Cleaned up errors from Automated CI.

* Cleaned up comments.

* Update gfx_display.c

change strcpy to strlcpy

* Update gfx_thumbnail_path.c

fix code formatting

* Update xmb.c

code formatting changes
  • Loading branch information
jbreitweiser authored and Sunderland93 committed Dec 26, 2024
1 parent 034fbcc commit 952ae5a
Show file tree
Hide file tree
Showing 17 changed files with 572 additions and 20 deletions.
1 change: 1 addition & 0 deletions config.def.h
Original file line number Diff line number Diff line change
Expand Up @@ -1620,6 +1620,7 @@
#define DEFAULT_GFX_THUMBNAILS_DEFAULT 3

#define DEFAULT_MENU_LEFT_THUMBNAILS_DEFAULT 0
#define DEFAULT_MENU_ICON_THUMBNAILS_DEFAULT 0

#define DEFAULT_GFX_THUMBNAIL_UPSCALE_THRESHOLD 0

Expand Down
1 change: 1 addition & 0 deletions configuration.c
Original file line number Diff line number Diff line change
Expand Up @@ -2352,6 +2352,7 @@ static struct config_uint_setting *populate_settings_uint(
SETTING_UINT("quit_on_close_content", &settings->uints.quit_on_close_content, true, DEFAULT_QUIT_ON_CLOSE_CONTENT, false);
SETTING_UINT("menu_thumbnails", &settings->uints.gfx_thumbnails, true, DEFAULT_GFX_THUMBNAILS_DEFAULT, false);
SETTING_UINT("menu_left_thumbnails", &settings->uints.menu_left_thumbnails, true, DEFAULT_MENU_LEFT_THUMBNAILS_DEFAULT, false);
SETTING_UINT("menu_icon_thumbnails", &settings->uints.menu_icon_thumbnails, true, DEFAULT_MENU_ICON_THUMBNAILS_DEFAULT, false);
SETTING_UINT("menu_thumbnail_upscale_threshold", &settings->uints.gfx_thumbnail_upscale_threshold, true, DEFAULT_GFX_THUMBNAIL_UPSCALE_THRESHOLD, false);
SETTING_UINT("menu_timedate_style", &settings->uints.menu_timedate_style, true, DEFAULT_MENU_TIMEDATE_STYLE, false);
SETTING_UINT("menu_timedate_date_separator", &settings->uints.menu_timedate_date_separator, true, DEFAULT_MENU_TIMEDATE_DATE_SEPARATOR, false);
Expand Down
1 change: 1 addition & 0 deletions configuration.h
Original file line number Diff line number Diff line change
Expand Up @@ -274,6 +274,7 @@ typedef struct settings
unsigned menu_timedate_date_separator;
unsigned gfx_thumbnails;
unsigned menu_left_thumbnails;
unsigned menu_icon_thumbnails;
unsigned gfx_thumbnail_upscale_threshold;
unsigned menu_rgui_thumbnail_downscaler;
unsigned menu_rgui_thumbnail_delay;
Expand Down
33 changes: 33 additions & 0 deletions gfx/gfx_display.c
Original file line number Diff line number Diff line change
Expand Up @@ -1127,6 +1127,39 @@ bool gfx_display_reset_textures_list(
return true;
}

bool gfx_display_reset_icon_texture(
const char *texture_path,
uintptr_t *item, enum texture_filter_type filter_type,
unsigned *width, unsigned *height)
{
char texpath[PATH_MAX_LENGTH];
struct texture_image ti;

ti.width = 0;
ti.height = 0;
ti.pixels = NULL;
ti.supports_rgba = video_driver_supports_rgba();

if (string_is_empty(texture_path))
return false;

strlcpy(texpath, texture_path, sizeof(texpath));

if (!image_texture_load(&ti, texpath))
return false;

if (width)
*width = ti.width;

if (height)
*height = ti.height;

video_driver_texture_load(&ti, filter_type, item);
image_texture_free(&ti);

return true;
}

void gfx_display_deinit_white_texture(void)
{
if (gfx_white_texture)
Expand Down
5 changes: 5 additions & 0 deletions gfx/gfx_display.h
Original file line number Diff line number Diff line change
Expand Up @@ -293,6 +293,11 @@ bool gfx_display_reset_textures_list(
unsigned *width,
unsigned *height);

bool gfx_display_reset_icon_texture(
const char *texture_path,
uintptr_t *item, enum texture_filter_type filter_type,
unsigned *width, unsigned *height);

bool gfx_display_reset_textures_list_buffer(
uintptr_t *item,
enum texture_filter_type filter_type,
Expand Down
183 changes: 183 additions & 0 deletions gfx/gfx_thumbnail_path.c
Original file line number Diff line number Diff line change
Expand Up @@ -94,6 +94,9 @@ static const char *gfx_thumbnail_get_type(
else
type = menu_left_thumbnails;
break;
case GFX_THUMBNAIL_ICON:
type = 4;
break;
default:
goto end;
}
Expand All @@ -106,6 +109,8 @@ static const char *gfx_thumbnail_get_type(
return "Named_Titles";
case 3:
return "Named_Boxarts";
case 4:
return "Named_Logos";
case 0:
default:
break;
Expand Down Expand Up @@ -167,6 +172,8 @@ bool gfx_thumbnail_is_enabled(gfx_thumbnail_path_data_t *path_data, enum gfx_thu
settings_t *settings = config_get_ptr();
unsigned gfx_thumbnails = settings->uints.gfx_thumbnails;
unsigned menu_left_thumbnails = settings->uints.menu_left_thumbnails;
unsigned menu_icon_thumbnails = settings->uints.menu_icon_thumbnails;

switch (thumbnail_id)
{
case GFX_THUMBNAIL_RIGHT:
Expand All @@ -177,6 +184,10 @@ bool gfx_thumbnail_is_enabled(gfx_thumbnail_path_data_t *path_data, enum gfx_thu
if (path_data->playlist_left_mode != PLAYLIST_THUMBNAIL_MODE_DEFAULT)
return path_data->playlist_left_mode != PLAYLIST_THUMBNAIL_MODE_OFF;
return menu_left_thumbnails != 0;
case GFX_THUMBNAIL_ICON:
if (path_data->playlist_icon_mode != PLAYLIST_THUMBNAIL_MODE_DEFAULT)
return path_data->playlist_left_mode != PLAYLIST_THUMBNAIL_MODE_OFF;
return menu_icon_thumbnails != 0;
default:
break;
}
Expand Down Expand Up @@ -555,6 +566,168 @@ 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;
char content_dir[PATH_MAX_LENGTH];
const char *dir_thumbnails = NULL;
settings_t *settings = config_get_ptr();

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* content_name_no_ext = NULL;
char tmp_buf[PATH_MAX_LENGTH];
/* Remove rom file extension
* > path_remove_extension() requires a char * (not const)
* so have to use a temporary buffer... */

const char* base_name = path_basename(path_data->content_path);
strlcpy(tmp_buf, base_name, sizeof(tmp_buf));
content_name_no_ext = path_remove_extension(tmp_buf);
if (!content_name_no_ext)
content_name_no_ext = tmp_buf;

gfx_thumbnail_fill_content_img(path_data->content_img_full,
sizeof(path_data->content_img_full), content_name_no_ext,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(strcmp(path_data->content_img, path_data->content_img_full) == 0)
{
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 *db_name_no_ext = NULL;
char tmp_buf[PATH_MAX_LENGTH];
const char* pos = strchr(db_name, '|');

if (pos && (size_t) (pos - db_name)+1 < sizeof(tmp_buf)) {
/* If db_name comes from core info, and there are multiple
* databases mentioned separated by |, use only first one */
strlcpy(tmp_buf, db_name, (size_t) (pos - db_name)+1);
}
else
{
/* Remove .lpl extension
* > path_remove_extension() requires a char * (not const)
* so have to use a temporary buffer... */
strlcpy(tmp_buf, db_name, sizeof(tmp_buf));
}
db_name_no_ext = path_remove_extension(tmp_buf);

if (!string_is_empty(db_name_no_ext))
strlcpy(path_data->content_db_name,
db_name_no_ext, sizeof(path_data->content_db_name));
else
strlcpy(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).
Expand Down Expand Up @@ -589,6 +762,9 @@ bool gfx_thumbnail_update_path(
case GFX_THUMBNAIL_LEFT:
thumbnail_path = path_data->left_path;
break;
case GFX_THUMBNAIL_ICON:
thumbnail_path = path_data->icon_path;
break;
default:
return false;
}
Expand Down Expand Up @@ -752,6 +928,13 @@ bool gfx_thumbnail_get_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;
Expand Down
7 changes: 6 additions & 1 deletion gfx/gfx_thumbnail_path.h
Original file line number Diff line number Diff line change
Expand Up @@ -44,7 +44,8 @@ RETRO_BEGIN_DECLS
enum gfx_thumbnail_id
{
GFX_THUMBNAIL_RIGHT = 0,
GFX_THUMBNAIL_LEFT
GFX_THUMBNAIL_LEFT,
GFX_THUMBNAIL_ICON
};

/* Prevent direct access to gfx_thumbnail_path_data_t members */
Expand All @@ -57,13 +58,15 @@ struct gfx_thumbnail_path_data
{
enum playlist_thumbnail_mode playlist_right_mode;
enum playlist_thumbnail_mode playlist_left_mode;
enum playlist_thumbnail_mode playlist_icon_mode;
size_t playlist_index;
char content_path[PATH_MAX_LENGTH];
char content_img[PATH_MAX_LENGTH];
char content_img_short[PATH_MAX_LENGTH];
char content_img_full[PATH_MAX_LENGTH];
char right_path[PATH_MAX_LENGTH];
char left_path[PATH_MAX_LENGTH];
char icon_path[PATH_MAX_LENGTH];
char content_label[256];
char content_core_name[256];
char system[256];
Expand Down Expand Up @@ -116,6 +119,8 @@ 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).
Expand Down
4 changes: 4 additions & 0 deletions intl/msg_hash_lbl.h
Original file line number Diff line number Diff line change
Expand Up @@ -3893,6 +3893,10 @@ MSG_HASH(
MENU_ENUM_LABEL_SYSTEM_INFO_ENTRY,
"system_info_entry"
)
MSG_HASH(
MENU_ENUM_LABEL_ICON_THUMBNAILS,
"icon_thumbnails"
)
MSG_HASH(
MENU_ENUM_LABEL_TAKE_SCREENSHOT,
"take_screenshot"
Expand Down
12 changes: 12 additions & 0 deletions intl/msg_hash_us.h
Original file line number Diff line number Diff line change
Expand Up @@ -6955,6 +6955,14 @@ MSG_HASH(
MENU_ENUM_LABEL_VALUE_SETTINGS_SHOW_USER,
"Show 'User'"
)
MSG_HASH(
MENU_ENUM_LABEL_VALUE_ICON_THUMBNAILS,
"Playlist Icons"
)
MSG_HASH(
MENU_ENUM_SUBLABEL_ICON_THUMBNAILS,
"Type of Playlist icon thumbnail to display."
)
MSG_HASH(
MENU_ENUM_SUBLABEL_SETTINGS_SHOW_USER,
"Show 'User' settings."
Expand Down Expand Up @@ -11121,6 +11129,10 @@ MSG_HASH(
MENU_ENUM_LABEL_VALUE_THUMBNAIL_MODE_TITLE_SCREENS,
"Title Screen"
)
MSG_HASH(
MENU_ENUM_LABEL_VALUE_THUMBNAIL_MODE_LOGOS,
"Content Logo"
)
MSG_HASH(
MENU_ENUM_LABEL_VALUE_SCROLL_NORMAL,
"Normal"
Expand Down
4 changes: 4 additions & 0 deletions menu/cbs/menu_cbs_sublabel.c
Original file line number Diff line number Diff line change
Expand Up @@ -912,6 +912,7 @@ DEFAULT_SUBLABEL_MACRO(action_bind_sublabel_netplay_nat_traversal, MENU_
DEFAULT_SUBLABEL_MACRO(action_bind_sublabel_stdin_cmd_enable, MENU_ENUM_SUBLABEL_STDIN_CMD_ENABLE)
DEFAULT_SUBLABEL_MACRO(action_bind_sublabel_mouse_enable, MENU_ENUM_SUBLABEL_MOUSE_ENABLE)
DEFAULT_SUBLABEL_MACRO(action_bind_sublabel_pointer_enable, MENU_ENUM_SUBLABEL_POINTER_ENABLE)
DEFAULT_SUBLABEL_MACRO(action_bind_sublabel_icon_thumbnails, MENU_ENUM_SUBLABEL_ICON_THUMBNAILS)
DEFAULT_SUBLABEL_MACRO(action_bind_sublabel_thumbnails, MENU_ENUM_SUBLABEL_THUMBNAILS)
#ifdef HAVE_MATERIALUI
DEFAULT_SUBLABEL_MACRO(action_bind_sublabel_thumbnails_materialui, MENU_ENUM_SUBLABEL_THUMBNAILS_MATERIALUI)
Expand Down Expand Up @@ -3675,6 +3676,9 @@ int menu_cbs_init_bind_sublabel(menu_file_list_cbs_t *cbs,
}
}
break;
case MENU_ENUM_LABEL_ICON_THUMBNAILS:
BIND_ACTION_SUBLABEL(cbs, action_bind_sublabel_icon_thumbnails);
break;
case MENU_ENUM_LABEL_MENU_THUMBNAIL_UPSCALE_THRESHOLD:
BIND_ACTION_SUBLABEL(cbs, action_bind_sublabel_menu_thumbnail_upscale_threshold);
break;
Expand Down
Loading

0 comments on commit 952ae5a

Please sign in to comment.