1 /* RetroArch - A frontend for libretro. 2 * Copyright (C) 2010-2014 - Hans-Kristian Arntzen 3 * Copyright (C) 2011-2017 - Daniel De Matteis 4 * Copyright (C) 2016-2019 - Brad Parker 5 * 6 * RetroArch is free software: you can redistribute it and/or modify it under the terms 7 * of the GNU General Public License as published by the Free Software Found- 8 * ation, either version 3 of the License, or (at your option) any later version. 9 * 10 * RetroArch is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; 11 * without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR 12 * PURPOSE. See the GNU General Public License for more details. 13 * 14 * You should have received a copy of the GNU General Public License along with RetroArch. 15 * If not, see <http://www.gnu.org/licenses/>. 16 */ 17 18 #ifndef _PLAYLIST_H__ 19 #define _PLAYLIST_H__ 20 21 #include <stddef.h> 22 23 #include <retro_common_api.h> 24 #include <boolean.h> 25 #include <lists/string_list.h> 26 27 #include "core_info.h" 28 29 RETRO_BEGIN_DECLS 30 31 /* Default maximum playlist size */ 32 #define COLLECTION_SIZE 0x7FFFFFFF 33 34 typedef struct content_playlist playlist_t; 35 36 enum playlist_runtime_status 37 { 38 PLAYLIST_RUNTIME_UNKNOWN = 0, 39 PLAYLIST_RUNTIME_MISSING, 40 PLAYLIST_RUNTIME_VALID 41 }; 42 43 enum playlist_file_mode 44 { 45 PLAYLIST_LOAD = 0, 46 PLAYLIST_SAVE 47 }; 48 49 enum playlist_label_display_mode 50 { 51 LABEL_DISPLAY_MODE_DEFAULT = 0, 52 LABEL_DISPLAY_MODE_REMOVE_PARENTHESES, 53 LABEL_DISPLAY_MODE_REMOVE_BRACKETS, 54 LABEL_DISPLAY_MODE_REMOVE_PARENTHESES_AND_BRACKETS, 55 LABEL_DISPLAY_MODE_KEEP_REGION, 56 LABEL_DISPLAY_MODE_KEEP_DISC_INDEX, 57 LABEL_DISPLAY_MODE_KEEP_REGION_AND_DISC_INDEX 58 }; 59 60 enum playlist_thumbnail_mode 61 { 62 PLAYLIST_THUMBNAIL_MODE_DEFAULT = 0, 63 PLAYLIST_THUMBNAIL_MODE_OFF, 64 PLAYLIST_THUMBNAIL_MODE_SCREENSHOTS, 65 PLAYLIST_THUMBNAIL_MODE_TITLE_SCREENS, 66 PLAYLIST_THUMBNAIL_MODE_BOXARTS 67 }; 68 69 enum playlist_sort_mode 70 { 71 PLAYLIST_SORT_MODE_DEFAULT = 0, 72 PLAYLIST_SORT_MODE_ALPHABETICAL, 73 PLAYLIST_SORT_MODE_OFF 74 }; 75 76 /* TODO/FIXME - since gfx_thumbnail_path.h has now 77 * been divorced from the menu code, perhaps jdgleaver 78 * can refactor this? */ 79 80 /* Note: We already have a left/right enum defined 81 * in gfx_thumbnail_path.h - but we can't include 82 * menu code here, so have to make a 'duplicate'... */ 83 enum playlist_thumbnail_id 84 { 85 PLAYLIST_THUMBNAIL_RIGHT = 0, 86 PLAYLIST_THUMBNAIL_LEFT 87 }; 88 89 /* Holds all parameters required to uniquely 90 * identify a playlist content path */ 91 typedef struct 92 { 93 char *real_path; 94 char *archive_path; 95 uint32_t real_path_hash; 96 uint32_t archive_path_hash; 97 bool is_archive; 98 bool is_in_archive; 99 } playlist_path_id_t; 100 101 struct playlist_entry 102 { 103 char *path; 104 char *label; 105 char *core_path; 106 char *core_name; 107 char *db_name; 108 char *crc32; 109 char *subsystem_ident; 110 char *subsystem_name; 111 char *runtime_str; 112 char *last_played_str; 113 struct string_list *subsystem_roms; 114 playlist_path_id_t *path_id; 115 unsigned runtime_hours; 116 unsigned runtime_minutes; 117 unsigned runtime_seconds; 118 /* Note: due to platform dependence, have to record 119 * timestamp as either a string or independent integer 120 * values. The latter is more verbose, but more efficient. */ 121 unsigned last_played_year; 122 unsigned last_played_month; 123 unsigned last_played_day; 124 unsigned last_played_hour; 125 unsigned last_played_minute; 126 unsigned last_played_second; 127 enum playlist_runtime_status runtime_status; 128 }; 129 130 /* Holds all configuration parameters required 131 * when initialising/saving playlists */ 132 typedef struct 133 { 134 size_t capacity; 135 bool old_format; 136 bool compress; 137 bool fuzzy_archive_match; 138 bool autofix_paths; 139 char path[PATH_MAX_LENGTH]; 140 char base_content_directory[PATH_MAX_LENGTH]; 141 } playlist_config_t; 142 143 /* Convenience function: copies specified playlist 144 * path to specified playlist configuration object */ 145 void playlist_config_set_path(playlist_config_t *config, const char *path); 146 147 /* Convenience function: copies base content directory 148 * path to specified playlist configuration object */ 149 void playlist_config_set_base_content_directory(playlist_config_t* config, const char* path); 150 151 /* Creates a copy of the specified playlist configuration. 152 * Returns false in the event of an error */ 153 bool playlist_config_copy(const playlist_config_t *src, playlist_config_t *dst); 154 155 /* Returns internal playlist configuration object 156 * of specified playlist. 157 * Returns NULL it the event of an error. */ 158 playlist_config_t *playlist_get_config(playlist_t *playlist); 159 160 /** 161 * playlist_init: 162 * @config : Playlist configuration object. 163 * 164 * Creates and initializes a playlist. 165 * 166 * Returns: handle to new playlist if successful, otherwise NULL 167 **/ 168 playlist_t *playlist_init(const playlist_config_t *config); 169 170 /** 171 * playlist_free: 172 * @playlist : Playlist handle. 173 * 174 * Frees playlist handle. 175 */ 176 void playlist_free(playlist_t *playlist); 177 178 /** 179 * playlist_clear: 180 * @playlist : Playlist handle. 181 * 182 * Clears all playlist entries in playlist. 183 **/ 184 void playlist_clear(playlist_t *playlist); 185 186 /** 187 * playlist_size: 188 * @playlist : Playlist handle. 189 * 190 * Gets size of playlist. 191 * Returns: size of playlist. 192 **/ 193 size_t playlist_size(playlist_t *playlist); 194 195 /** 196 * playlist_capacity: 197 * @playlist : Playlist handle. 198 * 199 * Gets maximum capacity of playlist. 200 * Returns: maximum capacity of playlist. 201 **/ 202 size_t playlist_capacity(playlist_t *playlist); 203 204 /** 205 * playlist_get_index: 206 * @playlist : Playlist handle. 207 * @idx : Index of playlist entry. 208 * 209 * Gets values of playlist index: 210 **/ 211 void playlist_get_index(playlist_t *playlist, 212 size_t idx, 213 const struct playlist_entry **entry); 214 215 /** 216 * playlist_delete_index: 217 * @playlist : Playlist handle. 218 * @idx : Index of playlist entry. 219 * 220 * Deletes the entry at index: 221 **/ 222 void playlist_delete_index(playlist_t *playlist, 223 size_t idx); 224 225 /** 226 * playlist_delete_by_path: 227 * @playlist : Playlist handle. 228 * @search_path : Content path. 229 * 230 * Deletes all entries with content path 231 * matching 'search_path' 232 **/ 233 void playlist_delete_by_path(playlist_t *playlist, 234 const char *search_path); 235 236 /** 237 * playlist_resolve_path: 238 * @mode : PLAYLIST_LOAD or PLAYLIST_SAVE 239 * @is_core : Set true if path to be resolved is a core file 240 * @path : The path to be modified 241 * 242 * Resolves the path of an item, such as the content path or path to the core, to a format 243 * appropriate for saving or loading depending on the @mode parameter 244 * 245 * Can be platform specific. File paths for saving can be abbreviated to avoid saving absolute 246 * paths, as the base directory (home or application dir) may change after each subsequent 247 * install (iOS) 248 **/ 249 void playlist_resolve_path(enum playlist_file_mode mode, 250 bool is_core, char *path, size_t len); 251 252 /** 253 * playlist_push: 254 * @playlist : Playlist handle. 255 * 256 * Push entry to top of playlist. 257 **/ 258 bool playlist_push(playlist_t *playlist, 259 const struct playlist_entry *entry); 260 261 bool playlist_push_runtime(playlist_t *playlist, 262 const struct playlist_entry *entry); 263 264 void playlist_update(playlist_t *playlist, size_t idx, 265 const struct playlist_entry *update_entry); 266 267 /* Note: register_update determines whether the internal 268 * 'playlist->modified' flag is set when updating runtime 269 * values. Since these are normally set temporarily (for 270 * display purposes), we do not always want this function 271 * to trigger a re-write of the playlist file. */ 272 void playlist_update_runtime(playlist_t *playlist, size_t idx, 273 const struct playlist_entry *update_entry, 274 bool register_update); 275 276 void playlist_get_index_by_path(playlist_t *playlist, 277 const char *search_path, 278 const struct playlist_entry **entry); 279 280 bool playlist_entry_exists(playlist_t *playlist, 281 const char *path); 282 283 char *playlist_get_conf_path(playlist_t *playlist); 284 285 uint32_t playlist_get_size(playlist_t *playlist); 286 287 void playlist_write_file(playlist_t *playlist); 288 289 void playlist_write_runtime_file(playlist_t *playlist); 290 291 void playlist_qsort(playlist_t *playlist); 292 293 void playlist_free_cached(void); 294 295 playlist_t *playlist_get_cached(void); 296 297 /* If current on-disk playlist file referenced 298 * by 'config->path' does not match requested 299 * 'old format' or 'compression' state, file will 300 * be updated automatically 301 * > Since this function is called whenever a 302 * playlist is browsed via the menu, this is 303 * a simple method for ensuring that files 304 * are always kept synced with user settings */ 305 bool playlist_init_cached(const playlist_config_t *config); 306 307 void command_playlist_push_write( 308 playlist_t *playlist, 309 const struct playlist_entry *entry); 310 311 void command_playlist_update_write( 312 playlist_t *playlist, 313 size_t idx, 314 const struct playlist_entry *entry); 315 316 /* Returns true if specified playlist index matches 317 * specified content/core paths */ 318 bool playlist_index_is_valid(playlist_t *playlist, size_t idx, 319 const char *path, const char *core_path); 320 321 /* Returns true if specified playlist entries have 322 * identical content and core paths */ 323 bool playlist_entries_are_equal( 324 const struct playlist_entry *entry_a, 325 const struct playlist_entry *entry_b, 326 const playlist_config_t *config); 327 328 /* Returns true if entries at specified indices 329 * of specified playlist have identical content 330 * and core paths */ 331 bool playlist_index_entries_are_equal( 332 playlist_t *playlist, size_t idx_a, size_t idx_b); 333 334 void playlist_get_crc32(playlist_t *playlist, size_t idx, 335 const char **crc32); 336 337 /* If db_name is empty, 'returns' playlist file basename */ 338 void playlist_get_db_name(playlist_t *playlist, size_t idx, 339 const char **db_name); 340 341 char *playlist_get_default_core_path(playlist_t *playlist); 342 char *playlist_get_default_core_name(playlist_t *playlist); 343 enum playlist_label_display_mode playlist_get_label_display_mode(playlist_t *playlist); 344 enum playlist_thumbnail_mode playlist_get_thumbnail_mode( 345 playlist_t *playlist, enum playlist_thumbnail_id thumbnail_id); 346 enum playlist_sort_mode playlist_get_sort_mode(playlist_t *playlist); 347 348 void playlist_set_default_core_path(playlist_t *playlist, const char *core_path); 349 void playlist_set_default_core_name(playlist_t *playlist, const char *core_name); 350 void playlist_set_label_display_mode(playlist_t *playlist, enum playlist_label_display_mode label_display_mode); 351 void playlist_set_thumbnail_mode( 352 playlist_t *playlist, enum playlist_thumbnail_id thumbnail_id, enum playlist_thumbnail_mode thumbnail_mode); 353 void playlist_set_sort_mode(playlist_t *playlist, enum playlist_sort_mode sort_mode); 354 355 /* Returns true if specified entry has a valid 356 * core association (i.e. a non-empty string 357 * other than DETECT) */ 358 bool playlist_entry_has_core(const struct playlist_entry *entry); 359 360 /* Fetches core info object corresponding to the 361 * currently associated core of the specified 362 * playlist entry. 363 * Returns NULL if entry does not have a valid 364 * core association */ 365 core_info_t *playlist_entry_get_core_info(const struct playlist_entry* entry); 366 367 /* Fetches core info object corresponding to the 368 * currently associated default core of the 369 * specified playlist. 370 * Returns NULL if playlist does not have a valid 371 * default core association */ 372 core_info_t *playlist_get_default_core_info(playlist_t* playlist); 373 374 void playlist_set_cached_external(playlist_t* pl); 375 376 RETRO_END_DECLS 377 378 #endif 379