diff --git a/command.c b/command.c index fc7a0ff97a..72e818eaa8 100644 --- a/command.c +++ b/command.c @@ -2222,13 +2222,6 @@ TODO: Add a setting for these tweaks */ } g_defaults.music_history = NULL; - if (g_defaults.content_runtime) - { - playlist_write_runtime_file(g_defaults.content_runtime); - playlist_free(g_defaults.content_runtime); - } - g_defaults.content_runtime = NULL; - #if defined(HAVE_FFMPEG) || defined(HAVE_MPV) if (g_defaults.video_history) { @@ -2279,13 +2272,6 @@ TODO: Add a setting for these tweaks */ settings->paths.path_content_music_history, content_history_size); - RARCH_LOG("%s: [%s].\n", - msg_hash_to_str(MSG_LOADING_HISTORY_FILE), - settings->paths.path_content_runtime); - g_defaults.content_runtime = playlist_init( - settings->paths.path_content_runtime, - content_history_size); - #if defined(HAVE_FFMPEG) || defined(HAVE_MPV) RARCH_LOG("%s: [%s].\n", msg_hash_to_str(MSG_LOADING_HISTORY_FILE), diff --git a/configuration.c b/configuration.c index 338a59e05d..55d67b7a75 100644 --- a/configuration.c +++ b/configuration.c @@ -1234,8 +1234,6 @@ static struct config_path_setting *populate_settings_path(settings_t *settings, settings->paths.path_content_video_history, false, NULL, true); SETTING_PATH("content_image_history_path", settings->paths.path_content_image_history, false, NULL, true); - SETTING_PATH("content_runtime_path", - settings->paths.path_content_runtime, false, NULL, true); #ifdef HAVE_OVERLAY SETTING_PATH("input_overlay", settings->paths.path_overlay, false, NULL, true); @@ -2085,7 +2083,6 @@ void config_set_defaults(void) *settings->paths.path_content_music_history = '\0'; *settings->paths.path_content_image_history = '\0'; *settings->paths.path_content_video_history = '\0'; - *settings->paths.path_content_runtime = '\0'; *settings->paths.path_cheat_settings = '\0'; *settings->paths.path_shader = '\0'; #ifndef IOS @@ -3069,25 +3066,6 @@ static bool config_load_file(const char *path, bool set_defaults, } } - if (string_is_empty(settings->paths.path_content_runtime)) - { - if (string_is_empty(settings->paths.directory_content_history)) - { - fill_pathname_resolve_relative( - settings->paths.path_content_runtime, - path_config, - file_path_str(FILE_PATH_CONTENT_RUNTIME), - sizeof(settings->paths.path_content_runtime)); - } - else - { - fill_pathname_join(settings->paths.path_content_runtime, - settings->paths.directory_content_history, - file_path_str(FILE_PATH_CONTENT_RUNTIME), - sizeof(settings->paths.path_content_runtime)); - } - } - if (!string_is_empty(settings->paths.directory_screenshot)) { if (string_is_equal(settings->paths.directory_screenshot, "default")) diff --git a/configuration.h b/configuration.h index 79f64ef833..517da9e807 100644 --- a/configuration.h +++ b/configuration.h @@ -552,7 +552,6 @@ typedef struct settings char path_content_music_history[PATH_MAX_LENGTH]; char path_content_image_history[PATH_MAX_LENGTH]; char path_content_video_history[PATH_MAX_LENGTH]; - char path_content_runtime[PATH_MAX_LENGTH]; char path_libretro_info[PATH_MAX_LENGTH]; char path_cheat_settings[PATH_MAX_LENGTH]; char path_shader[PATH_MAX_LENGTH]; diff --git a/defaults.h b/defaults.h index 1a0c58f694..117e14a39a 100644 --- a/defaults.h +++ b/defaults.h @@ -103,7 +103,6 @@ struct defaults #ifndef IS_SALAMANDER playlist_t *content_history; playlist_t *content_favorites; - playlist_t *content_runtime; #ifdef HAVE_IMAGEVIEWER playlist_t *image_history; #endif diff --git a/file_path_special.h b/file_path_special.h index c8e5c2ba68..8b7cc3e3ef 100644 --- a/file_path_special.h +++ b/file_path_special.h @@ -38,7 +38,6 @@ enum file_path_enum FILE_PATH_LOG_ERROR, FILE_PATH_LOG_INFO, FILE_PATH_CONTENT_HISTORY, - FILE_PATH_CONTENT_RUNTIME, FILE_PATH_CONTENT_FAVORITES, FILE_PATH_CONTENT_MUSIC_HISTORY, FILE_PATH_CONTENT_VIDEO_HISTORY, diff --git a/file_path_str.c b/file_path_str.c index 30aa0ff79e..46aad7605f 100644 --- a/file_path_str.c +++ b/file_path_str.c @@ -200,9 +200,6 @@ const char *file_path_str(enum file_path_enum enum_idx) case FILE_PATH_CONTENT_HISTORY: str = "content_history.lpl"; break; - case FILE_PATH_CONTENT_RUNTIME: - str = "content_runtime.lpl"; - break; case FILE_PATH_CONTENT_FAVORITES: str = "content_favorites.lpl"; break; diff --git a/intl/msg_hash_us.h b/intl/msg_hash_us.h index 0ae886806a..daf0544f1e 100644 --- a/intl/msg_hash_us.h +++ b/intl/msg_hash_us.h @@ -8334,3 +8334,7 @@ MSG_HASH( MENU_ENUM_LABEL_VALUE_PLAYLIST_SUBLABEL_RUNTIME, "Play Time:" ) +MSG_HASH( + MENU_ENUM_LABEL_VALUE_PLAYLIST_SUBLABEL_LAST_PLAYED, + "Last Played:" + ) diff --git a/menu/cbs/menu_cbs_sublabel.c b/menu/cbs/menu_cbs_sublabel.c index 151c823fe9..7071270c82 100644 --- a/menu/cbs/menu_cbs_sublabel.c +++ b/menu/cbs/menu_cbs_sublabel.c @@ -826,6 +826,12 @@ static int action_bind_sublabel_playlist_entry( unsigned runtime_hours = 0; unsigned runtime_minutes = 0; unsigned runtime_seconds = 0; + unsigned last_played_year = 0; + unsigned last_played_month = 0; + unsigned last_played_day = 0; + unsigned last_played_hour = 0; + unsigned last_played_minute = 0; + unsigned last_played_second = 0; if (!settings->bools.playlist_show_sublabels) return 0; @@ -836,7 +842,7 @@ static int action_bind_sublabel_playlist_entry( return 0; if (i >= playlist_get_size(playlist)) return 0; - + /* Read playlist entry */ playlist_get_index(playlist, i, NULL, NULL, NULL, &core_name, NULL, NULL); @@ -849,43 +855,56 @@ static int action_bind_sublabel_playlist_entry( msg_hash_to_str(MENU_ENUM_LABEL_VALUE_PLAYLIST_SUBLABEL_CORE), core_name); - /* Get runtime *if* 'content_runtime_log' is enabled - * NB: Runtime is currently stored in an independent - * 'content_runtime.lpl' file, similar to the content - * history. It therefore only really makes sense to - * check runtime when viewing the content history - * playlist. If runtime were added to all playlists - * (would be nice), we could do this trivially for all - * content. */ + /* Get runtime info *if* runtime logging is enabled + * *and* this is a valid playlist type */ if (!settings->bools.content_runtime_log) return 0; - if (!string_is_equal(label, msg_hash_to_str(MENU_ENUM_LABEL_LOAD_CONTENT_HISTORY)) - && !string_is_equal(label, msg_hash_to_str(MENU_ENUM_LABEL_HISTORY_TAB))) + /* Note: This looks heavy, but each string_is_equal() call will + * return almost immediately */ + if (!string_is_equal(label, msg_hash_to_str(MENU_ENUM_LABEL_LOAD_CONTENT_HISTORY)) && + !string_is_equal(label, msg_hash_to_str(MENU_ENUM_LABEL_HISTORY_TAB)) && + !string_is_equal(label, msg_hash_to_str(MENU_ENUM_LABEL_DEFERRED_FAVORITES_LIST)) && + !string_is_equal(label, msg_hash_to_str(MENU_ENUM_LABEL_FAVORITES_TAB)) && + !string_is_equal(label, msg_hash_to_str(MENU_ENUM_LABEL_DEFERRED_PLAYLIST_LIST)) && + !string_is_equal(label, msg_hash_to_str(MENU_ENUM_LABEL_HORIZONTAL_MENU))) return 0; /* Any available runtime values are now copied to the content * history playlist when it is parsed by menu_displaylist, so * we can extract them directly via index */ playlist_get_runtime_index(playlist, i, NULL, NULL, - &runtime_hours, &runtime_minutes, &runtime_seconds); + &runtime_hours, &runtime_minutes, &runtime_seconds, + &last_played_year, &last_played_month, &last_played_day, + &last_played_hour, &last_played_minute, &last_played_second); + /* Check whether a non-zero runtime has been recorded */ if ((runtime_hours > 0) || (runtime_minutes > 0) || (runtime_seconds > 0)) { int n = 0; char tmp[64]; - tmp[0] = '\0'; + /* 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), runtime_hours, runtime_minutes, runtime_seconds); - /* Stupid nonsense... GCC will generate warnings if we - * don't do something here... */ if ((n < 0) || (n >= 64)) - { - n = 0; - } + 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), + last_played_year, last_played_month, last_played_day, + last_played_hour, last_played_minute, last_played_second); + + if ((n < 0) || (n >= 64)) + n = 0; /* Silence GCC warnings... */ if (!string_is_empty(tmp)) strlcat(s, tmp, len); diff --git a/menu/menu_displaylist.c b/menu/menu_displaylist.c index dfa7a46402..b25fcc6346 100644 --- a/menu/menu_displaylist.c +++ b/menu/menu_displaylist.c @@ -93,6 +93,7 @@ #include "../wifi/wifi_driver.h" #include "../tasks/tasks_internal.h" #include "../dynamic.h" +#include "../runtime_file.h" static char new_path_entry[4096] = {0}; static char new_lbl_entry[4096] = {0}; @@ -1325,7 +1326,7 @@ static int menu_displaylist_parse_playlist(menu_displaylist_info_t *info, size_t list_size = playlist_size(playlist); settings_t *settings = config_get_ptr(); bool is_rgui = string_is_equal(settings->arrays.menu_driver, "rgui"); - bool get_runtime = string_is_equal(path_playlist, "history") && g_defaults.content_runtime && settings->bools.content_runtime_log; + bool get_runtime = false; char label_spacer[PL_LABEL_SPACER_MAXLEN]; label_spacer[0] = '\0'; @@ -1333,6 +1334,16 @@ static int menu_displaylist_parse_playlist(menu_displaylist_info_t *info, if (list_size == 0) goto error; + /* Check whether runtime logging info should be parsed */ + if (settings->bools.content_runtime_log) + { + /* Runtime logging is valid for every type of playlist *apart from* + * images/music/video history */ + get_runtime = !(string_is_equal(path_playlist, "images_history") || + string_is_equal(path_playlist, "music_history") || + string_is_equal(path_playlist, "video_history")); + } + /* Get spacer for menu entry labels () */ if (is_rgui) strlcpy(label_spacer, PL_LABEL_SPACER_RGUI, sizeof(label_spacer)); @@ -1368,32 +1379,46 @@ static int menu_displaylist_parse_playlist(menu_displaylist_info_t *info, playlist_get_index(playlist, i, &path, &label, &core_path, &core_name, NULL, NULL); - /* If this is the content history playlist and runtime logging - * is enabled, extract any available runtime values */ + /* Extract any available runtime values, if required */ if (get_runtime) { - unsigned j; + runtime_log_t *runtime_log = NULL; + runtime_log = runtime_log_init(path, core_path); - /* Search 'content_runtime.lpl' until we find the current - * content+core combo */ - for (j = 0; j < playlist_get_size(g_defaults.content_runtime); j++) + if (runtime_log) { - const char *runtime_path = NULL; - const char *runtime_core_path = NULL; - unsigned runtime_hours; - unsigned runtime_minutes; - unsigned runtime_seconds; - - playlist_get_runtime_index(g_defaults.content_runtime, j, &runtime_path, &runtime_core_path, - &runtime_hours, &runtime_minutes, &runtime_seconds); - - if (string_is_equal(path, runtime_path) && string_is_equal(core_path, runtime_core_path)) + /* Check whether a non-zero runtime has been recorded */ + if (runtime_log_has_runtime(runtime_log)) { - playlist_update_runtime(playlist, i, NULL, NULL, - runtime_hours, runtime_minutes, runtime_seconds); + 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; - break; + /* Read current runtime */ + runtime_log_get_runtime_hms(runtime_log, + &runtime_hours, &runtime_minutes, &runtime_seconds); + + /* Read last played timestamp */ + 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); + + /* Update playlist entry */ + playlist_update_runtime(playlist, i, NULL, NULL, + runtime_hours, runtime_minutes, runtime_seconds, + last_played_year, last_played_month, last_played_day, + last_played_hour, last_played_minute, last_played_second, + false); } + + /* Clean up */ + free(runtime_log); } } diff --git a/msg_hash.h b/msg_hash.h index fb033dc476..91867422b8 100644 --- a/msg_hash.h +++ b/msg_hash.h @@ -2283,6 +2283,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, MSG_LAST }; diff --git a/playlist.c b/playlist.c index 5b50a9456f..a4ec675a66 100644 --- a/playlist.c +++ b/playlist.c @@ -48,6 +48,15 @@ struct playlist_entry unsigned runtime_hours; unsigned runtime_minutes; unsigned runtime_seconds; + /* Note: due to platform dependence, have to record + * timestamp as either a string or independent integer + * values. The latter is more verbose, but more efficient. */ + unsigned last_played_year; + unsigned last_played_month; + unsigned last_played_day; + unsigned last_played_hour; + unsigned last_played_minute; + unsigned last_played_second; }; struct content_playlist @@ -133,8 +142,9 @@ void playlist_get_index(playlist_t *playlist, void playlist_get_runtime_index(playlist_t *playlist, size_t idx, const char **path, const char **core_path, - unsigned *runtime_hours, unsigned *runtime_minutes, - unsigned *runtime_seconds) + 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) { if (!playlist) return; @@ -149,6 +159,18 @@ void playlist_get_runtime_index(playlist_t *playlist, *runtime_minutes = playlist->entries[idx].runtime_minutes; if (runtime_seconds) *runtime_seconds = playlist->entries[idx].runtime_seconds; + if (last_played_year) + *last_played_year = playlist->entries[idx].last_played_year; + if (last_played_month) + *last_played_month = playlist->entries[idx].last_played_month; + if (last_played_day) + *last_played_day = playlist->entries[idx].last_played_day; + if (last_played_hour) + *last_played_hour = playlist->entries[idx].last_played_hour; + if (last_played_minute) + *last_played_minute = playlist->entries[idx].last_played_minute; + if (last_played_second) + *last_played_second = playlist->entries[idx].last_played_second; } /** @@ -252,6 +274,12 @@ static void playlist_free_entry(struct playlist_entry *entry) entry->runtime_hours = 0; entry->runtime_minutes = 0; entry->runtime_seconds = 0; + entry->last_played_year = 0; + entry->last_played_month = 0; + entry->last_played_day = 0; + entry->last_played_hour = 0; + entry->last_played_minute = 0; + entry->last_played_second = 0; } void playlist_update(playlist_t *playlist, size_t idx, @@ -319,8 +347,10 @@ void playlist_update(playlist_t *playlist, size_t idx, void playlist_update_runtime(playlist_t *playlist, size_t idx, const char *path, const char *core_path, - unsigned runtime_hours, unsigned runtime_minutes, - unsigned runtime_seconds) + 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, + bool register_update) { struct playlist_entry *entry = NULL; @@ -334,7 +364,7 @@ void playlist_update_runtime(playlist_t *playlist, size_t idx, if (entry->path != NULL) free(entry->path); entry->path = strdup(path); - playlist->modified = true; + playlist->modified = playlist->modified || register_update; } if (core_path && (core_path != entry->core_path)) @@ -343,32 +373,69 @@ void playlist_update_runtime(playlist_t *playlist, size_t idx, free(entry->core_path); entry->core_path = NULL; entry->core_path = strdup(core_path); - playlist->modified = true; + playlist->modified = playlist->modified || register_update; } if (runtime_hours != entry->runtime_hours) { entry->runtime_hours = runtime_hours; - playlist->modified = true; + playlist->modified = playlist->modified || register_update; } if (runtime_minutes != entry->runtime_minutes) { entry->runtime_minutes = runtime_minutes; - playlist->modified = true; + playlist->modified = playlist->modified || register_update; } if (runtime_seconds != entry->runtime_seconds) { entry->runtime_seconds = runtime_seconds; - playlist->modified = true; + playlist->modified = playlist->modified || register_update; + } + + if (last_played_year != entry->last_played_year) + { + entry->last_played_year = last_played_year; + playlist->modified = playlist->modified || register_update; + } + + if (last_played_month != entry->last_played_month) + { + entry->last_played_month = last_played_month; + playlist->modified = playlist->modified || register_update; + } + + if (last_played_day != entry->last_played_day) + { + entry->last_played_day = last_played_day; + playlist->modified = playlist->modified || register_update; + } + + if (last_played_hour != entry->last_played_hour) + { + entry->last_played_hour = last_played_hour; + playlist->modified = playlist->modified || register_update; + } + + if (last_played_minute != entry->last_played_minute) + { + entry->last_played_minute = last_played_minute; + playlist->modified = playlist->modified || register_update; + } + + if (last_played_second != entry->last_played_second) + { + entry->last_played_second = last_played_second; + playlist->modified = playlist->modified || register_update; } } bool playlist_push_runtime(playlist_t *playlist, const char *path, const char *core_path, - unsigned runtime_hours, unsigned runtime_minutes, - unsigned runtime_seconds) + 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) { size_t i; bool core_path_empty = string_is_empty(core_path); @@ -447,6 +514,12 @@ bool playlist_push_runtime(playlist_t *playlist, playlist->entries[0].runtime_hours = runtime_hours; playlist->entries[0].runtime_minutes = runtime_minutes; playlist->entries[0].runtime_seconds = runtime_seconds; + playlist->entries[0].last_played_year = last_played_year; + playlist->entries[0].last_played_month = last_played_month; + playlist->entries[0].last_played_day = last_played_day; + playlist->entries[0].last_played_hour = last_played_hour; + playlist->entries[0].last_played_minute = last_played_minute; + playlist->entries[0].last_played_second = last_played_second; } playlist->size++; @@ -549,15 +622,21 @@ bool playlist_push(playlist_t *playlist, memmove(playlist->entries + 1, playlist->entries, (playlist->cap - 1) * sizeof(struct playlist_entry)); - playlist->entries[0].path = NULL; - playlist->entries[0].label = NULL; - playlist->entries[0].core_path = NULL; - playlist->entries[0].core_name = NULL; - playlist->entries[0].db_name = NULL; - playlist->entries[0].crc32 = NULL; - playlist->entries[0].runtime_hours = 0; - playlist->entries[0].runtime_minutes = 0; - playlist->entries[0].runtime_seconds = 0; + playlist->entries[0].path = NULL; + playlist->entries[0].label = NULL; + playlist->entries[0].core_path = NULL; + playlist->entries[0].core_name = NULL; + playlist->entries[0].db_name = NULL; + playlist->entries[0].crc32 = NULL; + playlist->entries[0].runtime_hours = 0; + playlist->entries[0].runtime_minutes = 0; + playlist->entries[0].runtime_seconds = 0; + playlist->entries[0].last_played_year = 0; + playlist->entries[0].last_played_month = 0; + playlist->entries[0].last_played_day = 0; + playlist->entries[0].last_played_hour = 0; + playlist->entries[0].last_played_minute = 0; + playlist->entries[0].last_played_second = 0; if (!string_is_empty(path)) playlist->entries[0].path = strdup(path); if (!string_is_empty(label)) @@ -711,6 +790,78 @@ void playlist_write_runtime_file(playlist_t *playlist) JSON_Writer_WriteColon(context.writer); JSON_Writer_WriteSpace(context.writer, 1); JSON_Writer_WriteNumber(context.writer, tmp, strlen(tmp), JSON_UTF8); + JSON_Writer_WriteComma(context.writer); + JSON_Writer_WriteNewLine(context.writer); + + memset(tmp, 0, sizeof(tmp)); + + snprintf(tmp, sizeof(tmp), "%u", playlist->entries[i].last_played_year); + + JSON_Writer_WriteSpace(context.writer, 6); + JSON_Writer_WriteString(context.writer, "last_played_year", strlen("last_played_year"), JSON_UTF8); + JSON_Writer_WriteColon(context.writer); + JSON_Writer_WriteSpace(context.writer, 1); + JSON_Writer_WriteNumber(context.writer, tmp, strlen(tmp), JSON_UTF8); + JSON_Writer_WriteComma(context.writer); + JSON_Writer_WriteNewLine(context.writer); + + memset(tmp, 0, sizeof(tmp)); + + snprintf(tmp, sizeof(tmp), "%u", playlist->entries[i].last_played_month); + + JSON_Writer_WriteSpace(context.writer, 6); + JSON_Writer_WriteString(context.writer, "last_played_month", strlen("last_played_month"), JSON_UTF8); + JSON_Writer_WriteColon(context.writer); + JSON_Writer_WriteSpace(context.writer, 1); + JSON_Writer_WriteNumber(context.writer, tmp, strlen(tmp), JSON_UTF8); + JSON_Writer_WriteComma(context.writer); + JSON_Writer_WriteNewLine(context.writer); + + memset(tmp, 0, sizeof(tmp)); + + snprintf(tmp, sizeof(tmp), "%u", playlist->entries[i].last_played_day); + + JSON_Writer_WriteSpace(context.writer, 6); + JSON_Writer_WriteString(context.writer, "last_played_day", strlen("last_played_day"), JSON_UTF8); + JSON_Writer_WriteColon(context.writer); + JSON_Writer_WriteSpace(context.writer, 1); + JSON_Writer_WriteNumber(context.writer, tmp, strlen(tmp), JSON_UTF8); + JSON_Writer_WriteComma(context.writer); + JSON_Writer_WriteNewLine(context.writer); + + memset(tmp, 0, sizeof(tmp)); + + snprintf(tmp, sizeof(tmp), "%u", playlist->entries[i].last_played_hour); + + JSON_Writer_WriteSpace(context.writer, 6); + JSON_Writer_WriteString(context.writer, "last_played_hour", strlen("last_played_hour"), JSON_UTF8); + JSON_Writer_WriteColon(context.writer); + JSON_Writer_WriteSpace(context.writer, 1); + JSON_Writer_WriteNumber(context.writer, tmp, strlen(tmp), JSON_UTF8); + JSON_Writer_WriteComma(context.writer); + JSON_Writer_WriteNewLine(context.writer); + + memset(tmp, 0, sizeof(tmp)); + + snprintf(tmp, sizeof(tmp), "%u", playlist->entries[i].last_played_minute); + + JSON_Writer_WriteSpace(context.writer, 6); + JSON_Writer_WriteString(context.writer, "last_played_minute", strlen("last_played_minute"), JSON_UTF8); + JSON_Writer_WriteColon(context.writer); + JSON_Writer_WriteSpace(context.writer, 1); + JSON_Writer_WriteNumber(context.writer, tmp, strlen(tmp), JSON_UTF8); + JSON_Writer_WriteComma(context.writer); + JSON_Writer_WriteNewLine(context.writer); + + memset(tmp, 0, sizeof(tmp)); + + snprintf(tmp, sizeof(tmp), "%u", playlist->entries[i].last_played_second); + + JSON_Writer_WriteSpace(context.writer, 6); + JSON_Writer_WriteString(context.writer, "last_played_second", strlen("last_played_second"), JSON_UTF8); + JSON_Writer_WriteColon(context.writer); + JSON_Writer_WriteSpace(context.writer, 1); + JSON_Writer_WriteNumber(context.writer, tmp, strlen(tmp), JSON_UTF8); JSON_Writer_WriteNewLine(context.writer); } @@ -1148,6 +1299,18 @@ static JSON_Parser_HandlerResult JSONObjectMemberHandler(JSON_Parser parser, cha pCtx->current_entry_uint_val = &pCtx->current_entry->runtime_minutes; else if (string_is_equal(pValue, "runtime_seconds")) pCtx->current_entry_uint_val = &pCtx->current_entry->runtime_seconds; + else if (string_is_equal(pValue, "last_played_year")) + pCtx->current_entry_uint_val = &pCtx->current_entry->last_played_year; + else if (string_is_equal(pValue, "last_played_month")) + pCtx->current_entry_uint_val = &pCtx->current_entry->last_played_month; + else if (string_is_equal(pValue, "last_played_day")) + pCtx->current_entry_uint_val = &pCtx->current_entry->last_played_day; + else if (string_is_equal(pValue, "last_played_hour")) + pCtx->current_entry_uint_val = &pCtx->current_entry->last_played_hour; + else if (string_is_equal(pValue, "last_played_minute")) + pCtx->current_entry_uint_val = &pCtx->current_entry->last_played_minute; + else if (string_is_equal(pValue, "last_played_second")) + pCtx->current_entry_uint_val = &pCtx->current_entry->last_played_second; else { /* ignore unknown members */ diff --git a/playlist.h b/playlist.h index 62e3c2c607..c22b07cd4e 100644 --- a/playlist.h +++ b/playlist.h @@ -82,8 +82,9 @@ void playlist_get_index(playlist_t *playlist, void playlist_get_runtime_index(playlist_t *playlist, size_t idx, const char **path, const char **core_path, - unsigned *runtime_hours, unsigned *runtime_minutes, - unsigned *runtime_seconds); + 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); /** * playlist_delete_index: @@ -112,8 +113,9 @@ bool playlist_push(playlist_t *playlist, bool playlist_push_runtime(playlist_t *playlist, const char *path, const char *core_path, - unsigned runtime_hours, unsigned runtime_minutes, - unsigned runtime_seconds); + 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); void playlist_update(playlist_t *playlist, size_t idx, const char *path, const char *label, @@ -121,10 +123,17 @@ void playlist_update(playlist_t *playlist, size_t idx, const char *crc32, const char *db_name); +/* Note: register_update determines whether the internal + * 'playlist->modified' flag is set when updating runtime + * values. Since these are normally set temporarily (for + * display purposes), we do not always want this function + * to trigger a re-write of the playlist file. */ void playlist_update_runtime(playlist_t *playlist, size_t idx, const char *path, const char *core_path, - unsigned runtime_hours, unsigned runtime_minutes, - unsigned runtime_seconds); + 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, + bool register_update); void playlist_get_index_by_path(playlist_t *playlist, const char *search_path, diff --git a/retroarch.c b/retroarch.c index 8acf0156df..fc4ed11df7 100644 --- a/retroarch.c +++ b/retroarch.c @@ -108,8 +108,6 @@ #include "file_path_special.h" #include "ui/ui_companion_driver.h" #include "verbosity.h" -#include "defaults.h" -#include "playlist.h" #include "frontend/frontend_driver.h" #include "audio/audio_driver.h" @@ -2404,91 +2402,27 @@ bool rarch_ctl(enum rarch_ctl_state state, void *data) n = 0; /* Just silence any potential gcc warnings... */ RARCH_LOG(log); - if (settings->bools.content_runtime_log) + /* Only write to file if logging is enabled *and* content has run + * for a non-zero length of time */ + if (settings->bools.content_runtime_log && libretro_core_runtime_usec > 0) { - const char *content_path = path_get(RARCH_PATH_CONTENT); - const char *core_path = path_get(RARCH_PATH_CORE); + runtime_log_t *runtime_log = NULL; - if (!string_is_empty(content_path) && !string_is_empty(core_path) && !string_is_equal(core_path, "builtin")) + /* Initialise runtime log file */ + runtime_log = runtime_log_init(path_get(RARCH_PATH_CONTENT), path_get(RARCH_PATH_CORE)); + if (runtime_log) { - unsigned playlist_hours = 0; - unsigned playlist_minutes = 0; - unsigned playlist_seconds = 0; - runtime_log_t *runtime_log = NULL; - bool playlist_file_is_valid = false; - bool runtime_log_file_is_valid = false; + /* Add additional runtime */ + runtime_log_add_runtime_usec(runtime_log, libretro_core_runtime_usec); - /* Intialise content_runtime playlist entry and get - * existing values */ - if (g_defaults.content_runtime) - { - /* Push current entry to the top (does not update runtime - * values), or create new entry if it does not already exist */ - playlist_push_runtime(g_defaults.content_runtime, content_path, core_path, 0, 0, 0); + /* Update 'last played' entry */ + runtime_log_set_last_played_now(runtime_log); - /* Get current runtime */ - if (playlist_get_size(g_defaults.content_runtime) > 0) - { - playlist_get_runtime_index(g_defaults.content_runtime, 0, NULL, NULL, - &playlist_hours, &playlist_minutes, &playlist_seconds); + /* Save runtime log file */ + runtime_log_save(runtime_log); - playlist_file_is_valid = true; - } - } - - /* Initialise runtime log file */ - runtime_log = runtime_log_init(content_path, core_path); - if (runtime_log) - { - /* If runtime log file is empty, populate it with values - * from content_runtime playlist */ - if (!runtime_log_has_runtime(runtime_log)) - { - runtime_log_set_runtime_hms(runtime_log, - playlist_hours, playlist_minutes, playlist_seconds); - } - - /* Add additional runtime */ - runtime_log_add_runtime_usec(runtime_log, libretro_core_runtime_usec); - - /* Read back current runtime, so we can copy it - * to content_runtime playlist */ - runtime_log_get_runtime_hms(runtime_log, - &playlist_hours, &playlist_minutes, &playlist_seconds); - - /* Update 'last played' entry */ - runtime_log_set_last_played_now(runtime_log); - - /* Save runtime log file */ - runtime_log_save(runtime_log); - - /* Clean up */ - free(runtime_log); - - runtime_log_file_is_valid = true; - } - - /* Update content_runtime playlist */ - if (playlist_file_is_valid) - { - /* If something went wrong with the runtime log - * file (can't happen...), then playlist_hours/minutes/seconds - * still contains original (old) values. Have to update them - * manually... */ - if (!runtime_log_file_is_valid) - { - retro_time_t usec_old; - - runtime_log_convert_hms2usec( - playlist_hours, playlist_minutes, playlist_seconds, &usec_old); - - runtime_log_convert_usec2hms(usec_old + libretro_core_runtime_usec, - &playlist_hours, &playlist_minutes, &playlist_seconds); - } - - playlist_update_runtime(g_defaults.content_runtime, 0, content_path, core_path, - playlist_hours, playlist_minutes, playlist_seconds); - } + /* Clean up */ + free(runtime_log); } }