Enable customisation of runtime 'last played' display format

This commit is contained in:
jdgleaver 2019-09-10 16:13:25 +01:00
parent f6d1cbe6b9
commit a0fd9d21d2
17 changed files with 546 additions and 146 deletions

View File

@ -861,6 +861,9 @@ static const unsigned playlist_show_inline_core_name = PLAYLIST_INLINE_CORE_DISP
/* Specifies which runtime record to use on playlist sublabels */
static const unsigned playlist_sublabel_runtime_type = PLAYLIST_RUNTIME_PER_CORE;
/* Specifies time/date display format for runtime 'last played' data */
#define DEFAULT_PLAYLIST_SUBLABEL_LAST_PLAYED_STYLE PLAYLIST_LAST_PLAYED_STYLE_YMD_HMS
static const unsigned playlist_entry_remove_enable = PLAYLIST_ENTRY_REMOVE_ENABLE_ALL;
#endif

View File

@ -1867,6 +1867,7 @@ static struct config_uint_setting *populate_settings_uint(settings_t *settings,
SETTING_UINT("playlist_entry_remove_enable", &settings->uints.playlist_entry_remove_enable, true, playlist_entry_remove_enable, false);
SETTING_UINT("playlist_show_inline_core_name", &settings->uints.playlist_show_inline_core_name, true, playlist_show_inline_core_name, false);
SETTING_UINT("playlist_sublabel_runtime_type", &settings->uints.playlist_sublabel_runtime_type, true, playlist_sublabel_runtime_type, false);
SETTING_UINT("playlist_sublabel_last_played_style", &settings->uints.playlist_sublabel_last_played_style, true, DEFAULT_PLAYLIST_SUBLABEL_LAST_PLAYED_STYLE, false);
#endif
*size = count;

View File

@ -538,6 +538,7 @@ typedef struct settings
unsigned playlist_entry_remove_enable;
unsigned playlist_show_inline_core_name;
unsigned playlist_sublabel_runtime_type;
unsigned playlist_sublabel_last_played_style;
unsigned camera_width;
unsigned camera_height;

View File

@ -1985,6 +1985,8 @@ MSG_HASH(MENU_ENUM_LABEL_PLAYLIST_FUZZY_ARCHIVE_MATCH,
"playlist_fuzzy_archive_match")
MSG_HASH(MENU_ENUM_LABEL_PLAYLIST_SUBLABEL_RUNTIME_TYPE,
"playlist_sublabel_runtime_type")
MSG_HASH(MENU_ENUM_LABEL_PLAYLIST_SUBLABEL_LAST_PLAYED_STYLE,
"playlist_sublabel_last_played_style")
MSG_HASH(MENU_ENUM_LABEL_HELP_SEND_DEBUG_INFO,
"help_send_debug_info")
MSG_HASH(MENU_ENUM_LABEL_VIBRATE_ON_KEYPRESS,

View File

@ -9007,6 +9007,58 @@ MSG_HASH(
MENU_ENUM_LABEL_VALUE_PLAYLIST_RUNTIME_PER_CORE,
"Per Core"
)
MSG_HASH(
MENU_ENUM_LABEL_VALUE_PLAYLIST_RUNTIME_AGGREGATE,
"Aggregate"
)
MSG_HASH(
MENU_ENUM_LABEL_VALUE_PLAYLIST_SUBLABEL_LAST_PLAYED_STYLE,
"Playlist sublabel runtime 'last played' format"
)
MSG_HASH(
MENU_ENUM_SUBLABEL_PLAYLIST_SUBLABEL_LAST_PLAYED_STYLE,
"Selects date/time formatting style used when displaying runtime log record 'last played' timestamp information. Note: '(AM/PM)' options will have a small performance impact on some platforms."
)
MSG_HASH(
MENU_ENUM_LABEL_VALUE_PLAYLIST_SUBLABEL_LAST_PLAYED_STYLE_YMD_HMS,
"YYYY/MM/DD - HH:MM:SS"
)
MSG_HASH(
MENU_ENUM_LABEL_VALUE_PLAYLIST_SUBLABEL_LAST_PLAYED_STYLE_YMD_HM,
"YYYY/MM/DD - HH:MM"
)
MSG_HASH(
MENU_ENUM_LABEL_VALUE_PLAYLIST_SUBLABEL_LAST_PLAYED_STYLE_MDYYYY,
"MM/DD/YYYY - HH:MM"
)
MSG_HASH(
MENU_ENUM_LABEL_VALUE_PLAYLIST_SUBLABEL_LAST_PLAYED_STYLE_DM_HM,
"DD/MM - HH:MM"
)
MSG_HASH(
MENU_ENUM_LABEL_VALUE_PLAYLIST_SUBLABEL_LAST_PLAYED_STYLE_MD_HM,
"MM/DD - HH:MM"
)
MSG_HASH(
MENU_ENUM_LABEL_VALUE_PLAYLIST_SUBLABEL_LAST_PLAYED_STYLE_YMD_HMS_AM_PM,
"YYYY/MM/DD - HH:MM:SS (AM/PM)"
)
MSG_HASH(
MENU_ENUM_LABEL_VALUE_PLAYLIST_SUBLABEL_LAST_PLAYED_STYLE_YMD_HM_AM_PM,
"YYYY/MM/DD - HH:MM (AM/PM)"
)
MSG_HASH(
MENU_ENUM_LABEL_VALUE_PLAYLIST_SUBLABEL_LAST_PLAYED_STYLE_MDYYYY_AM_PM,
"MM/DD/YYYY - HH:MM (AM/PM)"
)
MSG_HASH(
MENU_ENUM_LABEL_VALUE_PLAYLIST_SUBLABEL_LAST_PLAYED_STYLE_DM_HM_AM_PM,
"DD/MM - HH:MM (AM/PM)"
)
MSG_HASH(
MENU_ENUM_LABEL_VALUE_PLAYLIST_SUBLABEL_LAST_PLAYED_STYLE_MD_HM_AM_PM,
"MM/DD - HH:MM (AM/PM)"
)
MSG_HASH(
MENU_ENUM_LABEL_VALUE_PLAYLIST_FUZZY_ARCHIVE_MATCH,
"Fuzzy archive matching"
@ -9015,10 +9067,7 @@ MSG_HASH(
MENU_ENUM_SUBLABEL_PLAYLIST_FUZZY_ARCHIVE_MATCH,
"When searching playlists for entries associated with compressed files, match only the archive file name instead of [file name]+[content]. Enable this to avoid duplicate content history entries when loading compressed files."
)
MSG_HASH(
MENU_ENUM_LABEL_VALUE_PLAYLIST_RUNTIME_AGGREGATE,
"Aggregate"
)
MSG_HASH(
MENU_ENUM_LABEL_VALUE_HELP_SEND_DEBUG_INFO,
"Send Debug Info"

View File

@ -678,6 +678,7 @@ default_sublabel_macro(action_bind_sublabel_content_runtime_log,
default_sublabel_macro(action_bind_sublabel_content_runtime_log_aggregate, MENU_ENUM_SUBLABEL_CONTENT_RUNTIME_LOG_AGGREGATE)
default_sublabel_macro(action_bind_sublabel_scan_without_core_match, MENU_ENUM_SUBLABEL_SCAN_WITHOUT_CORE_MATCH)
default_sublabel_macro(action_bind_sublabel_playlist_sublabel_runtime_type, MENU_ENUM_SUBLABEL_PLAYLIST_SUBLABEL_RUNTIME_TYPE)
default_sublabel_macro(action_bind_sublabel_playlist_sublabel_last_played_style, MENU_ENUM_SUBLABEL_PLAYLIST_SUBLABEL_LAST_PLAYED_STYLE)
default_sublabel_macro(action_bind_sublabel_menu_rgui_internal_upscale_level, MENU_ENUM_SUBLABEL_MENU_RGUI_INTERNAL_UPSCALE_LEVEL)
default_sublabel_macro(action_bind_sublabel_menu_rgui_aspect_ratio, MENU_ENUM_SUBLABEL_MENU_RGUI_ASPECT_RATIO)
default_sublabel_macro(action_bind_sublabel_menu_ticker_type, MENU_ENUM_SUBLABEL_MENU_TICKER_TYPE)
@ -1043,24 +1044,12 @@ static int action_bind_sublabel_playlist_entry(
int n = 0;
char tmp[64];
/* Runtime label */
tmp[0] = '\0';
n = snprintf(tmp, sizeof(tmp), "\n%s %02u:%02u:%02u",
msg_hash_to_str(MENU_ENUM_LABEL_VALUE_PLAYLIST_SUBLABEL_RUNTIME),
entry->runtime_hours, entry->runtime_minutes, entry->runtime_seconds);
if ((n < 0) || (n >= 64))
n = 0; /* Silence GCC warnings... */
if (!string_is_empty(tmp))
strlcat(s, tmp, len);
/* Last played label */
tmp[0] = '\0';
n = snprintf(tmp, sizeof(tmp), "\n%s %04u/%02u/%02u - %02u:%02u:%02u",
msg_hash_to_str(MENU_ENUM_LABEL_VALUE_PLAYLIST_SUBLABEL_LAST_PLAYED),
entry->last_played_year, entry->last_played_month, entry->last_played_day,
entry->last_played_hour, entry->last_played_minute, entry->last_played_second);
/* Runtime/last played strings are now cached in the
* playlist, so we can add both in one go */
n = snprintf(tmp, sizeof(tmp), "\n%s\n%s",
entry->runtime_str, entry->last_played_str);
if ((n < 0) || (n >= 64))
n = 0; /* Silence GCC warnings... */
@ -2925,6 +2914,9 @@ int menu_cbs_init_bind_sublabel(menu_file_list_cbs_t *cbs,
case MENU_ENUM_LABEL_PLAYLIST_SUBLABEL_RUNTIME_TYPE:
BIND_ACTION_SUBLABEL(cbs, action_bind_sublabel_playlist_sublabel_runtime_type);
break;
case MENU_ENUM_LABEL_PLAYLIST_SUBLABEL_LAST_PLAYED_STYLE:
BIND_ACTION_SUBLABEL(cbs, action_bind_sublabel_playlist_sublabel_last_played_style);
break;
case MENU_ENUM_LABEL_MENU_RGUI_INTERNAL_UPSCALE_LEVEL:
BIND_ACTION_SUBLABEL(cbs, action_bind_sublabel_menu_rgui_internal_upscale_level);
break;

View File

@ -1252,9 +1252,6 @@ void ozone_update_content_metadata(ozone_handle_t *ozone)
|| string_is_equal(core_label, "musicplayer")
|| string_is_equal(core_label, "movieplayer");
word_wrap(ozone->selection_core_name, ozone->selection_core_name, (unsigned)((float)ozone->dimensions.thumbnail_bar_width * (float)0.85) / ozone->footer_font_glyph_width, false, 0);
ozone->selection_core_name_lines = ozone_count_lines(ozone->selection_core_name);
/* Fill play time if applicable */
if (settings->bools.content_runtime_log || settings->bools.content_runtime_log_aggregate)
{
@ -1265,26 +1262,10 @@ void ozone_update_content_metadata(ozone_handle_t *ozone)
if (entry->runtime_status == PLAYLIST_RUNTIME_UNKNOWN)
runtime_update_playlist(playlist, selection);
if (entry->runtime_status == PLAYLIST_RUNTIME_VALID)
{
snprintf(ozone->selection_playtime, sizeof(ozone->selection_playtime), "%s %02u:%02u:%02u",
msg_hash_to_str(MENU_ENUM_LABEL_VALUE_PLAYLIST_SUBLABEL_RUNTIME),
entry->runtime_hours, entry->runtime_minutes, entry->runtime_seconds);
snprintf(ozone->selection_lastplayed, sizeof(ozone->selection_lastplayed), "%s %04u/%02u/%02u -\n%02u:%02u:%02u",
msg_hash_to_str(MENU_ENUM_LABEL_VALUE_PLAYLIST_SUBLABEL_LAST_PLAYED),
entry->last_played_year, entry->last_played_month, entry->last_played_day,
entry->last_played_hour, entry->last_played_minute, entry->last_played_second);
}
else
{
snprintf(ozone->selection_playtime, sizeof(ozone->selection_playtime), "%s 00:00:00",
msg_hash_to_str(MENU_ENUM_LABEL_VALUE_PLAYLIST_SUBLABEL_RUNTIME));
snprintf(ozone->selection_lastplayed, sizeof(ozone->selection_lastplayed), "%s %s",
msg_hash_to_str(MENU_ENUM_LABEL_VALUE_PLAYLIST_SUBLABEL_LAST_PLAYED),
msg_hash_to_str(MENU_ENUM_LABEL_VALUE_PLAYLIST_INLINE_CORE_DISPLAY_NEVER));
}
if (!string_is_empty(entry->runtime_str))
strlcpy(ozone->selection_playtime, entry->runtime_str, sizeof(ozone->selection_playtime));
if (!string_is_empty(entry->last_played_str))
strlcpy(ozone->selection_lastplayed, entry->last_played_str, sizeof(ozone->selection_lastplayed));
}
else
{

View File

@ -238,7 +238,6 @@ struct ozone_handle
char selection_core_name[255];
char selection_playtime[255];
char selection_lastplayed[255];
unsigned selection_core_name_lines;
bool selection_core_is_viewer;
bool is_db_manager_list;

View File

@ -702,8 +702,7 @@ static void ozone_draw_no_thumbnail_available(ozone_handle_t *ozone,
}
static void ozone_content_metadata_line(video_frame_info_t *video_info, ozone_handle_t *ozone,
unsigned *y, unsigned column_x,
const char *text, unsigned lines_count)
unsigned *y, unsigned column_x, const char *text)
{
ozone_draw_text(video_info, ozone,
text,
@ -716,7 +715,7 @@ static void ozone_content_metadata_line(video_frame_info_t *video_info, ozone_ha
true
);
*y += (font_driver_get_line_height(ozone->fonts.footer, 1) * 1.5) * lines_count;
*y += font_driver_get_line_height(ozone->fonts.footer, 1) * 1.5;
}
void ozone_draw_thumbnail_bar(ozone_handle_t *ozone, video_frame_info_t *video_info)
@ -805,10 +804,43 @@ void ozone_draw_thumbnail_bar(ozone_handle_t *ozone, video_frame_info_t *video_i
}
else if (!ozone->selection_core_is_viewer)
{
unsigned y = video_info->height / 2 + ozone->dimensions.sidebar_entry_icon_padding / 2;
unsigned content_metadata_padding = ozone->dimensions.sidebar_entry_icon_padding*3;
unsigned separator_padding = ozone->dimensions.sidebar_entry_icon_padding*2;
unsigned column_x = x_position + content_metadata_padding;
char ticker_buf[255];
menu_animation_ctx_ticker_t ticker;
menu_animation_ctx_ticker_smooth_t ticker_smooth;
static const char* const ticker_spacer = OZONE_TICKER_SPACER;
unsigned ticker_x_offset = 0;
settings_t *settings = config_get_ptr();
bool use_smooth_ticker = settings->bools.menu_ticker_smooth;
unsigned y = video_info->height / 2 + ozone->dimensions.sidebar_entry_icon_padding / 2;
unsigned separator_padding = ozone->dimensions.sidebar_entry_icon_padding*2;
unsigned column_x = x_position + separator_padding;
/* Initial ticker configuration */
if (use_smooth_ticker)
{
ticker_smooth.idx = menu_animation_get_ticker_pixel_idx();
ticker_smooth.font_scale = 1.0f;
ticker_smooth.type_enum = (enum menu_animation_ticker_type)settings->uints.menu_ticker_type;
ticker_smooth.spacer = ticker_spacer;
ticker_smooth.x_offset = &ticker_x_offset;
ticker_smooth.dst_str_width = NULL;
ticker_smooth.font = ozone->fonts.footer;
ticker_smooth.selected = true;
ticker_smooth.field_width = sidebar_width - (separator_padding * 2);
ticker_smooth.dst_str = ticker_buf;
ticker_smooth.dst_str_len = sizeof(ticker_buf);
}
else
{
ticker.idx = menu_animation_get_ticker_idx();
ticker.type_enum = (enum menu_animation_ticker_type)settings->uints.menu_ticker_type;
ticker.spacer = ticker_spacer;
ticker.selected = true;
ticker.len = (sidebar_width - (separator_padding * 2)) / ozone->footer_font_glyph_width;
ticker.s = ticker_buf;
}
/* Content metadata */
y += 10;
@ -823,25 +855,58 @@ void ozone_draw_thumbnail_bar(ozone_handle_t *ozone, video_frame_info_t *video_i
y += 18;
/* Core association */
ticker_buf[0] = '\0';
if (use_smooth_ticker)
{
ticker_smooth.src_str = ozone->selection_core_name;
menu_animation_ticker_smooth(&ticker_smooth);
}
else
{
ticker.str = ozone->selection_core_name;
menu_animation_ticker(&ticker);
}
ozone_content_metadata_line(video_info, ozone,
&y, column_x,
ozone->selection_core_name,
ozone->selection_core_name_lines
);
&y, ticker_x_offset + column_x,
ticker_buf);
/* Playtime */
ticker_buf[0] = '\0';
if (use_smooth_ticker)
{
ticker_smooth.src_str = ozone->selection_playtime;
menu_animation_ticker_smooth(&ticker_smooth);
}
else
{
ticker.str = ozone->selection_playtime;
menu_animation_ticker(&ticker);
}
ozone_content_metadata_line(video_info, ozone,
&y, column_x,
ozone->selection_playtime,
1
);
&y, ticker_x_offset + column_x,
ticker_buf);
/* Last played */
ticker_buf[0] = '\0';
if (use_smooth_ticker)
{
ticker_smooth.src_str = ozone->selection_lastplayed;
menu_animation_ticker_smooth(&ticker_smooth);
}
else
{
ticker.str = ozone->selection_lastplayed;
menu_animation_ticker(&ticker);
}
ozone_content_metadata_line(video_info, ozone,
&y, column_x,
ozone->selection_lastplayed,
2
);
&y, ticker_x_offset + column_x,
ticker_buf);
}
}

View File

@ -324,6 +324,21 @@ enum playlist_sublabel_runtime
PLAYLIST_RUNTIME_LAST
};
enum playlist_sublabel_last_played_style_type
{
PLAYLIST_LAST_PLAYED_STYLE_YMD_HMS = 0,
PLAYLIST_LAST_PLAYED_STYLE_YMD_HM,
PLAYLIST_LAST_PLAYED_STYLE_MDYYYY,
PLAYLIST_LAST_PLAYED_STYLE_DM_HM,
PLAYLIST_LAST_PLAYED_STYLE_MD_HM,
PLAYLIST_LAST_PLAYED_STYLE_YMD_HMS_AM_PM,
PLAYLIST_LAST_PLAYED_STYLE_YMD_HM_AM_PM,
PLAYLIST_LAST_PLAYED_STYLE_MDYYYY_AM_PM,
PLAYLIST_LAST_PLAYED_STYLE_DM_HM_AM_PM,
PLAYLIST_LAST_PLAYED_STYLE_MD_HM_AM_PM,
PLAYLIST_LAST_PLAYED_STYLE_LAST
};
enum playlist_inline_core_display_type
{
PLAYLIST_INLINE_CORE_DISPLAY_HIST_FAV = 0,

View File

@ -3110,60 +3110,28 @@ static unsigned menu_displaylist_parse_content_information(
{
if (runtime_log_has_runtime(runtime_log))
{
unsigned runtime_hours;
unsigned runtime_minutes;
unsigned runtime_seconds;
unsigned last_played_year;
unsigned last_played_month;
unsigned last_played_day;
unsigned last_played_hour;
unsigned last_played_minute;
unsigned last_played_second;
/* Play time */
runtime_log_get_runtime_hms(runtime_log,
&runtime_hours, &runtime_minutes, &runtime_seconds);
tmp[0] = '\0';
runtime_log_get_runtime_str(runtime_log, tmp, sizeof(tmp));
n = snprintf(tmp, sizeof(tmp),
"%s: %02u:%02u:%02u", msg_hash_to_str(MENU_ENUM_LABEL_VALUE_CONTENT_INFO_RUNTIME),
runtime_hours, runtime_minutes, runtime_seconds);
/* Silence gcc compiler warning
* (getting so sick of these...) */
if ((n < 0) || (n >= PATH_MAX_LENGTH))
n = 0;
if (menu_entries_append_enum(info->list, tmp,
msg_hash_to_str(MENU_ENUM_LABEL_CONTENT_INFO_RUNTIME),
MENU_ENUM_LABEL_CONTENT_INFO_RUNTIME,
0, 0, 0))
count++;
if (!string_is_empty(tmp))
if (menu_entries_append_enum(info->list, tmp,
msg_hash_to_str(MENU_ENUM_LABEL_CONTENT_INFO_RUNTIME),
MENU_ENUM_LABEL_CONTENT_INFO_RUNTIME,
0, 0, 0))
count++;
/* Last Played */
runtime_log_get_last_played(runtime_log,
&last_played_year, &last_played_month, &last_played_day,
&last_played_hour, &last_played_minute, &last_played_second);
tmp[0] = '\0';
runtime_log_get_last_played_str(runtime_log, tmp, sizeof(tmp),
settings->uints.playlist_sublabel_last_played_style);
n = snprintf(tmp, sizeof(tmp),
"%s: %04u/%02u/%02u - %02u:%02u:%02u",
msg_hash_to_str(MENU_ENUM_LABEL_VALUE_CONTENT_INFO_LAST_PLAYED),
last_played_year, last_played_month, last_played_day,
last_played_hour, last_played_minute, last_played_second);
/* Silence gcc compiler warning
* (getting so sick of these...) */
if ((n < 0) || (n >= PATH_MAX_LENGTH))
n = 0;
if (menu_entries_append_enum(info->list, tmp,
msg_hash_to_str(MENU_ENUM_LABEL_CONTENT_INFO_LAST_PLAYED),
MENU_ENUM_LABEL_CONTENT_INFO_LAST_PLAYED,
0, 0, 0))
count++;
if (!string_is_empty(tmp))
if (menu_entries_append_enum(info->list, tmp,
msg_hash_to_str(MENU_ENUM_LABEL_CONTENT_INFO_LAST_PLAYED),
MENU_ENUM_LABEL_CONTENT_INFO_LAST_PLAYED,
0, 0, 0))
count++;
}
free(runtime_log);
@ -7091,21 +7059,22 @@ bool menu_displaylist_ctl(enum menu_displaylist_ctl_state type,
{
menu_displaylist_build_info_t build_list[] = {
{MENU_ENUM_LABEL_HISTORY_LIST_ENABLE, PARSE_ONLY_BOOL},
{MENU_ENUM_LABEL_CONTENT_HISTORY_SIZE, PARSE_ONLY_UINT},
{MENU_ENUM_LABEL_CONTENT_FAVORITES_SIZE, PARSE_ONLY_INT },
{MENU_ENUM_LABEL_PLAYLIST_ENTRY_RENAME, PARSE_ONLY_BOOL},
{MENU_ENUM_LABEL_PLAYLIST_ENTRY_REMOVE, PARSE_ONLY_UINT},
{MENU_ENUM_LABEL_PLAYLIST_SORT_ALPHABETICAL, PARSE_ONLY_BOOL},
{MENU_ENUM_LABEL_PLAYLIST_USE_OLD_FORMAT, PARSE_ONLY_BOOL},
{MENU_ENUM_LABEL_PLAYLIST_SHOW_INLINE_CORE_NAME, PARSE_ONLY_UINT},
{MENU_ENUM_LABEL_PLAYLIST_SHOW_SUBLABELS, PARSE_ONLY_BOOL},
{MENU_ENUM_LABEL_PLAYLIST_SUBLABEL_RUNTIME_TYPE, PARSE_ONLY_UINT},
{MENU_ENUM_LABEL_PLAYLIST_FUZZY_ARCHIVE_MATCH, PARSE_ONLY_BOOL},
{MENU_ENUM_LABEL_SCAN_WITHOUT_CORE_MATCH, PARSE_ONLY_BOOL},
{MENU_ENUM_LABEL_OZONE_TRUNCATE_PLAYLIST_NAME, PARSE_ONLY_BOOL},
{MENU_ENUM_LABEL_CONTENT_RUNTIME_LOG, PARSE_ONLY_BOOL},
{MENU_ENUM_LABEL_CONTENT_RUNTIME_LOG_AGGREGATE, PARSE_ONLY_BOOL},
{MENU_ENUM_LABEL_HISTORY_LIST_ENABLE, PARSE_ONLY_BOOL},
{MENU_ENUM_LABEL_CONTENT_HISTORY_SIZE, PARSE_ONLY_UINT},
{MENU_ENUM_LABEL_CONTENT_FAVORITES_SIZE, PARSE_ONLY_INT },
{MENU_ENUM_LABEL_PLAYLIST_ENTRY_RENAME, PARSE_ONLY_BOOL},
{MENU_ENUM_LABEL_PLAYLIST_ENTRY_REMOVE, PARSE_ONLY_UINT},
{MENU_ENUM_LABEL_PLAYLIST_SORT_ALPHABETICAL, PARSE_ONLY_BOOL},
{MENU_ENUM_LABEL_PLAYLIST_USE_OLD_FORMAT, PARSE_ONLY_BOOL},
{MENU_ENUM_LABEL_PLAYLIST_SHOW_INLINE_CORE_NAME, PARSE_ONLY_UINT},
{MENU_ENUM_LABEL_PLAYLIST_SHOW_SUBLABELS, PARSE_ONLY_BOOL},
{MENU_ENUM_LABEL_PLAYLIST_SUBLABEL_RUNTIME_TYPE, PARSE_ONLY_UINT},
{MENU_ENUM_LABEL_PLAYLIST_SUBLABEL_LAST_PLAYED_STYLE, PARSE_ONLY_UINT},
{MENU_ENUM_LABEL_PLAYLIST_FUZZY_ARCHIVE_MATCH, PARSE_ONLY_BOOL},
{MENU_ENUM_LABEL_SCAN_WITHOUT_CORE_MATCH, PARSE_ONLY_BOOL},
{MENU_ENUM_LABEL_OZONE_TRUNCATE_PLAYLIST_NAME, PARSE_ONLY_BOOL},
{MENU_ENUM_LABEL_CONTENT_RUNTIME_LOG, PARSE_ONLY_BOOL},
{MENU_ENUM_LABEL_CONTENT_RUNTIME_LOG_AGGREGATE, PARSE_ONLY_BOOL},
};
for (i = 0; i < ARRAY_SIZE(build_list); i++)

View File

@ -4102,6 +4102,78 @@ static void setting_get_string_representation_uint_playlist_sublabel_runtime_typ
}
}
static void setting_get_string_representation_uint_playlist_sublabel_last_played_style(
rarch_setting_t *setting,
char *s, size_t len)
{
if (!setting)
return;
switch (*setting->value.target.unsigned_integer)
{
case PLAYLIST_LAST_PLAYED_STYLE_YMD_HMS:
strlcpy(s,
msg_hash_to_str(
MENU_ENUM_LABEL_VALUE_PLAYLIST_SUBLABEL_LAST_PLAYED_STYLE_YMD_HMS),
len);
break;
case PLAYLIST_LAST_PLAYED_STYLE_YMD_HM:
strlcpy(s,
msg_hash_to_str(
MENU_ENUM_LABEL_VALUE_PLAYLIST_SUBLABEL_LAST_PLAYED_STYLE_YMD_HM),
len);
break;
case PLAYLIST_LAST_PLAYED_STYLE_MDYYYY:
strlcpy(s,
msg_hash_to_str(
MENU_ENUM_LABEL_VALUE_PLAYLIST_SUBLABEL_LAST_PLAYED_STYLE_MDYYYY),
len);
break;
case PLAYLIST_LAST_PLAYED_STYLE_DM_HM:
strlcpy(s,
msg_hash_to_str(
MENU_ENUM_LABEL_VALUE_PLAYLIST_SUBLABEL_LAST_PLAYED_STYLE_DM_HM),
len);
break;
case PLAYLIST_LAST_PLAYED_STYLE_MD_HM:
strlcpy(s,
msg_hash_to_str(
MENU_ENUM_LABEL_VALUE_PLAYLIST_SUBLABEL_LAST_PLAYED_STYLE_MD_HM),
len);
break;
case PLAYLIST_LAST_PLAYED_STYLE_YMD_HMS_AM_PM:
strlcpy(s,
msg_hash_to_str(
MENU_ENUM_LABEL_VALUE_PLAYLIST_SUBLABEL_LAST_PLAYED_STYLE_YMD_HMS_AM_PM),
len);
break;
case PLAYLIST_LAST_PLAYED_STYLE_YMD_HM_AM_PM:
strlcpy(s,
msg_hash_to_str(
MENU_ENUM_LABEL_VALUE_PLAYLIST_SUBLABEL_LAST_PLAYED_STYLE_YMD_HM_AM_PM),
len);
break;
case PLAYLIST_LAST_PLAYED_STYLE_MDYYYY_AM_PM:
strlcpy(s,
msg_hash_to_str(
MENU_ENUM_LABEL_VALUE_PLAYLIST_SUBLABEL_LAST_PLAYED_STYLE_MDYYYY_AM_PM),
len);
break;
case PLAYLIST_LAST_PLAYED_STYLE_DM_HM_AM_PM:
strlcpy(s,
msg_hash_to_str(
MENU_ENUM_LABEL_VALUE_PLAYLIST_SUBLABEL_LAST_PLAYED_STYLE_DM_HM_AM_PM),
len);
break;
case PLAYLIST_LAST_PLAYED_STYLE_MD_HM_AM_PM:
strlcpy(s,
msg_hash_to_str(
MENU_ENUM_LABEL_VALUE_PLAYLIST_SUBLABEL_LAST_PLAYED_STYLE_MD_HM_AM_PM),
len);
break;
}
}
static void setting_get_string_representation_uint_playlist_inline_core_display_type(
rarch_setting_t *setting,
char *s, size_t len)
@ -14279,6 +14351,22 @@ static bool setting_append_list(
&setting_get_string_representation_uint_playlist_sublabel_runtime_type;
menu_settings_list_current_add_range(list, list_info, 0, PLAYLIST_RUNTIME_LAST-1, 1, true, true);
CONFIG_UINT(
list, list_info,
&settings->uints.playlist_sublabel_last_played_style,
MENU_ENUM_LABEL_PLAYLIST_SUBLABEL_LAST_PLAYED_STYLE,
MENU_ENUM_LABEL_VALUE_PLAYLIST_SUBLABEL_LAST_PLAYED_STYLE,
DEFAULT_PLAYLIST_SUBLABEL_LAST_PLAYED_STYLE,
&group_info,
&subgroup_info,
parent_group,
general_write_handler,
general_read_handler);
(*list)[list_info->index - 1].action_ok = &setting_action_ok_uint;
(*list)[list_info->index - 1].get_string_representation =
&setting_get_string_representation_uint_playlist_sublabel_last_played_style;
menu_settings_list_current_add_range(list, list_info, 0, PLAYLIST_LAST_PLAYED_STYLE_LAST-1, 1, true, true);
CONFIG_UINT(
list, list_info,
&settings->uints.playlist_show_inline_core_name,

View File

@ -2540,6 +2540,7 @@ enum msg_hash_enums
MENU_LABEL(PLAYLIST_SHOW_SUBLABELS),
MENU_LABEL(PLAYLIST_FUZZY_ARCHIVE_MATCH),
MENU_LABEL(PLAYLIST_SUBLABEL_RUNTIME_TYPE),
MENU_LABEL(PLAYLIST_SUBLABEL_LAST_PLAYED_STYLE),
MENU_ENUM_LABEL_VALUE_PLAYLIST_INLINE_CORE_DISPLAY_HIST_FAV,
MENU_ENUM_LABEL_VALUE_PLAYLIST_INLINE_CORE_DISPLAY_ALWAYS,
@ -2556,6 +2557,17 @@ enum msg_hash_enums
MENU_ENUM_LABEL_VALUE_PLAYLIST_RUNTIME_PER_CORE,
MENU_ENUM_LABEL_VALUE_PLAYLIST_RUNTIME_AGGREGATE,
MENU_ENUM_LABEL_VALUE_PLAYLIST_SUBLABEL_LAST_PLAYED_STYLE_YMD_HMS,
MENU_ENUM_LABEL_VALUE_PLAYLIST_SUBLABEL_LAST_PLAYED_STYLE_YMD_HM,
MENU_ENUM_LABEL_VALUE_PLAYLIST_SUBLABEL_LAST_PLAYED_STYLE_MDYYYY,
MENU_ENUM_LABEL_VALUE_PLAYLIST_SUBLABEL_LAST_PLAYED_STYLE_DM_HM,
MENU_ENUM_LABEL_VALUE_PLAYLIST_SUBLABEL_LAST_PLAYED_STYLE_MD_HM,
MENU_ENUM_LABEL_VALUE_PLAYLIST_SUBLABEL_LAST_PLAYED_STYLE_YMD_HMS_AM_PM,
MENU_ENUM_LABEL_VALUE_PLAYLIST_SUBLABEL_LAST_PLAYED_STYLE_YMD_HM_AM_PM,
MENU_ENUM_LABEL_VALUE_PLAYLIST_SUBLABEL_LAST_PLAYED_STYLE_MDYYYY_AM_PM,
MENU_ENUM_LABEL_VALUE_PLAYLIST_SUBLABEL_LAST_PLAYED_STYLE_DM_HM_AM_PM,
MENU_ENUM_LABEL_VALUE_PLAYLIST_SUBLABEL_LAST_PLAYED_STYLE_MD_HM_AM_PM,
MENU_LABEL(HELP_SEND_DEBUG_INFO),
MENU_ENUM_LABEL_VALUE_HELP_SEND_DEBUG_INFO_DESC,

View File

@ -278,6 +278,10 @@ static void playlist_free_entry(struct playlist_entry *entry)
free(entry->subsystem_ident);
if (entry->subsystem_name != NULL)
free(entry->subsystem_name);
if (entry->runtime_str != NULL)
free(entry->runtime_str);
if (entry->last_played_str != NULL)
free(entry->last_played_str);
if (entry->subsystem_roms != NULL)
string_list_free(entry->subsystem_roms);
@ -289,6 +293,8 @@ static void playlist_free_entry(struct playlist_entry *entry)
entry->crc32 = NULL;
entry->subsystem_ident = NULL;
entry->subsystem_name = NULL;
entry->runtime_str = NULL;
entry->last_played_str = NULL;
entry->subsystem_roms = NULL;
entry->runtime_status = PLAYLIST_RUNTIME_UNKNOWN;
entry->runtime_hours = 0;
@ -532,6 +538,24 @@ void playlist_update_runtime(playlist_t *playlist, size_t idx,
entry->last_played_second = update_entry->last_played_second;
playlist->modified = playlist->modified || register_update;
}
if (update_entry->runtime_str && (update_entry->runtime_str != entry->runtime_str))
{
if (entry->runtime_str != NULL)
free(entry->runtime_str);
entry->runtime_str = NULL;
entry->runtime_str = strdup(update_entry->runtime_str);
playlist->modified = playlist->modified || register_update;
}
if (update_entry->last_played_str && (update_entry->last_played_str != entry->last_played_str))
{
if (entry->last_played_str != NULL)
free(entry->last_played_str);
entry->last_played_str = NULL;
entry->last_played_str = strdup(update_entry->last_played_str);
playlist->modified = playlist->modified || register_update;
}
}
bool playlist_push_runtime(playlist_t *playlist,
@ -633,6 +657,14 @@ bool playlist_push_runtime(playlist_t *playlist,
playlist->entries[0].last_played_hour = entry->last_played_hour;
playlist->entries[0].last_played_minute = entry->last_played_minute;
playlist->entries[0].last_played_second = entry->last_played_second;
playlist->entries[0].runtime_str = NULL;
playlist->entries[0].last_played_str = NULL;
if (!string_is_empty(entry->runtime_str))
playlist->entries[0].runtime_str = strdup(entry->runtime_str);
if (!string_is_empty(entry->last_played_str))
playlist->entries[0].last_played_str = strdup(entry->last_played_str);
}
playlist->size++;
@ -881,6 +913,8 @@ bool playlist_push(playlist_t *playlist,
playlist->entries[0].crc32 = NULL;
playlist->entries[0].subsystem_ident = NULL;
playlist->entries[0].subsystem_name = NULL;
playlist->entries[0].runtime_str = NULL;
playlist->entries[0].last_played_str = NULL;
playlist->entries[0].subsystem_roms = NULL;
playlist->entries[0].runtime_status = PLAYLIST_RUNTIME_UNKNOWN;
playlist->entries[0].runtime_hours = 0;

View File

@ -83,6 +83,8 @@ struct playlist_entry
char *crc32;
char *subsystem_ident;
char *subsystem_name;
char *runtime_str;
char *last_played_str;
struct string_list *subsystem_roms;
enum playlist_runtime_status runtime_status;
unsigned runtime_hours;

View File

@ -24,6 +24,7 @@
#include <string.h>
#include <stdio.h>
#include <ctype.h>
#include <locale.h>
#include <file/file_path.h>
#include <retro_miscellaneous.h>
@ -36,9 +37,9 @@
#include "core_info.h"
#include "configuration.h"
#include "verbosity.h"
#include "msg_hash.h"
#include "runtime_file.h"
#include "menu/menu_defines.h"
#define LOG_FILE_RUNTIME_FORMAT_STR "%u:%02u:%02u"
#define LOG_FILE_LAST_PLAYED_FORMAT_STR "%04u-%02u-%02u %02u:%02u:%02u"
@ -530,7 +531,7 @@ void runtime_log_set_last_played(runtime_log_t *runtime_log,
void runtime_log_set_last_played_now(runtime_log_t *runtime_log)
{
time_t current_time;
struct tm * time_info;
struct tm *time_info;
if (!runtime_log)
return;
@ -598,6 +599,27 @@ void runtime_log_get_runtime_usec(
usec);
}
/* Gets runtime as a pre-formatted string */
void runtime_log_get_runtime_str(runtime_log_t *runtime_log, char *str, size_t len)
{
int n = 0;
if (runtime_log)
{
n = snprintf(str, len, "%s %02u:%02u:%02u",
msg_hash_to_str(MENU_ENUM_LABEL_VALUE_PLAYLIST_SUBLABEL_RUNTIME),
runtime_log->runtime.hours, runtime_log->runtime.minutes, runtime_log->runtime.seconds);
}
else
{
n = snprintf(str, len, "%s 00:00:00",
msg_hash_to_str(MENU_ENUM_LABEL_VALUE_PLAYLIST_SUBLABEL_RUNTIME));
}
if ((n < 0) || (n >= 64))
n = 0; /* Silence GCC warnings... */
}
/* Gets last played entry values */
void runtime_log_get_last_played(runtime_log_t *runtime_log,
unsigned *year, unsigned *month, unsigned *day,
@ -614,26 +636,152 @@ void runtime_log_get_last_played(runtime_log_t *runtime_log,
*second = runtime_log->last_played.second;
}
/* Gets last played entry values as a time_t 'object'
/* Gets last played entry values as a struct tm 'object'
* (e.g. for printing with strftime()) */
void runtime_log_get_last_played_time(runtime_log_t *runtime_log, time_t *time)
void runtime_log_get_last_played_time(runtime_log_t *runtime_log, struct tm *time_info)
{
struct tm time_info;
if (!runtime_log || !time)
if (!runtime_log || !time_info)
return;
/* Set tm values */
time_info.tm_year = (int)runtime_log->last_played.year - 1900;
time_info.tm_mon = (int)runtime_log->last_played.month - 1;
time_info.tm_mday = (int)runtime_log->last_played.day;
time_info.tm_hour = (int)runtime_log->last_played.hour;
time_info.tm_min = (int)runtime_log->last_played.minute;
time_info.tm_sec = (int)runtime_log->last_played.second;
time_info.tm_isdst = -1;
time_info->tm_year = (int)runtime_log->last_played.year - 1900;
time_info->tm_mon = (int)runtime_log->last_played.month - 1;
time_info->tm_mday = (int)runtime_log->last_played.day;
time_info->tm_hour = (int)runtime_log->last_played.hour;
time_info->tm_min = (int)runtime_log->last_played.minute;
time_info->tm_sec = (int)runtime_log->last_played.second;
time_info->tm_isdst = -1;
/* Perform any required range adjustment + populate
* missing entries */
mktime(time_info);
}
static void last_played_strftime(runtime_log_t *runtime_log, char *str, size_t len, const char *format)
{
struct tm time_info;
char *local = NULL;
if (!runtime_log)
return;
/* Get time */
*time = mktime(&time_info);
runtime_log_get_last_played_time(runtime_log, &time_info);
/* Ensure correct locale is set */
setlocale(LC_TIME, "");
/* Generate string */
#if defined(__linux__) && !defined(ANDROID)
strftime(str, len, format, &time_info);
#else
strftime(str, len, format, &time_info);
local = local_to_utf8_string_alloc(str);
if (!string_is_empty(local))
strlcpy(str, local, len);
if (local)
{
free(local);
local = NULL;
}
#endif
}
/* Gets last played entry value as a pre-formatted string */
void runtime_log_get_last_played_str(runtime_log_t *runtime_log,
char *str, size_t len, enum playlist_sublabel_last_played_style_type timedate_style)
{
settings_t *settings = config_get_ptr();
int n = 0;
char tmp[64];
tmp[0] = '\0';
if (!settings)
return;
if (runtime_log)
{
/* Handle 12-hour clock options
* > These require extra work, due to AM/PM localisation */
switch (timedate_style)
{
case PLAYLIST_LAST_PLAYED_STYLE_YMD_HMS_AM_PM:
last_played_strftime(runtime_log, tmp, sizeof(tmp), " %Y/%m/%d - %I:%M:%S %p");
strlcpy(str, msg_hash_to_str(MENU_ENUM_LABEL_VALUE_PLAYLIST_SUBLABEL_LAST_PLAYED), len);
strlcat(str, tmp, len);
return;
case PLAYLIST_LAST_PLAYED_STYLE_YMD_HM_AM_PM:
last_played_strftime(runtime_log, tmp, sizeof(tmp), " %Y/%m/%d - %I:%M %p");
strlcpy(str, msg_hash_to_str(MENU_ENUM_LABEL_VALUE_PLAYLIST_SUBLABEL_LAST_PLAYED), len);
strlcat(str, tmp, len);
return;
case PLAYLIST_LAST_PLAYED_STYLE_MDYYYY_AM_PM:
last_played_strftime(runtime_log, tmp, sizeof(tmp), " %m/%d/%Y - %I:%M %p");
strlcpy(str, msg_hash_to_str(MENU_ENUM_LABEL_VALUE_PLAYLIST_SUBLABEL_LAST_PLAYED), len);
strlcat(str, tmp, len);
return;
case PLAYLIST_LAST_PLAYED_STYLE_DM_HM_AM_PM:
last_played_strftime(runtime_log, tmp, sizeof(tmp), " %d/%m - %I:%M %p");
strlcpy(str, msg_hash_to_str(MENU_ENUM_LABEL_VALUE_PLAYLIST_SUBLABEL_LAST_PLAYED), len);
strlcat(str, tmp, len);
return;
case PLAYLIST_LAST_PLAYED_STYLE_MD_HM_AM_PM:
last_played_strftime(runtime_log, tmp, sizeof(tmp), " %m/%d - %I:%M %p");
strlcpy(str, msg_hash_to_str(MENU_ENUM_LABEL_VALUE_PLAYLIST_SUBLABEL_LAST_PLAYED), len);
strlcat(str, tmp, len);
return;
default:
break;
}
/* Handle non-12-hour clock options */
switch (timedate_style)
{
case PLAYLIST_LAST_PLAYED_STYLE_YMD_HM:
n = snprintf(str, len, "%s %04u/%02u/%02u - %02u:%02u",
msg_hash_to_str(MENU_ENUM_LABEL_VALUE_PLAYLIST_SUBLABEL_LAST_PLAYED),
runtime_log->last_played.year, runtime_log->last_played.month, runtime_log->last_played.day,
runtime_log->last_played.hour, runtime_log->last_played.minute);
return;
case PLAYLIST_LAST_PLAYED_STYLE_MDYYYY:
n = snprintf(str, len, "%s %02u/%02u/%04u - %02u:%02u",
msg_hash_to_str(MENU_ENUM_LABEL_VALUE_PLAYLIST_SUBLABEL_LAST_PLAYED),
runtime_log->last_played.month, runtime_log->last_played.day, runtime_log->last_played.year,
runtime_log->last_played.hour, runtime_log->last_played.minute);
return;
case PLAYLIST_LAST_PLAYED_STYLE_DM_HM:
n = snprintf(str, len, "%s %02u/%02u - %02u:%02u",
msg_hash_to_str(MENU_ENUM_LABEL_VALUE_PLAYLIST_SUBLABEL_LAST_PLAYED),
runtime_log->last_played.day, runtime_log->last_played.month,
runtime_log->last_played.hour, runtime_log->last_played.minute);
return;
case PLAYLIST_LAST_PLAYED_STYLE_MD_HM:
n = snprintf(str, len, "%s %02u/%02u - %02u:%02u",
msg_hash_to_str(MENU_ENUM_LABEL_VALUE_PLAYLIST_SUBLABEL_LAST_PLAYED),
runtime_log->last_played.month, runtime_log->last_played.day,
runtime_log->last_played.hour, runtime_log->last_played.minute);
return;
case PLAYLIST_LAST_PLAYED_STYLE_YMD_HMS:
default:
n = snprintf(str, len, "%s %04u/%02u/%02u - %02u:%02u:%02u",
msg_hash_to_str(MENU_ENUM_LABEL_VALUE_PLAYLIST_SUBLABEL_LAST_PLAYED),
runtime_log->last_played.year, runtime_log->last_played.month, runtime_log->last_played.day,
runtime_log->last_played.hour, runtime_log->last_played.minute, runtime_log->last_played.second);
return;
}
}
else
{
n = snprintf(str, len, "%s %s",
msg_hash_to_str(MENU_ENUM_LABEL_VALUE_PLAYLIST_SUBLABEL_LAST_PLAYED),
msg_hash_to_str(MENU_ENUM_LABEL_VALUE_PLAYLIST_INLINE_CORE_DISPLAY_NEVER));
}
if ((n < 0) || (n >= 64))
n = 0; /* Silence GCC warnings... */
}
/* Status */
@ -793,7 +941,6 @@ void runtime_log_convert_usec2hms(retro_time_t usec,
*minutes -= *hours * 60;
}
/* Playlist manipulation */
/* Updates specified playlist entry runtime values with
@ -804,6 +951,9 @@ void runtime_update_playlist(playlist_t *playlist, size_t idx)
runtime_log_t *runtime_log = NULL;
const struct playlist_entry *entry = NULL;
struct playlist_entry update_entry = {0};
enum playlist_sublabel_last_played_style_type timedate_style;
char runtime_str[64];
char last_played_str[64];
/* Sanity check */
if (!playlist || !settings)
@ -816,6 +966,20 @@ void runtime_update_playlist(playlist_t *playlist, size_t idx)
* (saves 'if' checks later...) */
update_entry.runtime_status = PLAYLIST_RUNTIME_MISSING;
/* Get current last played formatting type
* > Have to include a 'HAVE_MENU' check here... */
#ifdef HAVE_MENU
timedate_style = settings->uints.playlist_sublabel_last_played_style;
#else
timedate_style = PLAYLIST_LAST_PLAYED_STYLE_YMD_HMS
#endif
/* 'Attach' runtime/last played strings */
runtime_str[0] = '\0';
last_played_str[0] = '\0';
update_entry.runtime_str = runtime_str;
update_entry.last_played_str = last_played_str;
/* Read current playlist entry */
playlist_get_index(playlist, idx, &entry);
@ -831,20 +995,35 @@ void runtime_update_playlist(playlist_t *playlist, size_t idx)
/* Read current runtime */
runtime_log_get_runtime_hms(runtime_log,
&update_entry.runtime_hours, &update_entry.runtime_minutes, &update_entry.runtime_seconds);
runtime_log_get_runtime_str(runtime_log, runtime_str, sizeof(runtime_str));
/* Read last played timestamp */
runtime_log_get_last_played(runtime_log,
&update_entry.last_played_year, &update_entry.last_played_month, &update_entry.last_played_day,
&update_entry.last_played_hour, &update_entry.last_played_minute, &update_entry.last_played_second);
runtime_log_get_last_played_str(runtime_log, last_played_str, sizeof(last_played_str), timedate_style);
/* Playlist entry now contains valid runtime data */
update_entry.runtime_status = PLAYLIST_RUNTIME_VALID;
}
/* Clean up */
free(runtime_log);
}
/* Ozone requires runtime/last played strings to be
* populated even when no runtime is recorded */
if (string_is_equal(settings->arrays.menu_driver, "ozone"))
{
if (update_entry.runtime_status != PLAYLIST_RUNTIME_VALID)
{
runtime_log_get_runtime_str(NULL, runtime_str, sizeof(runtime_str));
runtime_log_get_last_played_str(NULL, last_played_str, sizeof(last_played_str), timedate_style);
}
}
/* Update playlist */
playlist_update_runtime(playlist, idx, &update_entry, false);
}

View File

@ -30,6 +30,7 @@
#include <boolean.h>
#include "playlist.h"
#include "menu/menu_defines.h"
RETRO_BEGIN_DECLS
@ -100,14 +101,21 @@ void runtime_log_get_runtime_hms(runtime_log_t *runtime_log, unsigned *hours, un
/* Gets runtime in microseconds */
void runtime_log_get_runtime_usec(runtime_log_t *runtime_log, retro_time_t *usec);
/* Gets runtime as a pre-formatted string */
void runtime_log_get_runtime_str(runtime_log_t *runtime_log, char *str, size_t len);
/* Gets last played entry values */
void runtime_log_get_last_played(runtime_log_t *runtime_log,
unsigned *year, unsigned *month, unsigned *day,
unsigned *hour, unsigned *minute, unsigned *second);
/* Gets last played entry values as a time_t 'object'
/* Gets last played entry values as a struct tm 'object'
* (e.g. for printing with strftime()) */
void runtime_log_get_last_played_time(runtime_log_t *runtime_log, time_t *time);
void runtime_log_get_last_played_time(runtime_log_t *runtime_log, struct tm *time_info);
/* Gets last played entry value as a pre-formatted string */
void runtime_log_get_last_played_str(runtime_log_t *runtime_log,
char *str, size_t len, enum playlist_sublabel_last_played_style_type timedate_style);
/* Status */