mirror of
https://github.com/libretro/RetroArch
synced 2025-01-30 03:32:46 +00:00
Adds base content directory support in playlists. If playlist base content directory does not match configuration parameter 'rgui_browser_directory', all entries paths are automatically fixed to match parameter 'rgui_browser_directory'.
Functionality is enabled if new parameter 'playlist_autofix_paths' is enabled.
This commit is contained in:
parent
a01380f847
commit
9744fcb76a
@ -1055,6 +1055,8 @@ static const int default_content_favorites_size = 200;
|
||||
|
||||
#define DEFAULT_PLAYLIST_FUZZY_ARCHIVE_MATCH false
|
||||
|
||||
#define DEFAULT_PLAYLIST_PORTABLE_PATHS false
|
||||
|
||||
/* Show Menu start-up screen on boot. */
|
||||
#define DEFAULT_MENU_SHOW_START_SCREEN true
|
||||
|
||||
|
@ -1722,6 +1722,7 @@ static struct config_bool_setting *populate_settings_bool(
|
||||
SETTING_BOOL("playlist_show_sublabels", &settings->bools.playlist_show_sublabels, true, DEFAULT_PLAYLIST_SHOW_SUBLABELS, false);
|
||||
SETTING_BOOL("playlist_sort_alphabetical", &settings->bools.playlist_sort_alphabetical, true, DEFAULT_PLAYLIST_SORT_ALPHABETICAL, false);
|
||||
SETTING_BOOL("playlist_fuzzy_archive_match", &settings->bools.playlist_fuzzy_archive_match, true, DEFAULT_PLAYLIST_FUZZY_ARCHIVE_MATCH, false);
|
||||
SETTING_BOOL("playlist_portable_paths", &settings->bools.playlist_portable_paths, true, DEFAULT_PLAYLIST_PORTABLE_PATHS, false);
|
||||
|
||||
SETTING_BOOL("quit_press_twice", &settings->bools.quit_press_twice, true, DEFAULT_QUIT_PRESS_TWICE, false);
|
||||
SETTING_BOOL("vibrate_on_keypress", &settings->bools.vibrate_on_keypress, true, vibrate_on_keypress, false);
|
||||
|
@ -404,6 +404,7 @@ typedef struct settings
|
||||
bool playlist_sort_alphabetical;
|
||||
bool playlist_show_sublabels;
|
||||
bool playlist_fuzzy_archive_match;
|
||||
bool playlist_portable_paths;
|
||||
|
||||
bool quit_press_twice;
|
||||
bool vibrate_on_keypress;
|
||||
|
47
core_info.c
47
core_info.c
@ -873,6 +873,53 @@ void core_info_list_get_supported_cores(core_info_list_t *core_info_list,
|
||||
*num_infos = supported;
|
||||
}
|
||||
|
||||
/*
|
||||
* Matches core path A and B "base" filename (ignoring everything after _libretro)
|
||||
*
|
||||
* Ex:
|
||||
* snes9x_libretro.dll and snes9x_libretro_android.so are matched
|
||||
* snes9x__2005_libretro.dll and snes9x_libretro_android.so are NOT matched
|
||||
*/
|
||||
bool core_info_core_file_id_is_equal(const char* core_path_a, const char* core_path_b)
|
||||
{
|
||||
const char *core_path_basename_a = NULL;
|
||||
const char *extension_pos = NULL;
|
||||
const char *underscore_pos = NULL;
|
||||
|
||||
if (!core_path_a || !core_path_b)
|
||||
return false;
|
||||
|
||||
core_path_basename_a = path_basename(core_path_a);
|
||||
|
||||
if (core_path_basename_a)
|
||||
{
|
||||
extension_pos = strrchr(core_path_basename_a, '.');
|
||||
|
||||
if (extension_pos)
|
||||
{
|
||||
/* Remove extension */
|
||||
*((char*)extension_pos) = '\0';
|
||||
|
||||
underscore_pos = strrchr(core_path_basename_a, '_');
|
||||
|
||||
/* Restore extension */
|
||||
*((char*)extension_pos) = '.';
|
||||
|
||||
if (underscore_pos)
|
||||
{
|
||||
size_t core_base_file_id_length = underscore_pos - core_path_basename_a;
|
||||
const char* core_path_basename_b = path_basename(core_path_b);
|
||||
|
||||
if (string_starts_with_size(core_path_basename_a, core_path_basename_b,
|
||||
core_base_file_id_length))
|
||||
return true;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
void core_info_get_name(const char *path, char *s, size_t len,
|
||||
const char *path_info, const char *dir_cores,
|
||||
const char *exts, bool dir_show_hidden_files,
|
||||
|
@ -220,6 +220,8 @@ bool core_info_get_core_lock(const char *core_path, bool validate_path);
|
||||
|
||||
core_info_state_t *coreinfo_get_ptr(void);
|
||||
|
||||
bool core_info_core_file_id_is_equal(const char* core_path_a, const char* core_path_b);
|
||||
|
||||
RETRO_END_DECLS
|
||||
|
||||
#endif /* CORE_INFO_H_ */
|
||||
|
@ -4292,6 +4292,10 @@ MSG_HASH(
|
||||
MENU_ENUM_LABEL_PLAYLIST_SUBLABEL_LAST_PLAYED_STYLE,
|
||||
"playlist_sublabel_last_played_style"
|
||||
)
|
||||
MSG_HASH(
|
||||
MENU_ENUM_LABEL_PLAYLIST_PORTABLE_PATHS,
|
||||
"playlist_portable_paths"
|
||||
)
|
||||
MSG_HASH(
|
||||
MENU_ENUM_LABEL_HELP_SEND_DEBUG_INFO,
|
||||
"help_send_debug_info"
|
||||
|
@ -4907,6 +4907,14 @@ MSG_HASH(
|
||||
MENU_ENUM_SUBLABEL_PLAYLIST_MANAGER_LIST,
|
||||
"Perform maintenance tasks on playlists."
|
||||
)
|
||||
MSG_HASH(
|
||||
MENU_ENUM_LABEL_VALUE_PLAYLIST_PORTABLE_PATHS,
|
||||
"Portable Playlists"
|
||||
)
|
||||
MSG_HASH(
|
||||
MENU_ENUM_SUBLABEL_PLAYLIST_PORTABLE_PATHS,
|
||||
"When enabled, and 'File Browser' directory is also selected, the current value of parameter 'File Browser' is saved in the playlist. When the playlist is loaded on another system where the same option is enabled, the value of parameter 'File Browser' is compared with the playlist value; if different, the playlist entries' paths are automatically fixed."
|
||||
)
|
||||
|
||||
/* Settings > Playlists > Playlist Management */
|
||||
|
||||
|
@ -2054,6 +2054,7 @@ static int action_ok_playlist_entry_collection(const char *path,
|
||||
playlist_config.old_format = settings->bools.playlist_use_old_format;
|
||||
playlist_config.compress = settings->bools.playlist_compression;
|
||||
playlist_config.fuzzy_archive_match = settings->bools.playlist_fuzzy_archive_match;
|
||||
playlist_config_set_base_content_directory(&playlist_config, settings->bools.playlist_portable_paths ? settings->paths.directory_menu_content : NULL);
|
||||
|
||||
content_path[0] = '\0';
|
||||
content_label[0] = '\0';
|
||||
@ -6207,6 +6208,7 @@ static int action_ok_manual_content_scan_start(const char *path,
|
||||
playlist_config.old_format = settings->bools.playlist_use_old_format;
|
||||
playlist_config.compress = settings->bools.playlist_compression;
|
||||
playlist_config.fuzzy_archive_match = settings->bools.playlist_fuzzy_archive_match;
|
||||
playlist_config_set_base_content_directory(&playlist_config, settings->bools.playlist_portable_paths ? settings->paths.directory_menu_content : NULL);
|
||||
|
||||
task_push_manual_content_scan(&playlist_config, directory_playlist);
|
||||
return 0;
|
||||
|
@ -850,6 +850,7 @@ DEFAULT_SUBLABEL_MACRO(action_bind_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_playlist_use_old_format, MENU_ENUM_SUBLABEL_PLAYLIST_USE_OLD_FORMAT)
|
||||
DEFAULT_SUBLABEL_MACRO(action_bind_sublabel_playlist_compression, MENU_ENUM_SUBLABEL_PLAYLIST_COMPRESSION)
|
||||
DEFAULT_SUBLABEL_MACRO(action_bind_sublabel_playlist_portable_paths, MENU_ENUM_SUBLABEL_PLAYLIST_PORTABLE_PATHS)
|
||||
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_thumbnails_updater_list, MENU_ENUM_SUBLABEL_THUMBNAILS_UPDATER_LIST)
|
||||
@ -3810,6 +3811,9 @@ int menu_cbs_init_bind_sublabel(menu_file_list_cbs_t *cbs,
|
||||
case MENU_ENUM_LABEL_PLAYLIST_FUZZY_ARCHIVE_MATCH:
|
||||
BIND_ACTION_SUBLABEL(cbs, action_bind_sublabel_playlist_fuzzy_archive_match);
|
||||
break;
|
||||
case MENU_ENUM_LABEL_PLAYLIST_PORTABLE_PATHS:
|
||||
BIND_ACTION_SUBLABEL(cbs, action_bind_sublabel_playlist_portable_paths);
|
||||
break;
|
||||
case MENU_ENUM_LABEL_PLAYLIST_USE_OLD_FORMAT:
|
||||
BIND_ACTION_SUBLABEL(cbs, action_bind_sublabel_playlist_use_old_format);
|
||||
break;
|
||||
|
@ -1671,6 +1671,7 @@ static int menu_displaylist_parse_database_entry(menu_handle_t *menu,
|
||||
playlist_config.old_format = settings->bools.playlist_use_old_format;
|
||||
playlist_config.compress = settings->bools.playlist_compression;
|
||||
playlist_config.fuzzy_archive_match = settings->bools.playlist_fuzzy_archive_match;
|
||||
playlist_config_set_base_content_directory(&playlist_config, settings->bools.playlist_portable_paths ? settings->paths.directory_menu_content : NULL);
|
||||
|
||||
path_playlist[0] = path_base[0] = query[0] = '\0';
|
||||
|
||||
@ -2312,6 +2313,7 @@ static void menu_displaylist_set_new_playlist(
|
||||
playlist_config.old_format = settings->bools.playlist_use_old_format;
|
||||
playlist_config.compress = settings->bools.playlist_compression;
|
||||
playlist_config.fuzzy_archive_match = settings->bools.playlist_fuzzy_archive_match;
|
||||
playlist_config_set_base_content_directory(&playlist_config, settings->bools.playlist_portable_paths ? settings->paths.directory_menu_content : NULL);
|
||||
|
||||
menu->db_playlist_file[0] = '\0';
|
||||
|
||||
@ -4910,6 +4912,7 @@ unsigned menu_displaylist_build_list(
|
||||
{MENU_ENUM_LABEL_OZONE_SORT_AFTER_TRUNCATE_PLAYLIST_NAME, PARSE_ONLY_BOOL, true},
|
||||
{MENU_ENUM_LABEL_CONTENT_RUNTIME_LOG, PARSE_ONLY_BOOL, true},
|
||||
{MENU_ENUM_LABEL_CONTENT_RUNTIME_LOG_AGGREGATE, PARSE_ONLY_BOOL, true},
|
||||
{MENU_ENUM_LABEL_PLAYLIST_PORTABLE_PATHS, PARSE_ONLY_BOOL, true},
|
||||
};
|
||||
|
||||
for (i = 0; i < ARRAY_SIZE(build_list); i++)
|
||||
|
@ -16234,6 +16234,22 @@ static bool setting_append_list(
|
||||
SD_FLAG_NONE
|
||||
);
|
||||
|
||||
CONFIG_BOOL(
|
||||
list, list_info,
|
||||
&settings->bools.playlist_portable_paths,
|
||||
MENU_ENUM_LABEL_PLAYLIST_PORTABLE_PATHS,
|
||||
MENU_ENUM_LABEL_VALUE_PLAYLIST_PORTABLE_PATHS,
|
||||
DEFAULT_PLAYLIST_PORTABLE_PATHS,
|
||||
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
|
||||
);
|
||||
|
||||
#ifdef HAVE_OZONE
|
||||
if (string_is_equal(settings->arrays.menu_driver, "ozone"))
|
||||
{
|
||||
|
@ -2872,6 +2872,7 @@ enum msg_hash_enums
|
||||
MENU_LABEL(PLAYLIST_FUZZY_ARCHIVE_MATCH),
|
||||
MENU_LABEL(PLAYLIST_SUBLABEL_RUNTIME_TYPE),
|
||||
MENU_LABEL(PLAYLIST_SUBLABEL_LAST_PLAYED_STYLE),
|
||||
MENU_LABEL(PLAYLIST_PORTABLE_PATHS),
|
||||
|
||||
MENU_ENUM_LABEL_VALUE_PLAYLIST_INLINE_CORE_DISPLAY_HIST_FAV,
|
||||
MENU_ENUM_LABEL_VALUE_PLAYLIST_INLINE_CORE_DISPLAY_ALWAYS,
|
||||
|
219
playlist.c
219
playlist.c
@ -34,11 +34,23 @@
|
||||
#include "playlist.h"
|
||||
#include "verbosity.h"
|
||||
#include "file_path_special.h"
|
||||
#include "core_info.h"
|
||||
|
||||
#ifndef PLAYLIST_ENTRIES
|
||||
#define PLAYLIST_ENTRIES 6
|
||||
#endif
|
||||
|
||||
#define WINDOWS_PATH_DELIMITER '\\'
|
||||
#define POSIX_PATH_DELIMITER '/'
|
||||
|
||||
#ifdef _WIN32
|
||||
#define LOCAL_FILE_SYSTEM_PATH_DELIMITER WINDOWS_PATH_DELIMITER
|
||||
#define USING_WINDOWS_FILE_SYSTEM
|
||||
#else
|
||||
#define LOCAL_FILE_SYSTEM_PATH_DELIMITER POSIX_PATH_DELIMITER
|
||||
#define USING_POSIX_FILE_SYSTEM
|
||||
#endif
|
||||
|
||||
struct content_playlist
|
||||
{
|
||||
bool modified;
|
||||
@ -54,6 +66,7 @@ struct content_playlist
|
||||
|
||||
char *default_core_path;
|
||||
char *default_core_name;
|
||||
char *base_content_directory;
|
||||
|
||||
struct playlist_entry *entries;
|
||||
playlist_config_t config;
|
||||
@ -105,6 +118,22 @@ void playlist_config_set_path(playlist_config_t *config, const char *path)
|
||||
strlcpy(config->path, path, sizeof(config->path));
|
||||
}
|
||||
|
||||
/* Convenience function: copies base content directory
|
||||
* path to specified playlist configuration object.
|
||||
* Also sets autofix_paths boolean, depending on base content directory value */
|
||||
void playlist_config_set_base_content_directory(playlist_config_t* config, const char* path)
|
||||
{
|
||||
if (!config)
|
||||
return;
|
||||
|
||||
config->autofix_paths = !string_is_empty(path);
|
||||
if (!config->autofix_paths)
|
||||
config->base_content_directory[0] = '\0';
|
||||
else
|
||||
strlcpy(config->base_content_directory, path, sizeof(config->base_content_directory));
|
||||
}
|
||||
|
||||
|
||||
/* Creates a copy of the specified playlist configuration.
|
||||
* Returns false in the event of an error */
|
||||
bool playlist_config_copy(const playlist_config_t *src, playlist_config_t *dst)
|
||||
@ -113,11 +142,13 @@ bool playlist_config_copy(const playlist_config_t *src, playlist_config_t *dst)
|
||||
return false;
|
||||
|
||||
strlcpy(dst->path, src->path, sizeof(dst->path));
|
||||
strlcpy(dst->base_content_directory, src->base_content_directory, sizeof(dst->base_content_directory));
|
||||
|
||||
dst->capacity = src->capacity;
|
||||
dst->old_format = src->old_format;
|
||||
dst->compress = src->compress;
|
||||
dst->fuzzy_archive_match = src->fuzzy_archive_match;
|
||||
dst->autofix_paths = src->autofix_paths;
|
||||
|
||||
return true;
|
||||
}
|
||||
@ -133,6 +164,43 @@ playlist_config_t *playlist_get_config(playlist_t *playlist)
|
||||
return &playlist->config;
|
||||
}
|
||||
|
||||
static void path_replace_base_path_and_convert_to_local_file_system(
|
||||
char *out_path, const char *in_path,
|
||||
const char *in_oldrefpath, const char *in_refpath,
|
||||
size_t size)
|
||||
{
|
||||
const char fs_delimeter = LOCAL_FILE_SYSTEM_PATH_DELIMITER;
|
||||
size_t in_oldrefpath_length = strlen(in_oldrefpath);
|
||||
size_t in_refpath_length = strlen(in_refpath);
|
||||
|
||||
/* If entry path is inside playlist base path,
|
||||
* replace it with new base content directory */
|
||||
if (string_starts_with_size(in_path, in_oldrefpath, in_oldrefpath_length))
|
||||
{
|
||||
memcpy(out_path, in_refpath, in_refpath_length);
|
||||
memcpy(out_path + in_refpath_length, in_path + in_oldrefpath_length,
|
||||
strlen(in_path) - in_oldrefpath_length + 1);
|
||||
|
||||
#ifdef USING_WINDOWS_FILE_SYSTEM
|
||||
/* If we are running under a win fs, '/' characters
|
||||
* are not allowed anywhere. we replace with '\' and
|
||||
* hope for the best... */
|
||||
string_replace_all_chars(out_path,
|
||||
POSIX_PATH_DELIMITER, WINDOWS_PATH_DELIMITER);
|
||||
#endif
|
||||
|
||||
#ifdef USING_POSIX_FILE_SYSTEM
|
||||
/* Under posix fs, we replace '\' characters with '/' */
|
||||
string_replace_all_chars(out_path,
|
||||
WINDOWS_PATH_DELIMITER, POSIX_PATH_DELIMITER);
|
||||
#endif
|
||||
}
|
||||
else
|
||||
{
|
||||
strlcpy(out_path, in_path, size);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* playlist_path_equal:
|
||||
* @real_path : 'Real' search path, generated by path_resolve_realpath()
|
||||
@ -228,14 +296,15 @@ static bool playlist_path_equal(const char *real_path,
|
||||
|
||||
/**
|
||||
* playlist_core_path_equal:
|
||||
* @real_core_path : 'Real' search path, generated by path_resolve_realpath()
|
||||
* @entry_core_path : Existing playlist entry 'core path' value
|
||||
* @real_core_path : 'Real' search path, generated by path_resolve_realpath()
|
||||
* @entry_core_path : Existing playlist entry 'core path' value
|
||||
* @config : Playlist config parameters
|
||||
*
|
||||
* 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)
|
||||
static bool playlist_core_path_equal(const char *real_core_path, const char *entry_core_path, const playlist_config_t *config)
|
||||
{
|
||||
char entry_real_core_path[PATH_MAX_LENGTH];
|
||||
|
||||
@ -263,6 +332,10 @@ static bool playlist_core_path_equal(const char *real_core_path, const char *ent
|
||||
return true;
|
||||
#endif
|
||||
|
||||
if (config->autofix_paths &&
|
||||
core_info_core_file_id_is_equal(real_core_path, entry_core_path))
|
||||
return true;
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
@ -699,7 +772,7 @@ bool playlist_push_runtime(playlist_t *playlist,
|
||||
if (!equal_path)
|
||||
continue;
|
||||
|
||||
if (!playlist_core_path_equal(real_core_path, playlist->entries[i].core_path))
|
||||
if (!playlist_core_path_equal(real_core_path, playlist->entries[i].core_path, &playlist->config))
|
||||
continue;
|
||||
|
||||
/* If top entry, we don't want to push a new entry since
|
||||
@ -882,7 +955,7 @@ bool playlist_push(playlist_t *playlist,
|
||||
if (!equal_path)
|
||||
continue;
|
||||
|
||||
if (!playlist_core_path_equal(real_core_path, playlist->entries[i].core_path))
|
||||
if (!playlist_core_path_equal(real_core_path, playlist->entries[i].core_path, &playlist->config))
|
||||
continue;
|
||||
|
||||
if ( !string_is_empty(entry->subsystem_ident)
|
||||
@ -1480,6 +1553,21 @@ void playlist_write_file(playlist_t *playlist)
|
||||
JSON_Writer_WriteComma(context.writer);
|
||||
json_write_new_line(context.writer);
|
||||
|
||||
if (!string_is_empty(playlist->base_content_directory))
|
||||
{
|
||||
json_write_space(context.writer, 2);
|
||||
JSON_Writer_WriteString(context.writer, "base_content_directory",
|
||||
STRLEN_CONST("base_content_directory"), JSON_UTF8);
|
||||
JSON_Writer_WriteColon(context.writer);
|
||||
json_write_space(context.writer, 1);
|
||||
JSON_Writer_WriteString(context.writer,
|
||||
playlist->base_content_directory,
|
||||
strlen(playlist->base_content_directory),
|
||||
JSON_UTF8);
|
||||
JSON_Writer_WriteComma(context.writer);
|
||||
json_write_new_line(context.writer);
|
||||
}
|
||||
|
||||
uint_str[0] = '\0';
|
||||
snprintf(uint_str, sizeof(uint_str), "%u", playlist->label_display_mode);
|
||||
|
||||
@ -1759,17 +1847,24 @@ void playlist_free(playlist_t *playlist)
|
||||
free(playlist->default_core_name);
|
||||
playlist->default_core_name = NULL;
|
||||
|
||||
for (i = 0; i < playlist->size; i++)
|
||||
if (playlist->base_content_directory != NULL)
|
||||
free(playlist->base_content_directory);
|
||||
playlist->base_content_directory = NULL;
|
||||
|
||||
if (playlist->entries)
|
||||
{
|
||||
struct playlist_entry *entry = &playlist->entries[i];
|
||||
for (i = 0; i < playlist->size; i++)
|
||||
{
|
||||
struct playlist_entry *entry = &playlist->entries[i];
|
||||
|
||||
if (entry)
|
||||
playlist_free_entry(entry);
|
||||
if (entry)
|
||||
playlist_free_entry(entry);
|
||||
}
|
||||
|
||||
free(playlist->entries);
|
||||
playlist->entries = NULL;
|
||||
}
|
||||
|
||||
free(playlist->entries);
|
||||
playlist->entries = NULL;
|
||||
|
||||
free(playlist);
|
||||
}
|
||||
|
||||
@ -2141,6 +2236,9 @@ static JSON_Parser_HandlerResult JSONObjectMemberHandler(JSON_Parser parser, cha
|
||||
pCtx->current_meta_thumbnail_mode_val = &pCtx->playlist->left_thumbnail_mode;
|
||||
else if (string_is_equal(pValue, "sort_mode"))
|
||||
pCtx->current_meta_sort_mode_val = &pCtx->playlist->sort_mode;
|
||||
else if (string_is_equal(pValue, "base_content_directory"))
|
||||
pCtx->current_meta_val = &pCtx->playlist->base_content_directory;
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -2561,27 +2659,94 @@ playlist_t *playlist_init(const playlist_config_t *config)
|
||||
goto error;
|
||||
|
||||
/* Set initial values */
|
||||
playlist->modified = false;
|
||||
playlist->old_format = false;
|
||||
playlist->compressed = false;
|
||||
playlist->size = 0;
|
||||
playlist->default_core_name = NULL;
|
||||
playlist->default_core_path = NULL;
|
||||
playlist->entries = entries;
|
||||
playlist->label_display_mode = LABEL_DISPLAY_MODE_DEFAULT;
|
||||
playlist->right_thumbnail_mode = PLAYLIST_THUMBNAIL_MODE_DEFAULT;
|
||||
playlist->left_thumbnail_mode = PLAYLIST_THUMBNAIL_MODE_DEFAULT;
|
||||
playlist->sort_mode = PLAYLIST_SORT_MODE_DEFAULT;
|
||||
playlist->modified = false;
|
||||
playlist->old_format = false;
|
||||
playlist->compressed = false;
|
||||
playlist->size = 0;
|
||||
playlist->default_core_name = NULL;
|
||||
playlist->default_core_path = NULL;
|
||||
playlist->base_content_directory = NULL;
|
||||
playlist->entries = entries;
|
||||
playlist->label_display_mode = LABEL_DISPLAY_MODE_DEFAULT;
|
||||
playlist->right_thumbnail_mode = PLAYLIST_THUMBNAIL_MODE_DEFAULT;
|
||||
playlist->left_thumbnail_mode = PLAYLIST_THUMBNAIL_MODE_DEFAULT;
|
||||
playlist->sort_mode = PLAYLIST_SORT_MODE_DEFAULT;
|
||||
|
||||
/* Attempt to read any existing playlist file */
|
||||
playlist_read_file(playlist);
|
||||
|
||||
/* Try auto-fixing paths if enabled, and playlist
|
||||
* base content directory is different */
|
||||
if (playlist->config.autofix_paths &&
|
||||
!string_is_empty(playlist->base_content_directory) &&
|
||||
!string_is_equal(playlist->base_content_directory,
|
||||
playlist->config.base_content_directory))
|
||||
{
|
||||
size_t playlist_base_content_directory_length = strlen(playlist->base_content_directory);
|
||||
size_t new_base_content_directory_length = strlen(playlist->config.base_content_directory);
|
||||
size_t i;
|
||||
size_t j;
|
||||
char tmp_entry_path[PATH_MAX_LENGTH];
|
||||
|
||||
for (i = 0; i < playlist->size; i++)
|
||||
{
|
||||
struct playlist_entry *entry = &playlist->entries[i];
|
||||
|
||||
if (!entry || string_is_empty(entry->path))
|
||||
continue;
|
||||
|
||||
/* Fix entry path */
|
||||
tmp_entry_path[0] = '\0';
|
||||
path_replace_base_path_and_convert_to_local_file_system(
|
||||
tmp_entry_path, entry->path,
|
||||
playlist->base_content_directory, playlist->config.base_content_directory,
|
||||
sizeof(tmp_entry_path));
|
||||
|
||||
free(entry->path);
|
||||
entry->path = strdup(tmp_entry_path);
|
||||
|
||||
/* Fix subsystem roms paths*/
|
||||
if (entry->subsystem_roms && (entry->subsystem_roms->size > 0))
|
||||
{
|
||||
struct string_list* subsystem_roms_new_paths = string_list_new();
|
||||
union string_list_elem_attr attributes = {0};
|
||||
|
||||
if (!subsystem_roms_new_paths)
|
||||
goto error;
|
||||
|
||||
for (j = 0; j < entry->subsystem_roms->size; j++)
|
||||
{
|
||||
const char *subsystem_rom_path = entry->subsystem_roms->elems[j].data;
|
||||
|
||||
if (string_is_empty(subsystem_rom_path))
|
||||
continue;
|
||||
|
||||
tmp_entry_path[0] = '\0';
|
||||
path_replace_base_path_and_convert_to_local_file_system(
|
||||
tmp_entry_path, subsystem_rom_path,
|
||||
playlist->base_content_directory, playlist->config.base_content_directory,
|
||||
sizeof(tmp_entry_path));
|
||||
string_list_append(subsystem_roms_new_paths, tmp_entry_path, attributes);
|
||||
}
|
||||
|
||||
string_list_free(entry->subsystem_roms);
|
||||
entry->subsystem_roms = subsystem_roms_new_paths;
|
||||
}
|
||||
}
|
||||
|
||||
/* Update playlist base content directory*/
|
||||
free(playlist->base_content_directory);
|
||||
playlist->base_content_directory = strdup(playlist->config.base_content_directory);
|
||||
|
||||
/* Save playlist */
|
||||
playlist->modified = true;
|
||||
playlist_write_file(playlist);
|
||||
}
|
||||
|
||||
return playlist;
|
||||
|
||||
error:
|
||||
if (playlist)
|
||||
free(playlist);
|
||||
|
||||
playlist_free(playlist);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
@ -2760,7 +2925,7 @@ bool playlist_entries_are_equal(
|
||||
path_resolve_realpath(real_core_path_a, sizeof(real_core_path_a), true);
|
||||
}
|
||||
|
||||
return playlist_core_path_equal(real_core_path_a, entry_b->core_path);
|
||||
return playlist_core_path_equal(real_core_path_a, entry_b->core_path, config);
|
||||
}
|
||||
|
||||
void playlist_get_crc32(playlist_t *playlist, size_t idx,
|
||||
|
@ -119,16 +119,22 @@ struct playlist_entry
|
||||
typedef struct
|
||||
{
|
||||
char path[PATH_MAX_LENGTH];
|
||||
char base_content_directory[PATH_MAX_LENGTH];
|
||||
size_t capacity;
|
||||
bool old_format;
|
||||
bool compress;
|
||||
bool fuzzy_archive_match;
|
||||
bool autofix_paths;
|
||||
} playlist_config_t;
|
||||
|
||||
/* Convenience function: copies specified playlist
|
||||
* path to specified playlist configuration object */
|
||||
void playlist_config_set_path(playlist_config_t *config, const char *path);
|
||||
|
||||
/* Convenience function: copies base content directory
|
||||
* path to specified playlist configuration object */
|
||||
void playlist_config_set_base_content_directory(playlist_config_t* config, const char* path);
|
||||
|
||||
/* Creates a copy of the specified playlist configuration.
|
||||
* Returns false in the event of an error */
|
||||
bool playlist_config_copy(const playlist_config_t *src, playlist_config_t *dst);
|
||||
|
@ -15995,6 +15995,8 @@ bool command_event(enum event_command cmd, void *data)
|
||||
playlist_config.old_format = settings->bools.playlist_use_old_format;
|
||||
playlist_config.compress = settings->bools.playlist_compression;
|
||||
playlist_config.fuzzy_archive_match = settings->bools.playlist_fuzzy_archive_match;
|
||||
/* don't use relative paths for content, music, video, and image histories */
|
||||
playlist_config_set_base_content_directory(&playlist_config, NULL);
|
||||
|
||||
command_event(CMD_EVENT_HISTORY_DEINIT, NULL);
|
||||
|
||||
@ -39625,6 +39627,7 @@ void rarch_favorites_init(void)
|
||||
playlist_config.old_format = settings ? settings->bools.playlist_use_old_format : false;
|
||||
playlist_config.compress = settings ? settings->bools.playlist_compression : false;
|
||||
playlist_config.fuzzy_archive_match = settings ? settings->bools.playlist_fuzzy_archive_match : false;
|
||||
playlist_config_set_base_content_directory(&playlist_config, NULL);
|
||||
|
||||
if (!settings)
|
||||
return;
|
||||
|
@ -1368,11 +1368,13 @@ bool task_push_dbscan(
|
||||
db->playlist_config.old_format = settings->bools.playlist_use_old_format;
|
||||
db->playlist_config.compress = settings->bools.playlist_compression;
|
||||
db->playlist_config.fuzzy_archive_match = settings->bools.playlist_fuzzy_archive_match;
|
||||
playlist_config_set_base_content_directory(&db->playlist_config, settings->bools.playlist_portable_paths ? settings->paths.directory_menu_content : NULL);
|
||||
#else
|
||||
db->playlist_config.capacity = COLLECTION_SIZE;
|
||||
db->playlist_config.old_format = false;
|
||||
db->playlist_config.compress = false;
|
||||
db->playlist_config.fuzzy_archive_match = false;
|
||||
playlist_config_set_base_content_directory(&db->playlist_config, NULL);
|
||||
#endif
|
||||
db->show_hidden_files = db_dir_show_hidden_files;
|
||||
db->is_directory = directory;
|
||||
|
@ -437,6 +437,7 @@ bool task_push_netplay_crc_scan(uint32_t crc, char* name,
|
||||
state->playlist_config.old_format = settings->bools.playlist_use_old_format;
|
||||
state->playlist_config.compress = settings->bools.playlist_compression;
|
||||
state->playlist_config.fuzzy_archive_match = settings->bools.playlist_fuzzy_archive_match;
|
||||
playlist_config_set_base_content_directory(&state->playlist_config, settings->bools.playlist_portable_paths ? settings->paths.directory_menu_content : NULL);
|
||||
|
||||
state->content_crc[0] = '\0';
|
||||
state->content_path[0] = '\0';
|
||||
|
@ -391,6 +391,7 @@ void MainWindow::addFilesToPlaylist(QStringList files)
|
||||
playlist_config.old_format = settings->bools.playlist_use_old_format;
|
||||
playlist_config.compress = settings->bools.playlist_compression;
|
||||
playlist_config.fuzzy_archive_match = settings->bools.playlist_fuzzy_archive_match;
|
||||
playlist_config_set_base_content_directory(&playlist_config, settings->bools.playlist_portable_paths ? settings->paths.directory_menu_content : NULL);
|
||||
|
||||
/* Assume a blank list means we will manually enter in all fields. */
|
||||
if (files.isEmpty())
|
||||
@ -697,6 +698,7 @@ bool MainWindow::updateCurrentPlaylistEntry(
|
||||
playlist_config.old_format = settings->bools.playlist_use_old_format;
|
||||
playlist_config.compress = settings->bools.playlist_compression;
|
||||
playlist_config.fuzzy_archive_match = settings->bools.playlist_fuzzy_archive_match;
|
||||
playlist_config_set_base_content_directory(&playlist_config, settings->bools.playlist_portable_paths ? settings->paths.directory_menu_content : NULL);
|
||||
|
||||
if ( playlistPath.isEmpty() ||
|
||||
contentHash.isEmpty() ||
|
||||
@ -825,6 +827,7 @@ void MainWindow::onPlaylistWidgetContextMenuRequested(const QPoint&)
|
||||
playlist_config.old_format = settings->bools.playlist_use_old_format;
|
||||
playlist_config.compress = settings->bools.playlist_compression;
|
||||
playlist_config.fuzzy_archive_match = settings->bools.playlist_fuzzy_archive_match;
|
||||
playlist_config_set_base_content_directory(&playlist_config, settings->bools.playlist_portable_paths ? settings->paths.directory_menu_content : NULL);
|
||||
|
||||
if (selectedItem)
|
||||
{
|
||||
@ -1361,6 +1364,7 @@ void MainWindow::deleteCurrentPlaylistItem()
|
||||
playlist_config.old_format = settings->bools.playlist_use_old_format;
|
||||
playlist_config.compress = settings->bools.playlist_compression;
|
||||
playlist_config.fuzzy_archive_match = settings->bools.playlist_fuzzy_archive_match;
|
||||
playlist_config_set_base_content_directory(&playlist_config, settings->bools.playlist_portable_paths ? settings->paths.directory_menu_content : NULL);
|
||||
|
||||
if (isAllPlaylist)
|
||||
return;
|
||||
@ -1408,6 +1412,7 @@ QString MainWindow::getPlaylistDefaultCore(QString dbName)
|
||||
playlist_config.old_format = settings->bools.playlist_use_old_format;
|
||||
playlist_config.compress = settings->bools.playlist_compression;
|
||||
playlist_config.fuzzy_archive_match = settings->bools.playlist_fuzzy_archive_match;
|
||||
playlist_config_set_base_content_directory(&playlist_config, settings->bools.playlist_portable_paths ? settings->paths.directory_menu_content : NULL);
|
||||
|
||||
playlistPath[0] = '\0';
|
||||
|
||||
@ -1478,6 +1483,7 @@ void PlaylistModel::getPlaylistItems(QString path)
|
||||
playlist_config.old_format = settings->bools.playlist_use_old_format;
|
||||
playlist_config.compress = settings->bools.playlist_compression;
|
||||
playlist_config.fuzzy_archive_match = settings->bools.playlist_fuzzy_archive_match;
|
||||
playlist_config_set_base_content_directory(&playlist_config, settings->bools.playlist_portable_paths ? settings->paths.directory_menu_content : NULL);
|
||||
|
||||
pathArray.append(path);
|
||||
pathData = pathArray.constData();
|
||||
|
Loading…
x
Reference in New Issue
Block a user