diff --git a/intl/msg_hash_us.h b/intl/msg_hash_us.h index a74f723841..a0644663cf 100644 --- a/intl/msg_hash_us.h +++ b/intl/msg_hash_us.h @@ -7911,6 +7911,10 @@ MSG_HASH( MENU_ENUM_LABEL_VALUE_PLAYLIST_SUBLABEL_LAST_PLAYED, "Last Played:" ) +MSG_HASH( + MENU_ENUM_LABEL_VALUE_PLAYLIST_SUBLABEL_PLAY_COUNT, + "Play Count:" + ) MSG_HASH( MENU_ENUM_LABEL_VALUE_TIME_UNIT_SECONDS_SINGLE, "second" diff --git a/menu/menu_displaylist.c b/menu/menu_displaylist.c index e6ab4f76aa..6a166ef204 100644 --- a/menu/menu_displaylist.c +++ b/menu/menu_displaylist.c @@ -5341,7 +5341,7 @@ static unsigned menu_displaylist_parse_content_information( { if (runtime_log_has_runtime(runtime_log)) { - /* Play time */ + /* Runtime */ tmp[0] = '\0'; runtime_log_get_runtime_str(runtime_log, tmp, sizeof(tmp)); @@ -5364,6 +5364,19 @@ static unsigned menu_displaylist_parse_content_information( MENU_ENUM_LABEL_CONTENT_INFO_LAST_PLAYED, 0, 0, 0, NULL)) count++; + + /* Play Count */ + tmp[0] = '\0'; + snprintf(tmp, sizeof(tmp), "%s %u", + msg_hash_to_str(MENU_ENUM_LABEL_VALUE_PLAYLIST_SUBLABEL_PLAY_COUNT), + runtime_log->play_count); + + if (!string_is_empty(tmp)) + if (menu_entries_append(info_list, tmp, + msg_hash_to_str(MENU_ENUM_LABEL_CONTENT_INFO_PLAY_COUNT), + MENU_ENUM_LABEL_CONTENT_INFO_PLAY_COUNT, + 0, 0, 0, NULL)) + count++; } free(runtime_log); } diff --git a/msg_hash.h b/msg_hash.h index 8bbd6fcf1f..dca5460f0e 100644 --- a/msg_hash.h +++ b/msg_hash.h @@ -2910,6 +2910,7 @@ enum msg_hash_enums MENU_LABEL(CONTENT_INFO_DATABASE), MENU_LABEL(CONTENT_INFO_RUNTIME), MENU_LABEL(CONTENT_INFO_LAST_PLAYED), + MENU_LABEL(CONTENT_INFO_PLAY_COUNT), MENU_LABEL(CONTENT_INFO_CHEEVOS_HASH), MENU_LABEL(NO_PLAYLIST_ENTRIES_AVAILABLE), @@ -4211,6 +4212,7 @@ enum msg_hash_enums MENU_ENUM_LABEL_VALUE_PLAYLIST_SUBLABEL_CORE, MENU_ENUM_LABEL_VALUE_PLAYLIST_SUBLABEL_RUNTIME, MENU_ENUM_LABEL_VALUE_PLAYLIST_SUBLABEL_LAST_PLAYED, + MENU_ENUM_LABEL_VALUE_PLAYLIST_SUBLABEL_PLAY_COUNT, MENU_ENUM_LABEL_VALUE_PLAYLIST_RUNTIME_PER_CORE, MENU_ENUM_LABEL_VALUE_PLAYLIST_RUNTIME_AGGREGATE, diff --git a/runloop.c b/runloop.c index 3dfb1074b3..f90944dc73 100644 --- a/runloop.c +++ b/runloop.c @@ -655,6 +655,9 @@ static void runloop_update_runtime_log( /* Update 'last played' entry */ runtime_log_set_last_played_now(runtime_log); + /* Update play count */ + runtime_log->play_count++; + /* Update state slot */ runtime_log->state_slot = config_get_ptr()->ints.state_slot; diff --git a/runtime_file.c b/runtime_file.c index a65698a474..425f56e3fb 100644 --- a/runtime_file.c +++ b/runtime_file.c @@ -55,6 +55,7 @@ typedef struct char **current_entry_val; char *runtime_string; char *last_played_string; + char *play_count; char *state_slot; } RtlJSONContext; @@ -72,6 +73,8 @@ static bool RtlJSONObjectMemberHandler(void *ctx, const char *s, size_t len) p_ctx->current_entry_val = &p_ctx->runtime_string; else if (string_is_equal(s, "last_played")) p_ctx->current_entry_val = &p_ctx->last_played_string; + else if (string_is_equal(s, "play_count")) + p_ctx->current_entry_val = &p_ctx->play_count; else if (string_is_equal(s, "state_slot")) p_ctx->current_entry_val = &p_ctx->state_slot; /* Ignore unknown members */ @@ -116,6 +119,8 @@ static void runtime_log_read_file(runtime_log_t *runtime_log) unsigned last_played_minute = 0; unsigned last_played_second = 0; + unsigned play_count = 0; + unsigned state_slot = 0; RtlJSONContext context = {0}; @@ -198,6 +203,18 @@ static void runtime_log_read_file(runtime_log_t *runtime_log) } } + /* Play count */ + if (!string_is_empty(context.play_count)) + { + if (sscanf(context.play_count, + "%u", + &play_count) != 1) + { + RARCH_ERR("[Runtime] Invalid \"play count\" entry detected: \"%s\".\n", runtime_log->path); + goto end; + } + } + /* State slot */ if (!string_is_empty(context.state_slot)) { @@ -229,6 +246,8 @@ static void runtime_log_read_file(runtime_log_t *runtime_log) runtime_log->last_played.minute = last_played_minute; runtime_log->last_played.second = last_played_second; + runtime_log->play_count = play_count; + runtime_log->state_slot = state_slot; end: @@ -237,6 +256,8 @@ end: free(context.runtime_string); if (context.last_played_string) free(context.last_played_string); + if (context.play_count) + free(context.play_count); if (context.state_slot) free(context.state_slot); @@ -402,6 +423,8 @@ runtime_log_t *runtime_log_init( runtime_log->last_played.minute = 0; runtime_log->last_played.second = 0; + runtime_log->play_count = 0; + runtime_log->state_slot = 0; runtime_log->path[0] = '\0'; @@ -504,6 +527,8 @@ void runtime_log_reset(runtime_log_t *runtime_log) runtime_log->last_played.minute = 0; runtime_log->last_played.second = 0; + runtime_log->play_count = 0; + runtime_log->state_slot = 0; } @@ -1152,6 +1177,20 @@ void runtime_log_save(runtime_log_t *runtime_log) rjsonwriter_raw(writer, ",", 1); rjsonwriter_raw(writer, "\n", 1); + /* > Play count */ + value_string[0] = '\0'; + snprintf(value_string, sizeof(value_string), + "%u", + runtime_log->play_count); + + rjsonwriter_add_spaces(writer, 2); + rjsonwriter_add_string(writer, "play_count"); + rjsonwriter_raw(writer, ":", 1); + rjsonwriter_raw(writer, " ", 1); + rjsonwriter_add_string(writer, value_string); + rjsonwriter_raw(writer, ",", 1); + rjsonwriter_raw(writer, "\n", 1); + /* > Current state slot */ value_string[0] = '\0'; snprintf(value_string, sizeof(value_string), diff --git a/runtime_file.h b/runtime_file.h index c694e7ff21..c26c31eef8 100644 --- a/runtime_file.h +++ b/runtime_file.h @@ -57,6 +57,7 @@ typedef struct { rtl_runtime_t runtime; /* unsigned alignment */ rtl_last_played_t last_played; /* unsigned alignment */ + unsigned play_count; unsigned state_slot; char path[PATH_MAX_LENGTH]; } runtime_log_t;