mirror of
https://github.com/libretro/RetroArch.git
synced 2025-01-27 03:56:06 +00:00
Prevent duplicate content history entries (+ general sanitisation of playlist searching)
This commit is contained in:
parent
7cc7a6df75
commit
05e0a6c8d2
@ -743,6 +743,8 @@ static const unsigned playlist_sublabel_runtime_type = PLAYLIST_RUNTIME_PER_CORE
|
||||
|
||||
static const bool playlist_show_sublabels = false;
|
||||
|
||||
static const bool playlist_fuzzy_archive_match = false;
|
||||
|
||||
/* Show Menu start-up screen on boot. */
|
||||
static const bool default_menu_show_start_screen = true;
|
||||
|
||||
|
@ -1601,6 +1601,7 @@ static struct config_bool_setting *populate_settings_bool(settings_t *settings,
|
||||
SETTING_BOOL("content_runtime_log_aggregate", &settings->bools.content_runtime_log_aggregate, true, content_runtime_log_aggregate, false);
|
||||
SETTING_BOOL("playlist_show_sublabels", &settings->bools.playlist_show_sublabels, true, playlist_show_sublabels, false);
|
||||
SETTING_BOOL("playlist_sort_alphabetical", &settings->bools.playlist_sort_alphabetical, true, playlist_sort_alphabetical, false);
|
||||
SETTING_BOOL("playlist_fuzzy_archive_match", &settings->bools.playlist_fuzzy_archive_match, true, playlist_fuzzy_archive_match, false);
|
||||
|
||||
SETTING_BOOL("quit_press_twice", &settings->bools.quit_press_twice, true, quit_press_twice, false);
|
||||
SETTING_BOOL("vibrate_on_keypress", &settings->bools.vibrate_on_keypress, true, vibrate_on_keypress, false);
|
||||
|
@ -317,6 +317,7 @@ typedef struct settings
|
||||
|
||||
bool playlist_sort_alphabetical;
|
||||
bool playlist_show_sublabels;
|
||||
bool playlist_fuzzy_archive_match;
|
||||
|
||||
bool quit_press_twice;
|
||||
bool vibrate_on_keypress;
|
||||
|
@ -1825,6 +1825,8 @@ MSG_HASH(MENU_ENUM_LABEL_PLAYLIST_SORT_ALPHABETICAL,
|
||||
"playlist_sort_alphabetical")
|
||||
MSG_HASH(MENU_ENUM_LABEL_PLAYLIST_SHOW_SUBLABELS,
|
||||
"playlist_show_sublabels")
|
||||
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_HELP_SEND_DEBUG_INFO,
|
||||
|
@ -8592,6 +8592,14 @@ MSG_HASH(
|
||||
MENU_ENUM_LABEL_VALUE_PLAYLIST_RUNTIME_PER_CORE,
|
||||
"Per Core"
|
||||
)
|
||||
MSG_HASH(
|
||||
MENU_ENUM_LABEL_VALUE_PLAYLIST_FUZZY_ARCHIVE_MATCH,
|
||||
"Fuzzy archive matching"
|
||||
)
|
||||
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"
|
||||
|
@ -549,6 +549,7 @@ default_sublabel_macro(action_bind_sublabel_menu_ticker_type,
|
||||
default_sublabel_macro(action_bind_sublabel_menu_ticker_speed, MENU_ENUM_SUBLABEL_MENU_TICKER_SPEED)
|
||||
default_sublabel_macro(action_bind_sublabel_playlist_show_inline_core_name, MENU_ENUM_SUBLABEL_PLAYLIST_SHOW_INLINE_CORE_NAME)
|
||||
default_sublabel_macro(action_bind_sublabel_playlist_sort_alphabetical, MENU_ENUM_SUBLABEL_PLAYLIST_SORT_ALPHABETICAL)
|
||||
default_sublabel_macro(action_bind_sublabel_playlist_fuzzy_archive_match, MENU_ENUM_SUBLABEL_PLAYLIST_FUZZY_ARCHIVE_MATCH)
|
||||
default_sublabel_macro(action_bind_sublabel_menu_rgui_full_width_layout, MENU_ENUM_SUBLABEL_MENU_RGUI_FULL_WIDTH_LAYOUT)
|
||||
default_sublabel_macro(action_bind_sublabel_menu_rgui_extended_ascii, MENU_ENUM_SUBLABEL_MENU_RGUI_EXTENDED_ASCII)
|
||||
default_sublabel_macro(action_bind_sublabel_help_send_debug_info, MENU_ENUM_SUBLABEL_HELP_SEND_DEBUG_INFO)
|
||||
@ -2494,6 +2495,9 @@ int menu_cbs_init_bind_sublabel(menu_file_list_cbs_t *cbs,
|
||||
case MENU_ENUM_LABEL_PLAYLIST_SORT_ALPHABETICAL:
|
||||
BIND_ACTION_SUBLABEL(cbs, action_bind_sublabel_playlist_sort_alphabetical);
|
||||
break;
|
||||
case MENU_ENUM_LABEL_PLAYLIST_FUZZY_ARCHIVE_MATCH:
|
||||
BIND_ACTION_SUBLABEL(cbs, action_bind_sublabel_playlist_fuzzy_archive_match);
|
||||
break;
|
||||
case MENU_ENUM_LABEL_MENU_RGUI_FULL_WIDTH_LAYOUT:
|
||||
BIND_ACTION_SUBLABEL(cbs, action_bind_sublabel_menu_rgui_full_width_layout);
|
||||
break;
|
||||
|
@ -5460,6 +5460,7 @@ bool menu_displaylist_ctl(enum menu_displaylist_ctl_state type,
|
||||
{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},
|
||||
};
|
||||
|
||||
for (i = 0; i < ARRAY_SIZE(build_list); i++)
|
||||
|
@ -12741,6 +12741,22 @@ static bool setting_append_list(
|
||||
&setting_get_string_representation_uint_playlist_inline_core_display_type;
|
||||
menu_settings_list_current_add_range(list, list_info, 0, PLAYLIST_INLINE_CORE_DISPLAY_LAST-1, 1, true, true);
|
||||
|
||||
CONFIG_BOOL(
|
||||
list, list_info,
|
||||
&settings->bools.playlist_fuzzy_archive_match,
|
||||
MENU_ENUM_LABEL_PLAYLIST_FUZZY_ARCHIVE_MATCH,
|
||||
MENU_ENUM_LABEL_VALUE_PLAYLIST_FUZZY_ARCHIVE_MATCH,
|
||||
playlist_fuzzy_archive_match,
|
||||
MENU_ENUM_LABEL_VALUE_OFF,
|
||||
MENU_ENUM_LABEL_VALUE_ON,
|
||||
&group_info,
|
||||
&subgroup_info,
|
||||
parent_group,
|
||||
general_write_handler,
|
||||
general_read_handler,
|
||||
SD_FLAG_NONE
|
||||
);
|
||||
|
||||
END_SUB_GROUP(list, list_info, parent_group);
|
||||
|
||||
END_GROUP(list, list_info, parent_group);
|
||||
|
@ -2322,6 +2322,7 @@ enum msg_hash_enums
|
||||
MENU_LABEL(PLAYLIST_SHOW_INLINE_CORE_NAME),
|
||||
MENU_LABEL(PLAYLIST_SORT_ALPHABETICAL),
|
||||
MENU_LABEL(PLAYLIST_SHOW_SUBLABELS),
|
||||
MENU_LABEL(PLAYLIST_FUZZY_ARCHIVE_MATCH),
|
||||
MENU_LABEL(PLAYLIST_SUBLABEL_RUNTIME_TYPE),
|
||||
|
||||
MENU_ENUM_LABEL_VALUE_PLAYLIST_INLINE_CORE_DISPLAY_HIST_FAV,
|
||||
|
322
playlist.c
322
playlist.c
@ -74,6 +74,133 @@ typedef int (playlist_sort_fun_t)(
|
||||
const struct playlist_entry *a,
|
||||
const struct playlist_entry *b);
|
||||
|
||||
/**
|
||||
* playlist_path_equal:
|
||||
* @real_path : 'Real' search path, generated by path_resolve_realpath()
|
||||
* @entry_path : Existing playlist entry 'path' value
|
||||
*
|
||||
* Returns 'true' if real_path matches entry_path
|
||||
* (Taking into account relative paths, case insensitive
|
||||
* filesystems, 'incomplete' archive paths)
|
||||
**/
|
||||
static bool playlist_path_equal(const char *real_path, const char *entry_path)
|
||||
{
|
||||
settings_t *settings = config_get_ptr();
|
||||
bool real_path_is_compressed;
|
||||
bool entry_real_path_is_compressed;
|
||||
char entry_real_path[PATH_MAX_LENGTH];
|
||||
|
||||
entry_real_path[0] = '\0';
|
||||
|
||||
/* Sanity check */
|
||||
if (string_is_empty(real_path) || string_is_empty(entry_path) || !settings)
|
||||
return false;
|
||||
|
||||
/* Get entry 'real' path */
|
||||
strlcpy(entry_real_path, entry_path, sizeof(entry_real_path));
|
||||
path_resolve_realpath(entry_real_path, sizeof(entry_real_path));
|
||||
|
||||
if (string_is_empty(entry_real_path))
|
||||
return false;
|
||||
|
||||
/* First pass comparison */
|
||||
#ifdef _WIN32
|
||||
/* Handle case-insensitive operating systems*/
|
||||
if (string_is_equal_noncase(real_path, entry_real_path))
|
||||
return true;
|
||||
#else
|
||||
if (string_is_equal(real_path, entry_real_path))
|
||||
return true;
|
||||
#endif
|
||||
|
||||
/* If fuzzy matching is disabled, we can give up now */
|
||||
if (!settings->bools.playlist_fuzzy_archive_match)
|
||||
return false;
|
||||
|
||||
/* If we reach this point, we have to work
|
||||
* harder...
|
||||
* Need to handle a rather awkward archive file
|
||||
* case where:
|
||||
* - playlist path contains a properly formatted
|
||||
* [archive_path][delimiter][rom_file]
|
||||
* - search path is just [archive_path]
|
||||
* ...or vice versa.
|
||||
* This pretty much always happens when a playlist
|
||||
* is generated via scan content (which handles the
|
||||
* archive paths correctly), but the user subsequently
|
||||
* loads an archive file via the command line or some
|
||||
* external launcher (where the [delimiter][rom_file]
|
||||
* part is almost always omitted) */
|
||||
real_path_is_compressed = path_is_compressed_file(real_path);
|
||||
entry_real_path_is_compressed = path_is_compressed_file(entry_real_path);
|
||||
|
||||
if ((real_path_is_compressed && !entry_real_path_is_compressed) ||
|
||||
(!real_path_is_compressed && entry_real_path_is_compressed))
|
||||
{
|
||||
const char *compressed_path_a = real_path_is_compressed ? real_path : entry_real_path;
|
||||
const char *full_path = real_path_is_compressed ? entry_real_path : real_path;
|
||||
const char *delim = path_get_archive_delim(full_path);
|
||||
|
||||
if (delim)
|
||||
{
|
||||
char compressed_path_b[PATH_MAX_LENGTH] = {0};
|
||||
unsigned len = 1 + delim - full_path;
|
||||
|
||||
strlcpy(compressed_path_b, full_path,
|
||||
(len < PATH_MAX_LENGTH ? len : PATH_MAX_LENGTH) * sizeof(char));
|
||||
|
||||
#ifdef _WIN32
|
||||
/* Handle case-insensitive operating systems*/
|
||||
if (string_is_equal_noncase(compressed_path_a, compressed_path_b))
|
||||
return true;
|
||||
#else
|
||||
if (string_is_equal(compressed_path_a, compressed_path_b))
|
||||
return true;
|
||||
#endif
|
||||
}
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* playlist_core_path_equal:
|
||||
* @real_core_path : 'Real' search path, generated by path_resolve_realpath()
|
||||
* @entry_core_path : Existing playlist entry 'core path' value
|
||||
*
|
||||
* Returns 'true' if real_core_path matches entry_core_path
|
||||
* (Taking into account relative paths, case insensitive
|
||||
* filesystems)
|
||||
**/
|
||||
static bool playlist_core_path_equal(const char *real_core_path, const char *entry_core_path)
|
||||
{
|
||||
char entry_real_core_path[PATH_MAX_LENGTH];
|
||||
|
||||
entry_real_core_path[0] = '\0';
|
||||
|
||||
/* Sanity check */
|
||||
if (string_is_empty(real_core_path) || string_is_empty(entry_core_path))
|
||||
return false;
|
||||
|
||||
/* Get entry 'real' core path */
|
||||
strlcpy(entry_real_core_path, entry_core_path, sizeof(entry_real_core_path));
|
||||
path_resolve_realpath(entry_real_core_path, sizeof(entry_real_core_path));
|
||||
|
||||
if (string_is_empty(entry_real_core_path))
|
||||
return false;
|
||||
|
||||
#ifdef _WIN32
|
||||
/* Handle case-insensitive operating systems*/
|
||||
if (string_is_equal_noncase(real_core_path, entry_real_core_path))
|
||||
return true;
|
||||
#else
|
||||
if (string_is_equal(real_core_path, entry_real_core_path))
|
||||
return true;
|
||||
#endif
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
uint32_t playlist_get_size(playlist_t *playlist)
|
||||
{
|
||||
if (!playlist)
|
||||
@ -168,13 +295,20 @@ void playlist_get_index_by_path(playlist_t *playlist,
|
||||
const struct playlist_entry **entry)
|
||||
{
|
||||
size_t i;
|
||||
char real_search_path[PATH_MAX_LENGTH];
|
||||
|
||||
if (!playlist || !entry)
|
||||
real_search_path[0] = '\0';
|
||||
|
||||
if (!playlist || !entry || string_is_empty(search_path))
|
||||
return;
|
||||
|
||||
/* Get 'real' search path */
|
||||
strlcpy(real_search_path, search_path, sizeof(real_search_path));
|
||||
path_resolve_realpath(real_search_path, sizeof(real_search_path));
|
||||
|
||||
for (i = 0; i < playlist->size; i++)
|
||||
{
|
||||
if (!string_is_equal(playlist->entries[i].path, search_path))
|
||||
if (!playlist_path_equal(real_search_path, playlist->entries[i].path))
|
||||
continue;
|
||||
|
||||
*entry = &playlist->entries[i];
|
||||
@ -188,11 +322,19 @@ bool playlist_entry_exists(playlist_t *playlist,
|
||||
const char *crc32)
|
||||
{
|
||||
size_t i;
|
||||
if (!playlist)
|
||||
char real_search_path[PATH_MAX_LENGTH];
|
||||
|
||||
real_search_path[0] = '\0';
|
||||
|
||||
if (!playlist || string_is_empty(path))
|
||||
return false;
|
||||
|
||||
/* Get 'real' search path */
|
||||
strlcpy(real_search_path, path, sizeof(real_search_path));
|
||||
path_resolve_realpath(real_search_path, sizeof(real_search_path));
|
||||
|
||||
for (i = 0; i < playlist->size; i++)
|
||||
if (string_is_equal(playlist->entries[i].path, path))
|
||||
if (playlist_path_equal(real_search_path, playlist->entries[i].path))
|
||||
return true;
|
||||
|
||||
return false;
|
||||
@ -401,41 +543,52 @@ bool playlist_push_runtime(playlist_t *playlist,
|
||||
unsigned last_played_hour, unsigned last_played_minute, unsigned last_played_second)
|
||||
{
|
||||
size_t i;
|
||||
bool core_path_empty = string_is_empty(core_path);
|
||||
char real_path[PATH_MAX_LENGTH];
|
||||
char real_core_path[PATH_MAX_LENGTH];
|
||||
|
||||
if (core_path_empty)
|
||||
{
|
||||
RARCH_ERR("cannot push NULL or empty core name into the playlist.\n");
|
||||
return false;
|
||||
}
|
||||
|
||||
if (string_is_empty(path))
|
||||
path = NULL;
|
||||
real_path[0] = '\0';
|
||||
real_core_path[0] = '\0';
|
||||
|
||||
if (!playlist)
|
||||
return false;
|
||||
|
||||
if (string_is_empty(core_path))
|
||||
{
|
||||
RARCH_ERR("cannot push NULL or empty core path into the playlist.\n");
|
||||
return false;
|
||||
}
|
||||
|
||||
/* Get 'real' path */
|
||||
if (!string_is_empty(path))
|
||||
{
|
||||
strlcpy(real_path, path, sizeof(real_path));
|
||||
path_resolve_realpath(real_path, sizeof(real_path));
|
||||
}
|
||||
|
||||
/* Get 'real' core path */
|
||||
strlcpy(real_core_path, core_path, sizeof(real_core_path));
|
||||
path_resolve_realpath(real_core_path, sizeof(real_core_path));
|
||||
|
||||
if (string_is_empty(real_core_path))
|
||||
{
|
||||
RARCH_ERR("cannot push NULL or empty core path into the playlist.\n");
|
||||
return false;
|
||||
}
|
||||
|
||||
for (i = 0; i < playlist->size; i++)
|
||||
{
|
||||
struct playlist_entry tmp;
|
||||
const char *entry_path = playlist->entries[i].path;
|
||||
bool equal_path =
|
||||
(!path && !entry_path) ||
|
||||
(path && entry_path &&
|
||||
#ifdef _WIN32
|
||||
/*prevent duplicates on case-insensitive operating systems*/
|
||||
string_is_equal_noncase(path, entry_path)
|
||||
#else
|
||||
string_is_equal(path, entry_path)
|
||||
#endif
|
||||
);
|
||||
bool equal_path =
|
||||
(string_is_empty(real_path) && string_is_empty(entry_path)) ||
|
||||
playlist_path_equal(real_path, entry_path);
|
||||
|
||||
/* Core name can have changed while still being the same core.
|
||||
* Differentiate based on the core path only. */
|
||||
if (!equal_path)
|
||||
continue;
|
||||
|
||||
if (!string_is_equal(playlist->entries[i].core_path, core_path))
|
||||
if (!playlist_core_path_equal(real_core_path, playlist->entries[i].core_path))
|
||||
continue;
|
||||
|
||||
/* If top entry, we don't want to push a new entry since
|
||||
@ -469,10 +622,10 @@ bool playlist_push_runtime(playlist_t *playlist,
|
||||
playlist->entries[0].path = NULL;
|
||||
playlist->entries[0].core_path = NULL;
|
||||
|
||||
if (!string_is_empty(path))
|
||||
playlist->entries[0].path = strdup(path);
|
||||
if (!string_is_empty(core_path))
|
||||
playlist->entries[0].core_path = strdup(core_path);
|
||||
if (!string_is_empty(real_path))
|
||||
playlist->entries[0].path = strdup(real_path);
|
||||
if (!string_is_empty(real_core_path))
|
||||
playlist->entries[0].core_path = strdup(real_core_path);
|
||||
|
||||
playlist->entries[0].runtime_hours = runtime_hours;
|
||||
playlist->entries[0].runtime_minutes = runtime_minutes;
|
||||
@ -503,53 +656,67 @@ bool playlist_push(playlist_t *playlist,
|
||||
const struct playlist_entry *entry)
|
||||
{
|
||||
size_t i;
|
||||
bool core_path_empty = string_is_empty(entry->core_path);
|
||||
bool core_name_empty = string_is_empty(entry->core_name);
|
||||
char real_path[PATH_MAX_LENGTH];
|
||||
char real_core_path[PATH_MAX_LENGTH];
|
||||
const char *core_name = entry->core_name;
|
||||
const char *path = entry->path;
|
||||
bool entry_updated = false;
|
||||
|
||||
if (core_path_empty || core_name_empty)
|
||||
real_path[0] = '\0';
|
||||
real_core_path[0] = '\0';
|
||||
|
||||
if (!playlist || !entry)
|
||||
return false;
|
||||
|
||||
if (string_is_empty(entry->core_path))
|
||||
{
|
||||
if (core_name_empty && !core_path_empty)
|
||||
{
|
||||
static char base_path[255] = {0};
|
||||
fill_pathname_base_noext(base_path, entry->core_path, sizeof(base_path));
|
||||
core_name = base_path;
|
||||
}
|
||||
RARCH_ERR("cannot push NULL or empty core path into the playlist.\n");
|
||||
return false;
|
||||
}
|
||||
|
||||
if (core_path_empty || core_name_empty)
|
||||
/* Get 'real' path */
|
||||
if (!string_is_empty(entry->path))
|
||||
{
|
||||
strlcpy(real_path, entry->path, sizeof(real_path));
|
||||
path_resolve_realpath(real_path, sizeof(real_path));
|
||||
}
|
||||
|
||||
/* Get 'real' core path */
|
||||
strlcpy(real_core_path, entry->core_path, sizeof(real_core_path));
|
||||
path_resolve_realpath(real_core_path, sizeof(real_core_path));
|
||||
|
||||
if (string_is_empty(real_core_path))
|
||||
{
|
||||
RARCH_ERR("cannot push NULL or empty core path into the playlist.\n");
|
||||
return false;
|
||||
}
|
||||
|
||||
if (string_is_empty(core_name))
|
||||
{
|
||||
static char base_path[255] = {0};
|
||||
fill_pathname_base_noext(base_path, real_core_path, sizeof(base_path));
|
||||
core_name = base_path;
|
||||
|
||||
if (string_is_empty(core_name))
|
||||
{
|
||||
RARCH_ERR("cannot push NULL or empty core name into the playlist.\n");
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
if (string_is_empty(path))
|
||||
path = NULL;
|
||||
|
||||
if (!playlist)
|
||||
return false;
|
||||
|
||||
for (i = 0; i < playlist->size; i++)
|
||||
{
|
||||
struct playlist_entry tmp;
|
||||
const char *entry_path = playlist->entries[i].path;
|
||||
bool equal_path = (!path && !entry_path) ||
|
||||
(path && entry_path &&
|
||||
#ifdef _WIN32
|
||||
/*prevent duplicates on case-insensitive operating systems*/
|
||||
string_is_equal_noncase(path, entry_path)
|
||||
#else
|
||||
string_is_equal(path, entry_path)
|
||||
#endif
|
||||
);
|
||||
bool equal_path =
|
||||
(string_is_empty(real_path) && string_is_empty(entry_path)) ||
|
||||
playlist_path_equal(real_path, entry_path);
|
||||
|
||||
/* Core name can have changed while still being the same core.
|
||||
* Differentiate based on the core path only. */
|
||||
if (!equal_path)
|
||||
continue;
|
||||
|
||||
if (!string_is_equal(playlist->entries[i].core_path, entry->core_path))
|
||||
if (!playlist_core_path_equal(real_core_path, playlist->entries[i].core_path))
|
||||
continue;
|
||||
|
||||
if ( !string_is_empty(entry->subsystem_ident)
|
||||
@ -589,7 +756,17 @@ bool playlist_push(playlist_t *playlist,
|
||||
|
||||
for (j = 0; j < entry->subsystem_roms->size; j++)
|
||||
{
|
||||
if (!string_is_equal(entry->subsystem_roms->elems[j].data, roms->elems[j].data))
|
||||
char real_rom_path[PATH_MAX_LENGTH];
|
||||
|
||||
real_rom_path[0] = '\0';
|
||||
|
||||
if (!string_is_empty(entry->subsystem_roms->elems[j].data))
|
||||
{
|
||||
strlcpy(real_rom_path, entry->subsystem_roms->elems[j].data, sizeof(real_rom_path));
|
||||
path_resolve_realpath(real_rom_path, sizeof(real_rom_path));
|
||||
}
|
||||
|
||||
if (!playlist_path_equal(real_rom_path, roms->elems[j].data))
|
||||
{
|
||||
unequal = true;
|
||||
break;
|
||||
@ -600,10 +777,35 @@ bool playlist_push(playlist_t *playlist,
|
||||
continue;
|
||||
}
|
||||
|
||||
/* If content was previously loaded via file browser
|
||||
* or command line, certain entry values will be missing.
|
||||
* If we are now loading the same content from a playlist,
|
||||
* fill in any blanks */
|
||||
if ((playlist->entries[i].label == NULL) && !string_is_empty(entry->label))
|
||||
{
|
||||
playlist->entries[i].label = strdup(entry->label);
|
||||
entry_updated = true;
|
||||
}
|
||||
if ((playlist->entries[i].crc32 == NULL) && !string_is_empty(entry->crc32))
|
||||
{
|
||||
playlist->entries[i].crc32 = strdup(entry->crc32);
|
||||
entry_updated = true;
|
||||
}
|
||||
if ((playlist->entries[i].db_name == NULL) && !string_is_empty(entry->db_name))
|
||||
{
|
||||
playlist->entries[i].db_name = strdup(entry->db_name);
|
||||
entry_updated = true;
|
||||
}
|
||||
|
||||
/* If top entry, we don't want to push a new entry since
|
||||
* the top and the entry to be pushed are the same. */
|
||||
if (i == 0)
|
||||
{
|
||||
if (entry_updated)
|
||||
goto success;
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
/* Seen it before, bump to top. */
|
||||
tmp = playlist->entries[i];
|
||||
@ -646,12 +848,12 @@ bool playlist_push(playlist_t *playlist,
|
||||
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(entry->path))
|
||||
playlist->entries[0].path = strdup(entry->path);
|
||||
if (!string_is_empty(real_path))
|
||||
playlist->entries[0].path = strdup(real_path);
|
||||
if (!string_is_empty(entry->label))
|
||||
playlist->entries[0].label = strdup(entry->label);
|
||||
if (!string_is_empty(entry->core_path))
|
||||
playlist->entries[0].core_path = strdup(entry->core_path);
|
||||
if (!string_is_empty(real_core_path))
|
||||
playlist->entries[0].core_path = strdup(real_core_path);
|
||||
if (!string_is_empty(core_name))
|
||||
playlist->entries[0].core_name = strdup(core_name);
|
||||
if (!string_is_empty(entry->db_name))
|
||||
|
Loading…
x
Reference in New Issue
Block a user