diff --git a/manual_content_scan.c b/manual_content_scan.c index 40e8051927..9f5a734be0 100644 --- a/manual_content_scan.c +++ b/manual_content_scan.c @@ -1870,7 +1870,7 @@ void manual_content_scan_add_content_to_playlist( entry.core_name = (char*)FILE_PATH_DETECT; entry.crc32 = (char*)"00000000|crc"; entry.db_name = task_config->database_name; - entry.entry_slot = 0; + PLAYLIST_SET_ENTRY_SLOT(&entry, 0); /* Add entry to playlist */ playlist_push(playlist, &entry); diff --git a/menu/cbs/menu_cbs_sublabel.c b/menu/cbs/menu_cbs_sublabel.c index 26bd3651fe..787106567f 100644 --- a/menu/cbs/menu_cbs_sublabel.c +++ b/menu/cbs/menu_cbs_sublabel.c @@ -1275,11 +1275,11 @@ static int action_bind_sublabel_playlist_entry( return 0; /* Check whether runtime info should be loaded from log file */ - if (entry->runtime_status == PLAYLIST_RUNTIME_UNKNOWN) + if (PLAYLIST_RUNTIME_STATUS(entry) == PLAYLIST_RUNTIME_UNKNOWN) runtime_update_playlist(playlist, playlist_index); /* Check whether runtime info is valid */ - if (entry->runtime_status == PLAYLIST_RUNTIME_VALID) + if (PLAYLIST_RUNTIME_STATUS(entry) == PLAYLIST_RUNTIME_VALID) { size_t n = 0; char tmp[128]; diff --git a/menu/drivers/materialui.c b/menu/drivers/materialui.c index 44250db274..7ce439cfdc 100644 --- a/menu/drivers/materialui.c +++ b/menu/drivers/materialui.c @@ -4234,7 +4234,7 @@ static bool materialui_render_process_entry_playlist_desktop( /* Get runtime info, if available */ if (content_runtime_log || content_runtime_log_aggregate) { - if (entry->runtime_status == PLAYLIST_RUNTIME_UNKNOWN) + if (PLAYLIST_RUNTIME_STATUS(entry) == PLAYLIST_RUNTIME_UNKNOWN) runtime_update_playlist(mui->playlist, playlist_idx); if (entry->runtime_str && *entry->runtime_str) diff --git a/menu/drivers/ozone.c b/menu/drivers/ozone.c index 0bc77d3fc0..577411fce3 100644 --- a/menu/drivers/ozone.c +++ b/menu/drivers/ozone.c @@ -4659,7 +4659,7 @@ static void ozone_update_content_metadata(ozone_handle_t *ozone) if (entry) { - if ( (entry->runtime_status == PLAYLIST_RUNTIME_UNKNOWN) + if ( (PLAYLIST_RUNTIME_STATUS(entry) == PLAYLIST_RUNTIME_UNKNOWN) || (ozone->flags2 & OZONE_FLAG2_IS_QUICK_MENU)) runtime_update_playlist(playlist, playlist_index); diff --git a/playlist.c b/playlist.c index 4e707d3833..3b6b00fc32 100644 --- a/playlist.c +++ b/playlist.c @@ -120,6 +120,7 @@ enum json_ctx_flags enum playlist_json_packed_val { PLAYLIST_JSON_PACKED_NONE = 0, + PLAYLIST_JSON_PACKED_ENTRY_SLOT, PLAYLIST_JSON_PACKED_RUNTIME_HOURS, PLAYLIST_JSON_PACKED_RUNTIME_MINUTES, PLAYLIST_JSON_PACKED_RUNTIME_SECONDS, @@ -686,8 +687,8 @@ static void playlist_free_entry(struct playlist_entry *entry) entry->last_played_str = NULL; entry->subsystem_roms = NULL; entry->path_id = NULL; - entry->entry_slot = 0; - entry->runtime_status = PLAYLIST_RUNTIME_UNKNOWN; + PLAYLIST_SET_ENTRY_SLOT(entry, 0); + PLAYLIST_SET_RUNTIME_STATUS(entry, PLAYLIST_RUNTIME_UNKNOWN); PLAYLIST_SET_RUNTIME_HOURS(entry, 0); PLAYLIST_SET_RUNTIME_MINUTES(entry, 0); PLAYLIST_SET_RUNTIME_SECONDS(entry, 0); @@ -1211,9 +1212,9 @@ void playlist_update_runtime(playlist_t *playlist, size_t idx, playlist->flags |= CNT_PLAYLIST_FLG_MOD; } - if (update_entry->runtime_status != entry->runtime_status) + if (PLAYLIST_RUNTIME_STATUS(update_entry) != PLAYLIST_RUNTIME_STATUS(entry)) { - entry->runtime_status = update_entry->runtime_status; + PLAYLIST_SET_RUNTIME_STATUS(entry, PLAYLIST_RUNTIME_STATUS(update_entry)); if (register_update) playlist->flags |= CNT_PLAYLIST_FLG_MOD; } @@ -1399,7 +1400,8 @@ bool playlist_push_runtime(playlist_t *playlist, if (*real_core_path) playlist->entries[0].core_path = strdup(real_core_path); - playlist->entries[0].runtime_status = entry->runtime_status; + PLAYLIST_SET_RUNTIME_STATUS(&playlist->entries[0], + PLAYLIST_RUNTIME_STATUS(entry)); PLAYLIST_SET_RUNTIME_HOURS(&playlist->entries[0], PLAYLIST_RUNTIME_HOURS(entry)); PLAYLIST_SET_RUNTIME_MINUTES(&playlist->entries[0], PLAYLIST_RUNTIME_MINUTES(entry)); PLAYLIST_SET_RUNTIME_SECONDS(&playlist->entries[0], PLAYLIST_RUNTIME_SECONDS(entry)); @@ -1437,7 +1439,7 @@ void playlist_update_thumbnail_name_flag(playlist_t *playlist, size_t idx, return; entry = &playlist->entries[idx]; - entry->thumbnail_flags |= thumbnail_flags; + PLAYLIST_OR_THUMBNAIL_FLAGS(entry, thumbnail_flags); } enum playlist_thumbnail_name_flags playlist_get_curr_thumbnail_name_flag(playlist_t *playlist, size_t idx) @@ -1446,7 +1448,7 @@ enum playlist_thumbnail_name_flags playlist_get_curr_thumbnail_name_flag(playlis if (!playlist || idx >= RBUF_LEN(playlist->entries)) return PLAYLIST_THUMBNAIL_FLAG_NONE; entry = &playlist->entries[idx]; - return (enum playlist_thumbnail_name_flags)entry->thumbnail_flags; + return (enum playlist_thumbnail_name_flags)PLAYLIST_THUMBNAIL_FLAGS(entry); } @@ -1458,11 +1460,11 @@ enum playlist_thumbnail_name_flags playlist_get_next_thumbnail_name_flag(playlis return PLAYLIST_THUMBNAIL_FLAG_NONE; entry = (struct playlist_entry*)&playlist->entries[idx]; - if (entry->thumbnail_flags & PLAYLIST_THUMBNAIL_FLAG_SHORT_NAME) + if (PLAYLIST_THUMBNAIL_FLAGS(entry) & PLAYLIST_THUMBNAIL_FLAG_SHORT_NAME) return PLAYLIST_THUMBNAIL_FLAG_NONE; - if (entry->thumbnail_flags & PLAYLIST_THUMBNAIL_FLAG_STD_NAME) + if (PLAYLIST_THUMBNAIL_FLAGS(entry) & PLAYLIST_THUMBNAIL_FLAG_STD_NAME) return PLAYLIST_THUMBNAIL_FLAG_SHORT_NAME; - if (entry->thumbnail_flags & PLAYLIST_THUMBNAIL_FLAG_FULL_NAME) + if (PLAYLIST_THUMBNAIL_FLAGS(entry) & PLAYLIST_THUMBNAIL_FLAG_FULL_NAME) return PLAYLIST_THUMBNAIL_FLAG_STD_NAME; /* Special case: only one entry in playlist, only one query is possible * as flag swapping relies on going back and forth among entries @@ -1735,7 +1737,8 @@ static bool playlist_push_new_entry(playlist_t *playlist, playlist->entries[0].last_played_str = NULL; playlist->entries[0].subsystem_roms = NULL; playlist->entries[0].path_id = NULL; - playlist->entries[0].runtime_status = PLAYLIST_RUNTIME_UNKNOWN; + PLAYLIST_SET_RUNTIME_STATUS(&playlist->entries[0], + PLAYLIST_RUNTIME_UNKNOWN); PLAYLIST_SET_RUNTIME_HOURS(&playlist->entries[0], 0); PLAYLIST_SET_RUNTIME_MINUTES(&playlist->entries[0], 0); PLAYLIST_SET_RUNTIME_SECONDS(&playlist->entries[0], 0); @@ -1750,7 +1753,8 @@ static bool playlist_push_new_entry(playlist_t *playlist, playlist->entries[0].path = strdup(path_id->real_path); playlist->entries[0].path_id = path_id; - playlist->entries[0].entry_slot = entry->entry_slot; + PLAYLIST_SET_ENTRY_SLOT(&playlist->entries[0], + PLAYLIST_ENTRY_SLOT(entry)); if (entry->label && *entry->label) playlist->entries[0].label = strdup(entry->label); @@ -1898,10 +1902,11 @@ bool playlist_push(playlist_t *playlist, } /* Only write non-redundant entry slot numbers */ - if ( playlist->entries[i].entry_slot != entry->entry_slot - && (int)entry->entry_slot > 0) + if ( PLAYLIST_ENTRY_SLOT(&playlist->entries[i]) != PLAYLIST_ENTRY_SLOT(entry) + && (int)PLAYLIST_ENTRY_SLOT(entry) > 0) { - playlist->entries[i].entry_slot = entry->entry_slot; + PLAYLIST_SET_ENTRY_SLOT(&playlist->entries[i], + PLAYLIST_ENTRY_SLOT(entry)); entry_updated = true; } @@ -2482,7 +2487,7 @@ void playlist_write_file(playlist_t *playlist) /* Typecast required because playlist_entry.entry_slot is unsigned, * and 0 and -1 are redundant, but runloop.entry_state_slot is int16_t * and must be able to be negative, because 0 is a valid slot */ - if ( (int)playlist->entries[i].entry_slot > 0 + if ( (int)PLAYLIST_ENTRY_SLOT(&playlist->entries[i]) > 0 && !strstr(playlist->config.path, FILE_PATH_BUILTIN)) { rjsonwriter_raw(writer, ",", 1); @@ -2490,7 +2495,8 @@ void playlist_write_file(playlist_t *playlist) rjsonwriter_add_spaces(writer, 6); rjsonwriter_add_string(writer, "entry_slot"); rjsonwriter_raw(writer, ": ", 2); - rjsonwriter_rawf(writer, "%d", (int)playlist->entries[i].entry_slot); + rjsonwriter_rawf(writer, "%d", + (int)PLAYLIST_ENTRY_SLOT(&playlist->entries[i])); } if (playlist->entries[i].subsystem_ident && *playlist->entries[i].subsystem_ident) @@ -2874,6 +2880,9 @@ static bool JSONNumberHandler(void *context, const char *pValue, size_t len) unsigned v = (unsigned)strtoul(pValue, NULL, 10); switch (pCtx->current_entry_packed_val) { + case PLAYLIST_JSON_PACKED_ENTRY_SLOT: + PLAYLIST_SET_ENTRY_SLOT(pCtx->current_entry, v); + break; case PLAYLIST_JSON_PACKED_RUNTIME_HOURS: PLAYLIST_SET_RUNTIME_HOURS(pCtx->current_entry, v); break; @@ -2989,7 +2998,7 @@ static bool JSONObjectMemberHandler(void *context, const char *pValue, size_t le break; case 'e': if (!strcmp(pValue, "entry_slot")) - pCtx->current_entry_uint_val = &pCtx->current_entry->entry_slot; + pCtx->current_entry_packed_val = PLAYLIST_JSON_PACKED_ENTRY_SLOT; break; case 'l': if (!strcmp(pValue, "label")) diff --git a/playlist.h b/playlist.h index 35ac974865..7ccc98d261 100644 --- a/playlist.h +++ b/playlist.h @@ -130,7 +130,6 @@ struct playlist_entry char *last_played_str; struct string_list *subsystem_roms; playlist_path_id_t *path_id; - unsigned entry_slot; /* 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. @@ -145,10 +144,27 @@ struct playlist_entry uint32_t runtime; /* hours:20 | minutes:6 | seconds:6 */ uint32_t last_played_ymd; /* year:16 | month:4 | day:5 */ uint32_t last_played_hms; /* hour:5 | minute:6 | second:6 */ - enum playlist_runtime_status runtime_status; - int thumbnail_flags; + /* Packed, for the same reason as the timestamps above: the slot + * index is a subsystem content slot, the runtime status has three + * values and the thumbnail flags are five bits. */ + uint32_t attr; /* slot:16 | status:3 | thumbs:5 */ }; +#define PLAYLIST_ENTRY_SLOT(e) ((e)->attr & 0xffffu) +#define PLAYLIST_RUNTIME_STATUS(e) \ + ((enum playlist_runtime_status)(((e)->attr >> 16) & 0x7u)) +#define PLAYLIST_THUMBNAIL_FLAGS(e) ((int)(((e)->attr >> 19) & 0x1fu)) +#define PLAYLIST_SET_ENTRY_SLOT(e, v) \ + ((e)->attr = ((e)->attr & ~0xffffu) | ((uint32_t)(v) & 0xffffu)) +#define PLAYLIST_SET_RUNTIME_STATUS(e, v) \ + ((e)->attr = ((e)->attr & ~(0x7u << 16)) \ + | (((uint32_t)(v) & 0x7u) << 16)) +#define PLAYLIST_SET_THUMBNAIL_FLAGS(e, v) \ + ((e)->attr = ((e)->attr & ~(0x1fu << 19)) \ + | (((uint32_t)(v) & 0x1fu) << 19)) +#define PLAYLIST_OR_THUMBNAIL_FLAGS(e, v) \ + PLAYLIST_SET_THUMBNAIL_FLAGS((e), PLAYLIST_THUMBNAIL_FLAGS(e) | (int)(v)) + #define PLAYLIST_RUNTIME_HOURS(e) ((e)->runtime >> 12) #define PLAYLIST_RUNTIME_MINUTES(e) (((e)->runtime >> 6) & 0x3fu) #define PLAYLIST_RUNTIME_SECONDS(e) ((e)->runtime & 0x3fu) diff --git a/runloop.c b/runloop.c index 3c0adaa0db..95984cc168 100644 --- a/runloop.c +++ b/runloop.c @@ -4801,8 +4801,8 @@ static bool event_init_content( if (menu_st && menu_st->driver_data) playlist_get_index(playlist, menu_st->driver_data->rpl_entry_selection_ptr, &entry); - if (entry && entry->entry_slot > 0) - runloop_st->entry_state_slot = entry->entry_slot; + if (entry && PLAYLIST_ENTRY_SLOT(entry) > 0) + runloop_st->entry_state_slot = PLAYLIST_ENTRY_SLOT(entry); entry_state_load = runloop_st->entry_state_slot > -1; diff --git a/runtime_file.c b/runtime_file.c index 86cc568e26..e3339d3964 100644 --- a/runtime_file.c +++ b/runtime_file.c @@ -1362,7 +1362,7 @@ void runtime_update_playlist( /* Set fallback playlist 'runtime_status' * (saves 'if' checks later...) */ - update_entry.runtime_status = PLAYLIST_RUNTIME_MISSING; + PLAYLIST_SET_RUNTIME_STATUS(&update_entry, PLAYLIST_RUNTIME_MISSING); /* 'Attach' runtime/last played strings */ runtime_str[0] = '\0'; @@ -1423,7 +1423,7 @@ void runtime_update_playlist( timedate_style, date_separator); /* Playlist entry now contains valid runtime data */ - update_entry.runtime_status = PLAYLIST_RUNTIME_VALID; + PLAYLIST_SET_RUNTIME_STATUS(&update_entry, PLAYLIST_RUNTIME_VALID); } /* Clean up */ @@ -1433,7 +1433,7 @@ void runtime_update_playlist( #if defined(HAVE_MENU) && (defined(HAVE_OZONE) || defined(HAVE_MATERIALUI)) /* Ozone and GLUI require runtime/last played strings * to be populated even when no runtime is recorded */ - if (update_entry.runtime_status != PLAYLIST_RUNTIME_VALID) + if (PLAYLIST_RUNTIME_STATUS(&update_entry) != PLAYLIST_RUNTIME_VALID) { const char *menu_ident = menu_driver_ident(); if ( !strcmp(menu_ident, "ozone") @@ -1447,7 +1447,7 @@ void runtime_update_playlist( /* While runtime data does not exist, the playlist * entry does now contain valid information... */ - update_entry.runtime_status = PLAYLIST_RUNTIME_VALID; + PLAYLIST_SET_RUNTIME_STATUS(&update_entry, PLAYLIST_RUNTIME_VALID); } } #endif diff --git a/tasks/task_content.c b/tasks/task_content.c index b144c4bde3..109aa0c25b 100644 --- a/tasks/task_content.c +++ b/tasks/task_content.c @@ -2199,7 +2199,7 @@ static void task_push_to_history_list( entry.subsystem_ident = (char*)path_get(RARCH_PATH_SUBSYSTEM); entry.subsystem_name = (char*)subsystem_name; entry.subsystem_roms = (struct string_list*)path_get_subsystem_list(); - entry.entry_slot = runloop_st->entry_state_slot; + PLAYLIST_SET_ENTRY_SLOT(&entry, runloop_st->entry_state_slot); command_playlist_push_write(playlist_hist, &entry); #if TARGET_OS_TV @@ -2295,7 +2295,7 @@ static bool task_push_to_history_list_from_playlist_pre_load_static( { label = pl_entry->label; crc32 = pl_entry->crc32; - ss_entry_slot = pl_entry->entry_slot; + ss_entry_slot = PLAYLIST_ENTRY_SLOT(pl_entry); } playlist_get_db_name(playlist_curr, @@ -2323,7 +2323,7 @@ static bool task_push_to_history_list_from_playlist_pre_load_static( new_entry.core_name = (char*)core_name; new_entry.crc32 = (char*)crc32; new_entry.db_name = (char*)db_name; - new_entry.entry_slot = ss_entry_slot; + PLAYLIST_SET_ENTRY_SLOT(&new_entry, ss_entry_slot); /* TODO/FIXME: Subsystems are not properly supported * on static platforms, so exclude the following: diff --git a/tasks/task_database.c b/tasks/task_database.c index cf0c567ba1..24cb6c9262 100644 --- a/tasks/task_database.c +++ b/tasks/task_database.c @@ -2209,7 +2209,7 @@ static bool manual_scan_end_flush_tick( entry.subsystem_ident = NULL; entry.subsystem_name = NULL; entry.subsystem_roms = NULL; - entry.entry_slot = 0; + PLAYLIST_SET_ENTRY_SLOT(&entry, 0); PLAYLIST_SET_RUNTIME_HOURS(&entry, 0); PLAYLIST_SET_RUNTIME_MINUTES(&entry, 0); PLAYLIST_SET_RUNTIME_SECONDS(&entry, 0);