/* RetroArch - A frontend for libretro.
* Copyright (C) 2010-2014 - Hans-Kristian Arntzen
* Copyright (C) 2011-2017 - Daniel De Matteis
* Copyright (C) 2016-2019 - Brad Parker
*
* RetroArch is free software: you can redistribute it and/or modify it under the terms
* of the GNU General Public License as published by the Free Software Found-
* ation, either version 3 of the License, or (at your option) any later version.
*
* RetroArch is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY;
* without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
* PURPOSE. See the GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License along with RetroArch.
* If not, see .
*/
#ifndef _PLAYLIST_H__
#define _PLAYLIST_H__
#include
#include
#include
#include
#include "core_info.h"
/* Default maximum playlist size */
#define COLLECTION_SIZE 0x7FFFFFFF
RETRO_BEGIN_DECLS
enum playlist_runtime_status
{
PLAYLIST_RUNTIME_UNKNOWN = 0,
PLAYLIST_RUNTIME_MISSING,
PLAYLIST_RUNTIME_VALID
};
enum playlist_file_mode
{
PLAYLIST_LOAD = 0,
PLAYLIST_SAVE
};
enum playlist_label_display_mode
{
LABEL_DISPLAY_MODE_DEFAULT = 0,
LABEL_DISPLAY_MODE_REMOVE_PARENTHESES,
LABEL_DISPLAY_MODE_REMOVE_BRACKETS,
LABEL_DISPLAY_MODE_REMOVE_PARENTHESES_AND_BRACKETS,
LABEL_DISPLAY_MODE_KEEP_REGION,
LABEL_DISPLAY_MODE_KEEP_DISC_INDEX,
LABEL_DISPLAY_MODE_KEEP_REGION_AND_DISC_INDEX
};
enum playlist_thumbnail_mode
{
PLAYLIST_THUMBNAIL_MODE_DEFAULT = 0,
PLAYLIST_THUMBNAIL_MODE_OFF,
PLAYLIST_THUMBNAIL_MODE_SCREENSHOTS,
PLAYLIST_THUMBNAIL_MODE_TITLE_SCREENS,
PLAYLIST_THUMBNAIL_MODE_BOXARTS,
PLAYLIST_THUMBNAIL_MODE_LOGOS
};
enum playlist_thumbnail_match_mode
{
PLAYLIST_THUMBNAIL_MATCH_MODE_DEFAULT = 0,
PLAYLIST_THUMBNAIL_MATCH_MODE_WITH_LABEL = PLAYLIST_THUMBNAIL_MATCH_MODE_DEFAULT,
PLAYLIST_THUMBNAIL_MATCH_MODE_WITH_FILENAME
};
enum playlist_sort_mode
{
PLAYLIST_SORT_MODE_DEFAULT = 0,
PLAYLIST_SORT_MODE_ALPHABETICAL,
PLAYLIST_SORT_MODE_OFF
};
/* Note: We already have a left/right enum defined
* in gfx_thumbnail_path.h - but we can't include
* menu code here, so have to make a 'duplicate'... */
enum playlist_thumbnail_id
{
PLAYLIST_THUMBNAIL_RIGHT = 0,
PLAYLIST_THUMBNAIL_LEFT,
PLAYLIST_THUMBNAIL_ICON
};
enum playlist_thumbnail_name_flags
{
PLAYLIST_THUMBNAIL_FLAG_INVALID = 0,
PLAYLIST_THUMBNAIL_FLAG_FULL_NAME = (1 << 0),
PLAYLIST_THUMBNAIL_FLAG_STD_NAME = (1 << 1),
PLAYLIST_THUMBNAIL_FLAG_SHORT_NAME = (1 << 2),
PLAYLIST_THUMBNAIL_FLAG_NONE = (1 << 3)
};
typedef struct content_playlist playlist_t;
/* Holds all parameters required to uniquely
* identify a playlist content path */
typedef struct
{
char *real_path;
char *archive_path;
uint32_t real_path_hash;
uint32_t archive_path_hash;
bool is_archive;
bool is_in_archive;
} playlist_path_id_t;
struct playlist_entry
{
char *path;
char *label;
char *core_path;
char *core_name;
char *db_name;
char *crc32;
char *subsystem_ident;
char *subsystem_name;
char *runtime_str;
char *last_played_str;
struct string_list *subsystem_roms;
playlist_path_id_t *path_id;
unsigned entry_slot;
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;
enum playlist_runtime_status runtime_status;
enum playlist_thumbnail_name_flags thumbnail_flags;
};
/* Holds all configuration parameters required
* when initialising/saving playlists */
typedef struct
{
size_t capacity;
bool old_format;
bool compress;
bool fuzzy_archive_match;
bool autofix_paths;
char path[PATH_MAX_LENGTH];
char base_content_directory[DIR_MAX_LENGTH];
} 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);
/* Returns internal playlist configuration object
* of specified playlist.
* Returns NULL it the event of an error. */
playlist_config_t *playlist_get_config(playlist_t *playlist);
/**
* playlist_init:
* @config : Playlist configuration object.
*
* Creates and initializes a playlist.
*
* Returns: handle to new playlist if successful, otherwise NULL
**/
playlist_t *playlist_init(const playlist_config_t *config);
/**
* playlist_free:
* @playlist : Playlist handle.
*
* Frees playlist handle.
*/
void playlist_free(playlist_t *playlist);
/**
* playlist_clear:
* @playlist : Playlist handle.
*
* Clears all playlist entries in playlist.
**/
void playlist_clear(playlist_t *playlist);
/**
* playlist_size:
* @playlist : Playlist handle.
*
* Gets size of playlist.
* Returns: size of playlist.
**/
size_t playlist_size(playlist_t *playlist);
/**
* playlist_capacity:
* @playlist : Playlist handle.
*
* Gets maximum capacity of playlist.
* Returns: maximum capacity of playlist.
**/
size_t playlist_capacity(playlist_t *playlist);
/**
* playlist_get_index:
* @playlist : Playlist handle.
* @idx : Index of playlist entry.
*
* Gets values of playlist index:
**/
void playlist_get_index(playlist_t *playlist,
size_t idx,
const struct playlist_entry **entry);
/**
* playlist_delete_index:
* @playlist : Playlist handle.
* @idx : Index of playlist entry.
*
* Deletes the entry at index:
**/
void playlist_delete_index(playlist_t *playlist,
size_t idx);
/**
* playlist_delete_by_path:
* @playlist : Playlist handle.
* @search_path : Content path.
*
* Deletes all entries with content path
* matching 'search_path'
**/
void playlist_delete_by_path(playlist_t *playlist,
const char *search_path);
/**
* playlist_resolve_path:
* @mode : PLAYLIST_LOAD or PLAYLIST_SAVE
* @is_core : Set true if path to be resolved is a core file
* @path : The path to be modified
*
* Resolves the path of an item, such as the content path or path to the core, to a format
* appropriate for saving or loading depending on the @mode parameter
*
* Can be platform specific. File paths for saving can be abbreviated to avoid saving absolute
* paths, as the base directory (home or application dir) may change after each subsequent
* install (iOS)
**/
void playlist_resolve_path(enum playlist_file_mode mode,
bool is_core, char *path, size_t len);
/**
* playlist_content_path_is_valid:
* @path : Content path
*
* Checks whether specified playlist content path
* refers to an existent file. Handles all playlist
* content path 'types' (i.e. can validate paths
* referencing files inside archives).
*
* Returns true if file referenced by content
* path exists on the host filesystem.
**/
bool playlist_content_path_is_valid(const char *path);
/**
* playlist_push:
* @playlist : Playlist handle.
*
* Push entry to top of playlist.
**/
bool playlist_push(playlist_t *playlist,
const struct playlist_entry *entry);
bool playlist_push_runtime(playlist_t *playlist,
const struct playlist_entry *entry);
void playlist_update(playlist_t *playlist, size_t idx,
const struct playlist_entry *update_entry);
/* 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 struct playlist_entry *update_entry,
bool register_update);
void playlist_update_thumbnail_name_flag(playlist_t *playlist, size_t idx,
enum playlist_thumbnail_name_flags thumbnail_flags);
enum playlist_thumbnail_name_flags playlist_get_next_thumbnail_name_flag(playlist_t *playlist, size_t idx);
enum playlist_thumbnail_name_flags playlist_get_curr_thumbnail_name_flag(playlist_t *playlist, size_t idx);
void playlist_get_index_by_path(playlist_t *playlist,
const char *search_path,
const struct playlist_entry **entry);
bool playlist_entry_exists(playlist_t *playlist,
const char *path);
char *playlist_get_conf_path(playlist_t *playlist);
uint32_t playlist_get_size(playlist_t *playlist);
void playlist_write_file(playlist_t *playlist);
void playlist_write_runtime_file(playlist_t *playlist);
void playlist_qsort(playlist_t *playlist);
void playlist_free_cached(void);
playlist_t *playlist_get_cached(void);
/* If current on-disk playlist file referenced
* by 'config->path' does not match requested
* 'old format' or 'compression' state, file will
* be updated automatically
* > Since this function is called whenever a
* playlist is browsed via the menu, this is
* a simple method for ensuring that files
* are always kept synced with user settings */
bool playlist_init_cached(const playlist_config_t *config);
void command_playlist_push_write(
playlist_t *playlist,
const struct playlist_entry *entry);
void command_playlist_update_write(
playlist_t *playlist,
size_t idx,
const struct playlist_entry *entry);
/* Returns true if specified playlist index matches
* specified content/core paths */
bool playlist_index_is_valid(playlist_t *playlist, size_t idx,
const char *path, const char *core_path);
/* Returns true if specified playlist entries have
* identical content and core paths */
bool playlist_entries_are_equal(
const struct playlist_entry *entry_a,
const struct playlist_entry *entry_b,
const playlist_config_t *config);
/* Returns true if entries at specified indices
* of specified playlist have identical content
* and core paths */
bool playlist_index_entries_are_equal(
playlist_t *playlist, size_t idx_a, size_t idx_b);
void playlist_get_crc32(playlist_t *playlist, size_t idx,
const char **crc32);
/* If db_name is empty, 'returns' playlist file basename */
void playlist_get_db_name(playlist_t *playlist, size_t idx,
const char **db_name);
const char *playlist_get_default_core_path(playlist_t *playlist);
const char *playlist_get_default_core_name(playlist_t *playlist);
enum playlist_label_display_mode playlist_get_label_display_mode(playlist_t *playlist);
enum playlist_thumbnail_mode playlist_get_thumbnail_mode(
playlist_t *playlist, enum playlist_thumbnail_id thumbnail_id);
bool playlist_thumbnail_match_with_filename(playlist_t *playlist);
enum playlist_sort_mode playlist_get_sort_mode(playlist_t *playlist);
const char *playlist_get_scan_content_dir(playlist_t *playlist);
const char *playlist_get_scan_file_exts(playlist_t *playlist);
const char *playlist_get_scan_dat_file_path(playlist_t *playlist);
bool playlist_get_scan_search_recursively(playlist_t *playlist);
bool playlist_get_scan_search_archives(playlist_t *playlist);
bool playlist_get_scan_filter_dat_content(playlist_t *playlist);
bool playlist_get_scan_overwrite_playlist(playlist_t *playlist);
bool playlist_scan_refresh_enabled(playlist_t *playlist);
void playlist_set_default_core_path(playlist_t *playlist, const char *core_path);
void playlist_set_default_core_name(playlist_t *playlist, const char *core_name);
void playlist_set_label_display_mode(playlist_t *playlist, enum playlist_label_display_mode label_display_mode);
void playlist_set_thumbnail_mode(
playlist_t *playlist, enum playlist_thumbnail_id thumbnail_id, enum playlist_thumbnail_mode thumbnail_mode);
void playlist_set_sort_mode(playlist_t *playlist, enum playlist_sort_mode sort_mode);
void playlist_set_scan_content_dir(playlist_t *playlist, const char *content_dir);
void playlist_set_scan_file_exts(playlist_t *playlist, const char *file_exts);
void playlist_set_scan_dat_file_path(playlist_t *playlist, const char *dat_file_path);
void playlist_set_scan_search_recursively(playlist_t *playlist, bool search_recursively);
void playlist_set_scan_search_archives(playlist_t *playlist, bool search_archives);
void playlist_set_scan_filter_dat_content(playlist_t *playlist, bool filter_dat_content);
void playlist_set_scan_overwrite_playlist(playlist_t *playlist, bool overwrite_playlist);
/* Returns true if specified entry has a valid
* core association (i.e. a non-empty string
* other than DETECT) */
bool playlist_entry_has_core(const struct playlist_entry *entry);
/* Fetches core info object corresponding to the
* currently associated core of the specified
* playlist entry.
* Returns NULL if entry does not have a valid
* core association */
core_info_t *playlist_entry_get_core_info(const struct playlist_entry* entry);
/* Fetches core info object corresponding to the
* currently associated default core of the
* specified playlist.
* Returns NULL if playlist does not have a valid
* default core association */
core_info_t *playlist_get_default_core_info(playlist_t* playlist);
void playlist_set_cached_external(playlist_t* pl);
RETRO_END_DECLS
#endif