mirror of
https://github.com/libretro/RetroArch
synced 2025-04-16 08:43:10 +00:00
Merge pull request #9795 from jdgleaver/manual-scan
Add manual content scanner
This commit is contained in:
commit
00ca7297f3
@ -163,6 +163,7 @@ OBJ += frontend/frontend_driver.o \
|
|||||||
tasks/task_file_transfer.o \
|
tasks/task_file_transfer.o \
|
||||||
tasks/task_image.o \
|
tasks/task_image.o \
|
||||||
tasks/task_playlist_manager.o \
|
tasks/task_playlist_manager.o \
|
||||||
|
tasks/task_manual_content_scan.o \
|
||||||
$(LIBRETRO_COMM_DIR)/encodings/encoding_utf.o \
|
$(LIBRETRO_COMM_DIR)/encodings/encoding_utf.o \
|
||||||
$(LIBRETRO_COMM_DIR)/encodings/encoding_crc32.o \
|
$(LIBRETRO_COMM_DIR)/encodings/encoding_crc32.o \
|
||||||
$(LIBRETRO_COMM_DIR)/encodings/encoding_base64.o \
|
$(LIBRETRO_COMM_DIR)/encodings/encoding_base64.o \
|
||||||
@ -258,8 +259,8 @@ OBJ += \
|
|||||||
performance_counters.o \
|
performance_counters.o \
|
||||||
verbosity.o \
|
verbosity.o \
|
||||||
midi/drivers/null_midi.o \
|
midi/drivers/null_midi.o \
|
||||||
$(LIBRETRO_COMM_DIR)/playlists/label_sanitization.o
|
$(LIBRETRO_COMM_DIR)/playlists/label_sanitization.o \
|
||||||
|
manual_content_scan.o
|
||||||
|
|
||||||
ifeq ($(HAVE_AUDIOMIXER), 1)
|
ifeq ($(HAVE_AUDIOMIXER), 1)
|
||||||
DEFINES += -DHAVE_AUDIOMIXER
|
DEFINES += -DHAVE_AUDIOMIXER
|
||||||
|
@ -79,6 +79,7 @@ enum file_path_enum
|
|||||||
FILE_PATH_LPL_EXTENSION,
|
FILE_PATH_LPL_EXTENSION,
|
||||||
FILE_PATH_LPL_EXTENSION_NO_DOT,
|
FILE_PATH_LPL_EXTENSION_NO_DOT,
|
||||||
FILE_PATH_RDB_EXTENSION,
|
FILE_PATH_RDB_EXTENSION,
|
||||||
|
FILE_PATH_RDB_EXTENSION_NO_DOT,
|
||||||
FILE_PATH_BSV_EXTENSION,
|
FILE_PATH_BSV_EXTENSION,
|
||||||
FILE_PATH_AUTO_EXTENSION,
|
FILE_PATH_AUTO_EXTENSION,
|
||||||
FILE_PATH_ZIP_EXTENSION,
|
FILE_PATH_ZIP_EXTENSION,
|
||||||
|
@ -130,6 +130,9 @@ const char *file_path_str(enum file_path_enum enum_idx)
|
|||||||
case FILE_PATH_RDB_EXTENSION:
|
case FILE_PATH_RDB_EXTENSION:
|
||||||
str = ".rdb";
|
str = ".rdb";
|
||||||
break;
|
break;
|
||||||
|
case FILE_PATH_RDB_EXTENSION_NO_DOT:
|
||||||
|
str = "rdb";
|
||||||
|
break;
|
||||||
case FILE_PATH_ZIP_EXTENSION:
|
case FILE_PATH_ZIP_EXTENSION:
|
||||||
str = ".zip";
|
str = ".zip";
|
||||||
break;
|
break;
|
||||||
|
@ -1205,6 +1205,7 @@ DATA RUNLOOP
|
|||||||
#include "../tasks/task_image.c"
|
#include "../tasks/task_image.c"
|
||||||
#include "../tasks/task_file_transfer.c"
|
#include "../tasks/task_file_transfer.c"
|
||||||
#include "../tasks/task_playlist_manager.c"
|
#include "../tasks/task_playlist_manager.c"
|
||||||
|
#include "../tasks/task_manual_content_scan.c"
|
||||||
#ifdef HAVE_ZLIB
|
#ifdef HAVE_ZLIB
|
||||||
#include "../tasks/task_decompress.c"
|
#include "../tasks/task_decompress.c"
|
||||||
#endif
|
#endif
|
||||||
@ -1634,3 +1635,8 @@ SSL
|
|||||||
PLAYLIST NAME SANITIZATION
|
PLAYLIST NAME SANITIZATION
|
||||||
============================================================ */
|
============================================================ */
|
||||||
#include "../libretro-common/playlists/label_sanitization.c"
|
#include "../libretro-common/playlists/label_sanitization.c"
|
||||||
|
|
||||||
|
/*============================================================
|
||||||
|
MANUAL CONTENT SCAN
|
||||||
|
============================================================ */
|
||||||
|
#include "../manual_content_scan.c"
|
||||||
|
@ -2105,3 +2105,25 @@ MSG_HASH(MENU_ENUM_LABEL_DRIVER_SWITCH_ENABLE,
|
|||||||
"driver_switch_enable")
|
"driver_switch_enable")
|
||||||
MSG_HASH(MENU_ENUM_LABEL_AI_SERVICE_PAUSE,
|
MSG_HASH(MENU_ENUM_LABEL_AI_SERVICE_PAUSE,
|
||||||
"ai_service_pause")
|
"ai_service_pause")
|
||||||
|
MSG_HASH(MENU_ENUM_LABEL_DEFERRED_MANUAL_CONTENT_SCAN_LIST,
|
||||||
|
"deferred_manual_content_scan_list")
|
||||||
|
MSG_HASH(MENU_ENUM_LABEL_MANUAL_CONTENT_SCAN_LIST,
|
||||||
|
"manual_content_scan_list")
|
||||||
|
MSG_HASH(MENU_ENUM_LABEL_MANUAL_CONTENT_SCAN_DIR,
|
||||||
|
"manual_content_scan_dir")
|
||||||
|
MSG_HASH(MENU_ENUM_LABEL_MANUAL_CONTENT_SCAN_SYSTEM_NAME,
|
||||||
|
"manual_content_scan_system_name")
|
||||||
|
MSG_HASH(MENU_ENUM_LABEL_DEFERRED_DROPDOWN_BOX_LIST_MANUAL_CONTENT_SCAN_SYSTEM_NAME,
|
||||||
|
"deferred_dropdown_box_list_manual_content_scan_system_name")
|
||||||
|
MSG_HASH(MENU_ENUM_LABEL_MANUAL_CONTENT_SCAN_SYSTEM_NAME_CUSTOM,
|
||||||
|
"manual_content_scan_system_name_custom")
|
||||||
|
MSG_HASH(MENU_ENUM_LABEL_MANUAL_CONTENT_SCAN_CORE_NAME,
|
||||||
|
"manual_content_scan_core_name")
|
||||||
|
MSG_HASH(MENU_ENUM_LABEL_DEFERRED_DROPDOWN_BOX_LIST_MANUAL_CONTENT_SCAN_CORE_NAME,
|
||||||
|
"deferred_dropdown_box_list_manual_content_scan_core_name")
|
||||||
|
MSG_HASH(MENU_ENUM_LABEL_MANUAL_CONTENT_SCAN_FILE_EXTS,
|
||||||
|
"manual_content_scan_file_exts")
|
||||||
|
MSG_HASH(MENU_ENUM_LABEL_MANUAL_CONTENT_SCAN_OVERWRITE,
|
||||||
|
"manual_content_scan_overwrite")
|
||||||
|
MSG_HASH(MENU_ENUM_LABEL_MANUAL_CONTENT_SCAN_START,
|
||||||
|
"manual_content_scan_start")
|
||||||
|
@ -10040,3 +10040,99 @@ MSG_HASH(
|
|||||||
MENU_ENUM_SUBLABEL_AI_SERVICE_PAUSE,
|
MENU_ENUM_SUBLABEL_AI_SERVICE_PAUSE,
|
||||||
"Pauses core while screen is translated."
|
"Pauses core while screen is translated."
|
||||||
)
|
)
|
||||||
|
MSG_HASH(
|
||||||
|
MENU_ENUM_LABEL_VALUE_MANUAL_CONTENT_SCAN_LIST,
|
||||||
|
"Manual Scan"
|
||||||
|
)
|
||||||
|
MSG_HASH(
|
||||||
|
MENU_ENUM_SUBLABEL_MANUAL_CONTENT_SCAN_LIST,
|
||||||
|
"Configurable scan based on content file names. Does not require content to match the database."
|
||||||
|
)
|
||||||
|
MSG_HASH(
|
||||||
|
MENU_ENUM_LABEL_VALUE_MANUAL_CONTENT_SCAN_DIR,
|
||||||
|
"Content Directory"
|
||||||
|
)
|
||||||
|
MSG_HASH(
|
||||||
|
MENU_ENUM_SUBLABEL_MANUAL_CONTENT_SCAN_DIR,
|
||||||
|
"Selects a directory to scan for content."
|
||||||
|
)
|
||||||
|
MSG_HASH(
|
||||||
|
MENU_ENUM_LABEL_VALUE_MANUAL_CONTENT_SCAN_SYSTEM_NAME,
|
||||||
|
"System Name"
|
||||||
|
)
|
||||||
|
MSG_HASH(
|
||||||
|
MENU_ENUM_SUBLABEL_MANUAL_CONTENT_SCAN_SYSTEM_NAME,
|
||||||
|
"Specify a 'system name' with which to associate scanned content. Used to name to the generated playlist file and to identify playlist thumbnails."
|
||||||
|
)
|
||||||
|
MSG_HASH(
|
||||||
|
MENU_ENUM_LABEL_VALUE_MANUAL_CONTENT_SCAN_SYSTEM_NAME_CUSTOM,
|
||||||
|
"Custom System Name"
|
||||||
|
)
|
||||||
|
MSG_HASH(
|
||||||
|
MENU_ENUM_SUBLABEL_MANUAL_CONTENT_SCAN_SYSTEM_NAME_CUSTOM,
|
||||||
|
"Manually specify a 'system name' for scanned content. Only used when 'System Name' is set to '<Custom>'."
|
||||||
|
)
|
||||||
|
MSG_HASH(
|
||||||
|
MENU_ENUM_LABEL_VALUE_MANUAL_CONTENT_SCAN_CORE_NAME,
|
||||||
|
"Core"
|
||||||
|
)
|
||||||
|
MSG_HASH(
|
||||||
|
MENU_ENUM_SUBLABEL_MANUAL_CONTENT_SCAN_CORE_NAME,
|
||||||
|
"Select a default core to use when launching scanned content."
|
||||||
|
)
|
||||||
|
MSG_HASH(
|
||||||
|
MENU_ENUM_LABEL_VALUE_MANUAL_CONTENT_SCAN_FILE_EXTS,
|
||||||
|
"File Extensions"
|
||||||
|
)
|
||||||
|
MSG_HASH(
|
||||||
|
MENU_ENUM_SUBLABEL_MANUAL_CONTENT_SCAN_FILE_EXTS,
|
||||||
|
"Space-delimited list of file types to include in the scan. If empty, includes all files - or if a core is specified, all files supported by the core."
|
||||||
|
)
|
||||||
|
MSG_HASH(
|
||||||
|
MENU_ENUM_LABEL_VALUE_MANUAL_CONTENT_SCAN_OVERWRITE,
|
||||||
|
"Overwrite Existing Playlist"
|
||||||
|
)
|
||||||
|
MSG_HASH(
|
||||||
|
MENU_ENUM_SUBLABEL_MANUAL_CONTENT_SCAN_OVERWRITE,
|
||||||
|
"When enabled, any existing playlist will be deleted before scanning content. When disabled, existing playlist entries are preserved and only content currently missing from the playlist will be added."
|
||||||
|
)
|
||||||
|
MSG_HASH(
|
||||||
|
MENU_ENUM_LABEL_VALUE_MANUAL_CONTENT_SCAN_START,
|
||||||
|
"Start Scan"
|
||||||
|
)
|
||||||
|
MSG_HASH(
|
||||||
|
MENU_ENUM_SUBLABEL_MANUAL_CONTENT_SCAN_START,
|
||||||
|
"Scan selected content."
|
||||||
|
)
|
||||||
|
MSG_HASH(
|
||||||
|
MENU_ENUM_LABEL_VALUE_MANUAL_CONTENT_SCAN_SYSTEM_NAME_USE_CONTENT_DIR,
|
||||||
|
"<Content Directory>"
|
||||||
|
)
|
||||||
|
MSG_HASH(
|
||||||
|
MENU_ENUM_LABEL_VALUE_MANUAL_CONTENT_SCAN_SYSTEM_NAME_USE_CUSTOM,
|
||||||
|
"<Custom>"
|
||||||
|
)
|
||||||
|
MSG_HASH(
|
||||||
|
MENU_ENUM_LABEL_VALUE_MANUAL_CONTENT_SCAN_CORE_NAME_DETECT,
|
||||||
|
"<Unspecified>"
|
||||||
|
)
|
||||||
|
MSG_HASH(
|
||||||
|
MSG_MANUAL_CONTENT_SCAN_INVALID_CONFIG,
|
||||||
|
"Invalid manual scan configuration"
|
||||||
|
)
|
||||||
|
MSG_HASH(
|
||||||
|
MSG_MANUAL_CONTENT_SCAN_INVALID_CONTENT,
|
||||||
|
"No valid content detected"
|
||||||
|
)
|
||||||
|
MSG_HASH(
|
||||||
|
MSG_MANUAL_CONTENT_SCAN_START,
|
||||||
|
"Scanning content: "
|
||||||
|
)
|
||||||
|
MSG_HASH(
|
||||||
|
MSG_MANUAL_CONTENT_SCAN_IN_PROGRESS,
|
||||||
|
"Scanning: "
|
||||||
|
)
|
||||||
|
MSG_HASH(
|
||||||
|
MSG_MANUAL_CONTENT_SCAN_END,
|
||||||
|
"Scan complete: "
|
||||||
|
)
|
||||||
|
@ -133,6 +133,10 @@ char* string_tokenize(char **str, const char *delim);
|
|||||||
/* Removes every instance of character 'c' from 'str' */
|
/* Removes every instance of character 'c' from 'str' */
|
||||||
void string_remove_all_chars(char *str, char c);
|
void string_remove_all_chars(char *str, char c);
|
||||||
|
|
||||||
|
/* Replaces every instance of character 'find' in 'str'
|
||||||
|
* with character 'replace' */
|
||||||
|
void string_replace_all_chars(char *str, char find, char replace);
|
||||||
|
|
||||||
/* Converts string to unsigned integer.
|
/* Converts string to unsigned integer.
|
||||||
* Returns 0 if string is invalid */
|
* Returns 0 if string is invalid */
|
||||||
unsigned string_to_unsigned(const char *str);
|
unsigned string_to_unsigned(const char *str);
|
||||||
|
@ -319,6 +319,19 @@ void string_remove_all_chars(char *str, char c)
|
|||||||
*write_ptr = '\0';
|
*write_ptr = '\0';
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* Replaces every instance of character 'find' in 'str'
|
||||||
|
* with character 'replace' */
|
||||||
|
void string_replace_all_chars(char *str, char find, char replace)
|
||||||
|
{
|
||||||
|
char *str_ptr = str;
|
||||||
|
|
||||||
|
if (string_is_empty(str))
|
||||||
|
return;
|
||||||
|
|
||||||
|
while((str_ptr = strchr(str_ptr, find)) != NULL)
|
||||||
|
*str_ptr++ = replace;
|
||||||
|
}
|
||||||
|
|
||||||
/* Converts string to unsigned integer.
|
/* Converts string to unsigned integer.
|
||||||
* Returns 0 if string is invalid */
|
* Returns 0 if string is invalid */
|
||||||
unsigned string_to_unsigned(const char *str)
|
unsigned string_to_unsigned(const char *str)
|
||||||
|
875
manual_content_scan.c
Normal file
875
manual_content_scan.c
Normal file
@ -0,0 +1,875 @@
|
|||||||
|
/* Copyright (C) 2010-2019 The RetroArch team
|
||||||
|
*
|
||||||
|
* ---------------------------------------------------------------------------------------
|
||||||
|
* The following license statement only applies to this file (manual_content_scan.c).
|
||||||
|
* ---------------------------------------------------------------------------------------
|
||||||
|
*
|
||||||
|
* Permission is hereby granted, free of charge,
|
||||||
|
* to any person obtaining a copy of this software and associated documentation files (the "Software"),
|
||||||
|
* to deal in the Software without restriction, including without limitation the rights to
|
||||||
|
* use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software,
|
||||||
|
* and to permit persons to whom the Software is furnished to do so, subject to the following conditions:
|
||||||
|
*
|
||||||
|
* The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.
|
||||||
|
*
|
||||||
|
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED,
|
||||||
|
* INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||||
|
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
|
||||||
|
* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
|
||||||
|
* WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||||
|
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include <file/file_path.h>
|
||||||
|
#include <string/stdstring.h>
|
||||||
|
#include <lists/dir_list.h>
|
||||||
|
#include <retro_miscellaneous.h>
|
||||||
|
|
||||||
|
#include "configuration.h"
|
||||||
|
#include "msg_hash.h"
|
||||||
|
#include "list_special.h"
|
||||||
|
#include "core_info.h"
|
||||||
|
#include "file_path_special.h"
|
||||||
|
|
||||||
|
#include "manual_content_scan.h"
|
||||||
|
|
||||||
|
/* Holds all configuration parameters associated
|
||||||
|
* with a manual content scan */
|
||||||
|
typedef struct
|
||||||
|
{
|
||||||
|
char content_dir[PATH_MAX_LENGTH];
|
||||||
|
char system_name_content_dir[PATH_MAX_LENGTH];
|
||||||
|
char system_name_database[PATH_MAX_LENGTH];
|
||||||
|
char system_name_custom[PATH_MAX_LENGTH];
|
||||||
|
char core_name[PATH_MAX_LENGTH];
|
||||||
|
char core_path[PATH_MAX_LENGTH];
|
||||||
|
char file_exts_core[PATH_MAX_LENGTH];
|
||||||
|
char file_exts_custom[PATH_MAX_LENGTH];
|
||||||
|
enum manual_content_scan_system_name_type system_name_type;
|
||||||
|
enum manual_content_scan_core_type core_type;
|
||||||
|
bool overwrite_playlist;
|
||||||
|
} scan_settings_t;
|
||||||
|
|
||||||
|
/* Static settings object
|
||||||
|
* > Provides easy access to settings parameters
|
||||||
|
* when creating associated menu entries
|
||||||
|
* > We are handling this in almost exactly the same
|
||||||
|
* way as the regular global 'static settings_t *configuration_settings;'
|
||||||
|
* object in retroarch.c. This means it is not inherently thread safe,
|
||||||
|
* but this should not be an issue (i.e. regular configuration_settings
|
||||||
|
* are not thread safe, but we only access them when pushing a
|
||||||
|
* task, not in the task thread itself, so all is well) */
|
||||||
|
static scan_settings_t scan_settings = {
|
||||||
|
"", /* content_dir */
|
||||||
|
"", /* system_name_content_dir */
|
||||||
|
"", /* system_name_database */
|
||||||
|
"", /* system_name_custom */
|
||||||
|
"", /* core_name */
|
||||||
|
"", /* core_path */
|
||||||
|
"", /* file_exts_core */
|
||||||
|
"", /* file_exts_custom */
|
||||||
|
MANUAL_CONTENT_SCAN_SYSTEM_NAME_CONTENT_DIR, /* system_name_type */
|
||||||
|
MANUAL_CONTENT_SCAN_CORE_DETECT, /* core_type */
|
||||||
|
false /* overwrite_playlist */
|
||||||
|
};
|
||||||
|
|
||||||
|
/*****************/
|
||||||
|
/* Configuration */
|
||||||
|
/*****************/
|
||||||
|
|
||||||
|
/* Pointer access */
|
||||||
|
|
||||||
|
/* Returns a pointer to the internal
|
||||||
|
* 'system_name_custom' string */
|
||||||
|
char *manual_content_scan_get_system_name_custom_ptr(void)
|
||||||
|
{
|
||||||
|
return scan_settings.system_name_custom;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Returns size of the internal
|
||||||
|
* 'system_name_custom' string */
|
||||||
|
size_t manual_content_scan_get_system_name_custom_size(void)
|
||||||
|
{
|
||||||
|
return sizeof(scan_settings.system_name_custom);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Returns a pointer to the internal
|
||||||
|
* 'file_exts_custom' string */
|
||||||
|
char *manual_content_scan_get_file_exts_custom_ptr(void)
|
||||||
|
{
|
||||||
|
return scan_settings.file_exts_custom;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Returns size of the internal
|
||||||
|
* 'file_exts_custom' string */
|
||||||
|
size_t manual_content_scan_get_file_exts_custom_size(void)
|
||||||
|
{
|
||||||
|
return sizeof(scan_settings.file_exts_custom);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Returns a pointer to the internal
|
||||||
|
* 'overwrite_playlist' bool */
|
||||||
|
bool *manual_content_scan_get_overwrite_playlist_ptr(void)
|
||||||
|
{
|
||||||
|
return &scan_settings.overwrite_playlist;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Sanitisation */
|
||||||
|
|
||||||
|
/* Sanitises file extensions list string:
|
||||||
|
* > Removes period (full stop) characters
|
||||||
|
* > Converts to lower case
|
||||||
|
* > Trims leading/trailing whitespace */
|
||||||
|
static void manual_content_scan_scrub_file_exts(char *file_exts)
|
||||||
|
{
|
||||||
|
if (string_is_empty(file_exts))
|
||||||
|
return;
|
||||||
|
|
||||||
|
string_remove_all_chars(file_exts, '.');
|
||||||
|
string_to_lower(file_exts);
|
||||||
|
string_trim_whitespace(file_exts);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Removes invalid characters from
|
||||||
|
* 'system_name_custom' string */
|
||||||
|
void manual_content_scan_scrub_system_name_custom(void)
|
||||||
|
{
|
||||||
|
char *scrub_char_pointer = NULL;
|
||||||
|
|
||||||
|
if (string_is_empty(scan_settings.system_name_custom))
|
||||||
|
return;
|
||||||
|
|
||||||
|
/* Scrub characters that are not cross-platform
|
||||||
|
* and/or violate the No-Intro filename standard:
|
||||||
|
* http://datomatic.no-intro.org/stuff/The%20Official%20No-Intro%20Convention%20(20071030).zip
|
||||||
|
* Replace these characters with underscores */
|
||||||
|
while((scrub_char_pointer = strpbrk(scan_settings.system_name_custom, "&*/:`\"<>?\\|")))
|
||||||
|
*scrub_char_pointer = '_';
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Removes period (full stop) characters from
|
||||||
|
* 'file_exts_custom' string and converts to
|
||||||
|
* lower case */
|
||||||
|
void manual_content_scan_scrub_file_exts_custom(void)
|
||||||
|
{
|
||||||
|
manual_content_scan_scrub_file_exts(scan_settings.file_exts_custom);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Menu setters */
|
||||||
|
|
||||||
|
/* Sets content directory for next manual scan
|
||||||
|
* operation.
|
||||||
|
* Returns true if content directory is valid. */
|
||||||
|
bool manual_content_scan_set_menu_content_dir(const char *content_dir)
|
||||||
|
{
|
||||||
|
const char *dir_name = NULL;
|
||||||
|
size_t len;
|
||||||
|
|
||||||
|
/* Sanity check */
|
||||||
|
if (string_is_empty(content_dir))
|
||||||
|
goto error;
|
||||||
|
|
||||||
|
if (!path_is_directory(content_dir))
|
||||||
|
goto error;
|
||||||
|
|
||||||
|
/* Copy directory path to settings struct */
|
||||||
|
strlcpy(
|
||||||
|
scan_settings.content_dir,
|
||||||
|
content_dir,
|
||||||
|
sizeof(scan_settings.content_dir));
|
||||||
|
|
||||||
|
/* Remove trailing slash, if required */
|
||||||
|
len = strlen(scan_settings.content_dir);
|
||||||
|
if (len > 0)
|
||||||
|
{
|
||||||
|
if (scan_settings.content_dir[len - 1] == path_default_slash_c())
|
||||||
|
scan_settings.content_dir[len - 1] = '\0';
|
||||||
|
}
|
||||||
|
else
|
||||||
|
goto error;
|
||||||
|
|
||||||
|
/* Handle case where path was a single slash... */
|
||||||
|
if (string_is_empty(scan_settings.content_dir))
|
||||||
|
goto error;
|
||||||
|
|
||||||
|
/* Get directory name (used as system name
|
||||||
|
* when scan_settings.system_name_type ==
|
||||||
|
* MANUAL_CONTENT_SCAN_SYSTEM_NAME_CONTENT_DIR) */
|
||||||
|
dir_name = path_basename(scan_settings.content_dir);
|
||||||
|
|
||||||
|
if (string_is_empty(dir_name))
|
||||||
|
goto error;
|
||||||
|
|
||||||
|
/* Copy directory name to settings struct */
|
||||||
|
strlcpy(
|
||||||
|
scan_settings.system_name_content_dir,
|
||||||
|
dir_name,
|
||||||
|
sizeof(scan_settings.system_name_content_dir));
|
||||||
|
|
||||||
|
return true;
|
||||||
|
|
||||||
|
error:
|
||||||
|
/* Directory is invalid - reset internal
|
||||||
|
* content directory and associated 'directory'
|
||||||
|
* system name */
|
||||||
|
scan_settings.content_dir[0] = '\0';
|
||||||
|
scan_settings.system_name_content_dir[0] = '\0';
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Sets system name for the next manual scan
|
||||||
|
* operation.
|
||||||
|
* Returns true if system name is valid.
|
||||||
|
* NOTE:
|
||||||
|
* > Only sets 'system_name_type' and 'system_name_database'
|
||||||
|
* > 'system_name_content_dir' and 'system_name_custom' are
|
||||||
|
* (by necessity) handled elsewhere
|
||||||
|
* > This may look fishy, but it's not - it's a menu-specific
|
||||||
|
* function, and this is simply the cleanest way to handle
|
||||||
|
* the setting... */
|
||||||
|
bool manual_content_scan_set_menu_system_name(
|
||||||
|
enum manual_content_scan_system_name_type system_name_type,
|
||||||
|
const char *system_name)
|
||||||
|
{
|
||||||
|
/* Sanity check */
|
||||||
|
if (system_name_type > MANUAL_CONTENT_SCAN_SYSTEM_NAME_DATABASE)
|
||||||
|
goto error;
|
||||||
|
|
||||||
|
/* Cache system name 'type' */
|
||||||
|
scan_settings.system_name_type = system_name_type;
|
||||||
|
|
||||||
|
/* Check if we are using a non-database name */
|
||||||
|
if ((scan_settings.system_name_type == MANUAL_CONTENT_SCAN_SYSTEM_NAME_CONTENT_DIR) ||
|
||||||
|
(scan_settings.system_name_type == MANUAL_CONTENT_SCAN_SYSTEM_NAME_CUSTOM))
|
||||||
|
scan_settings.system_name_database[0] = '\0';
|
||||||
|
else
|
||||||
|
{
|
||||||
|
/* We are using a database name... */
|
||||||
|
if (string_is_empty(system_name))
|
||||||
|
goto error;
|
||||||
|
|
||||||
|
/* Copy database name to settings struct */
|
||||||
|
strlcpy(
|
||||||
|
scan_settings.system_name_database,
|
||||||
|
system_name,
|
||||||
|
sizeof(scan_settings.system_name_database));
|
||||||
|
}
|
||||||
|
|
||||||
|
return true;
|
||||||
|
|
||||||
|
error:
|
||||||
|
/* Input parameters are invalid - reset internal
|
||||||
|
* 'system_name_type' and 'system_name_database' */
|
||||||
|
scan_settings.system_name_type = MANUAL_CONTENT_SCAN_SYSTEM_NAME_CONTENT_DIR;
|
||||||
|
scan_settings.system_name_database[0] = '\0';
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Sets core name for the next manual scan
|
||||||
|
* operation (+ core path and other associated
|
||||||
|
* parameters).
|
||||||
|
* Returns true if core name is valid. */
|
||||||
|
bool manual_content_scan_set_menu_core_name(
|
||||||
|
enum manual_content_scan_core_type core_type,
|
||||||
|
const char *core_name)
|
||||||
|
{
|
||||||
|
/* Sanity check */
|
||||||
|
if (core_type > MANUAL_CONTENT_SCAN_CORE_SET)
|
||||||
|
goto error;
|
||||||
|
|
||||||
|
/* Cache core 'type' */
|
||||||
|
scan_settings.core_type = core_type;
|
||||||
|
|
||||||
|
/* Check if we are using core autodetection */
|
||||||
|
if (scan_settings.core_type == MANUAL_CONTENT_SCAN_CORE_DETECT)
|
||||||
|
{
|
||||||
|
scan_settings.core_name[0] = '\0';
|
||||||
|
scan_settings.core_path[0] = '\0';
|
||||||
|
scan_settings.file_exts_core[0] = '\0';
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
core_info_list_t *core_info_list = NULL;
|
||||||
|
core_info_t *core_info = NULL;
|
||||||
|
bool core_found = false;
|
||||||
|
size_t i;
|
||||||
|
|
||||||
|
/* We are using a manually set core... */
|
||||||
|
if (string_is_empty(core_name))
|
||||||
|
goto error;
|
||||||
|
|
||||||
|
/* Get core list */
|
||||||
|
core_info_get_list(&core_info_list);
|
||||||
|
|
||||||
|
if (!core_info_list)
|
||||||
|
goto error;
|
||||||
|
|
||||||
|
/* Search for the specified core name */
|
||||||
|
for (i = 0; i < core_info_list->count; i++)
|
||||||
|
{
|
||||||
|
core_info = NULL;
|
||||||
|
core_info = core_info_get(core_info_list, i);
|
||||||
|
|
||||||
|
if (core_info)
|
||||||
|
{
|
||||||
|
if (string_is_equal(core_info->display_name, core_name))
|
||||||
|
{
|
||||||
|
/* Core has been found */
|
||||||
|
core_found = true;
|
||||||
|
|
||||||
|
/* Copy core path to settings struct */
|
||||||
|
if (string_is_empty(core_info->path))
|
||||||
|
goto error;
|
||||||
|
|
||||||
|
strlcpy(
|
||||||
|
scan_settings.core_path,
|
||||||
|
core_info->path,
|
||||||
|
sizeof(scan_settings.core_path));
|
||||||
|
|
||||||
|
/* Copy core name to settings struct */
|
||||||
|
strlcpy(
|
||||||
|
scan_settings.core_name,
|
||||||
|
core_info->display_name,
|
||||||
|
sizeof(scan_settings.core_name));
|
||||||
|
|
||||||
|
/* Copy supported extensions to settings
|
||||||
|
* struct, if required */
|
||||||
|
if (!string_is_empty(core_info->supported_extensions))
|
||||||
|
{
|
||||||
|
strlcpy(
|
||||||
|
scan_settings.file_exts_core,
|
||||||
|
core_info->supported_extensions,
|
||||||
|
sizeof(scan_settings.file_exts_core));
|
||||||
|
|
||||||
|
/* Core info extensions are delimited by
|
||||||
|
* vertical bars. For internal consistency,
|
||||||
|
* replace them with spaces */
|
||||||
|
string_replace_all_chars(scan_settings.file_exts_core, '|', ' ');
|
||||||
|
|
||||||
|
/* Apply standard scrubbing/clean-up
|
||||||
|
* (should not be required, but must handle the
|
||||||
|
* case where a core info file is incorrectly
|
||||||
|
* formatted) */
|
||||||
|
manual_content_scan_scrub_file_exts(scan_settings.file_exts_core);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
scan_settings.file_exts_core[0] = '\0';
|
||||||
|
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Sanity check */
|
||||||
|
if (!core_found)
|
||||||
|
goto error;
|
||||||
|
}
|
||||||
|
|
||||||
|
return true;
|
||||||
|
|
||||||
|
error:
|
||||||
|
/* Input parameters are invalid - reset internal
|
||||||
|
* core values */
|
||||||
|
scan_settings.core_type = MANUAL_CONTENT_SCAN_CORE_DETECT;
|
||||||
|
scan_settings.core_name[0] = '\0';
|
||||||
|
scan_settings.core_path[0] = '\0';
|
||||||
|
scan_settings.file_exts_core[0] = '\0';
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Menu getters */
|
||||||
|
|
||||||
|
/* Fetches content directory for next manual scan
|
||||||
|
* operation.
|
||||||
|
* Returns true if content directory is valid. */
|
||||||
|
bool manual_content_scan_get_menu_content_dir(const char **content_dir)
|
||||||
|
{
|
||||||
|
if (!content_dir)
|
||||||
|
return false;
|
||||||
|
|
||||||
|
if (string_is_empty(scan_settings.content_dir))
|
||||||
|
return false;
|
||||||
|
|
||||||
|
*content_dir = scan_settings.content_dir;
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Fetches system name for the next manual scan operation.
|
||||||
|
* Returns true if system name is valid.
|
||||||
|
* NOTE: This corresponds to the 'System Name' value
|
||||||
|
* displayed in menus - this is not identical to the
|
||||||
|
* actual system name used when generating the playlist */
|
||||||
|
bool manual_content_scan_get_menu_system_name(const char **system_name)
|
||||||
|
{
|
||||||
|
if (!system_name)
|
||||||
|
return false;
|
||||||
|
|
||||||
|
switch (scan_settings.system_name_type)
|
||||||
|
{
|
||||||
|
case MANUAL_CONTENT_SCAN_SYSTEM_NAME_CONTENT_DIR:
|
||||||
|
*system_name = msg_hash_to_str(
|
||||||
|
MENU_ENUM_LABEL_VALUE_MANUAL_CONTENT_SCAN_SYSTEM_NAME_USE_CONTENT_DIR);
|
||||||
|
return true;
|
||||||
|
case MANUAL_CONTENT_SCAN_SYSTEM_NAME_CUSTOM:
|
||||||
|
*system_name = msg_hash_to_str(
|
||||||
|
MENU_ENUM_LABEL_VALUE_MANUAL_CONTENT_SCAN_SYSTEM_NAME_USE_CUSTOM);
|
||||||
|
return true;
|
||||||
|
case MANUAL_CONTENT_SCAN_SYSTEM_NAME_DATABASE:
|
||||||
|
if (string_is_empty(scan_settings.system_name_database))
|
||||||
|
return false;
|
||||||
|
else
|
||||||
|
{
|
||||||
|
*system_name = scan_settings.system_name_database;
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
default:
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Fetches core name for the next manual scan operation.
|
||||||
|
* Returns true if core name is valid. */
|
||||||
|
bool manual_content_scan_get_menu_core_name(const char **core_name)
|
||||||
|
{
|
||||||
|
if (!core_name)
|
||||||
|
return false;
|
||||||
|
|
||||||
|
switch (scan_settings.core_type)
|
||||||
|
{
|
||||||
|
case MANUAL_CONTENT_SCAN_CORE_DETECT:
|
||||||
|
*core_name = msg_hash_to_str(
|
||||||
|
MENU_ENUM_LABEL_VALUE_MANUAL_CONTENT_SCAN_CORE_NAME_DETECT);
|
||||||
|
return true;
|
||||||
|
case MANUAL_CONTENT_SCAN_CORE_SET:
|
||||||
|
if (string_is_empty(scan_settings.core_name))
|
||||||
|
return false;
|
||||||
|
else
|
||||||
|
{
|
||||||
|
*core_name = scan_settings.core_name;
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
default:
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Menu utility functions */
|
||||||
|
|
||||||
|
/* Creates a list of all possible 'system name' menu
|
||||||
|
* strings, for use in 'menu_displaylist' drop-down
|
||||||
|
* lists and 'menu_cbs_left/right'
|
||||||
|
* > Returns NULL in the event of failure
|
||||||
|
* > Returned string list must be free()'d */
|
||||||
|
struct string_list *manual_content_scan_get_menu_system_name_list(void)
|
||||||
|
{
|
||||||
|
settings_t *settings = config_get_ptr();
|
||||||
|
struct string_list *name_list = string_list_new();
|
||||||
|
union string_list_elem_attr attr;
|
||||||
|
|
||||||
|
/* Sanity check */
|
||||||
|
if (!name_list)
|
||||||
|
goto error;
|
||||||
|
|
||||||
|
attr.i = 0;
|
||||||
|
|
||||||
|
/* Add 'use content directory' entry */
|
||||||
|
if (!string_list_append(name_list, msg_hash_to_str(
|
||||||
|
MENU_ENUM_LABEL_VALUE_MANUAL_CONTENT_SCAN_SYSTEM_NAME_USE_CONTENT_DIR), attr))
|
||||||
|
goto error;
|
||||||
|
|
||||||
|
/* Add 'use custom' entry */
|
||||||
|
if (!string_list_append(name_list, msg_hash_to_str(
|
||||||
|
MENU_ENUM_LABEL_VALUE_MANUAL_CONTENT_SCAN_SYSTEM_NAME_USE_CUSTOM), attr))
|
||||||
|
goto error;
|
||||||
|
|
||||||
|
#ifdef HAVE_LIBRETRODB
|
||||||
|
|
||||||
|
/* If platform has database support, get names
|
||||||
|
* of all installed database files */
|
||||||
|
if (settings)
|
||||||
|
{
|
||||||
|
/* Note: dir_list_new_special() is well behaved - the
|
||||||
|
* returned string list will only include database
|
||||||
|
* files (i.e. don't have to check for directories,
|
||||||
|
* or verify file extensions) */
|
||||||
|
struct string_list *rdb_list = dir_list_new_special(
|
||||||
|
settings->paths.path_content_database,
|
||||||
|
DIR_LIST_DATABASES, NULL);
|
||||||
|
|
||||||
|
if (rdb_list && rdb_list->size)
|
||||||
|
{
|
||||||
|
unsigned i;
|
||||||
|
|
||||||
|
/* Ensure database list is in alphabetical order */
|
||||||
|
dir_list_sort(rdb_list, true);
|
||||||
|
|
||||||
|
/* Loop over database files */
|
||||||
|
for (i = 0; i < rdb_list->size; i++)
|
||||||
|
{
|
||||||
|
const char *rdb_path = rdb_list->elems[i].data;
|
||||||
|
const char *rdb_file = NULL;
|
||||||
|
char rdb_name[PATH_MAX_LENGTH];
|
||||||
|
|
||||||
|
rdb_name[0] = '\0';
|
||||||
|
|
||||||
|
/* Sanity check */
|
||||||
|
if (string_is_empty(rdb_path))
|
||||||
|
continue;
|
||||||
|
|
||||||
|
rdb_file = path_basename(rdb_path);
|
||||||
|
|
||||||
|
if (string_is_empty(rdb_file))
|
||||||
|
continue;
|
||||||
|
|
||||||
|
/* Remove file extension */
|
||||||
|
strlcpy(rdb_name, rdb_file, sizeof(rdb_name));
|
||||||
|
path_remove_extension(rdb_name);
|
||||||
|
|
||||||
|
if (string_is_empty(rdb_name))
|
||||||
|
continue;
|
||||||
|
|
||||||
|
/* Add database name to list */
|
||||||
|
if (!string_list_append(name_list, rdb_name, attr))
|
||||||
|
goto error;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Clean up */
|
||||||
|
string_list_free(rdb_list);
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif
|
||||||
|
|
||||||
|
return name_list;
|
||||||
|
|
||||||
|
error:
|
||||||
|
if (name_list)
|
||||||
|
string_list_free(name_list);
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Creates a list of all possible 'core name' menu
|
||||||
|
* strings, for use in 'menu_displaylist' drop-down
|
||||||
|
* lists and 'menu_cbs_left/right'
|
||||||
|
* > Returns NULL in the event of failure
|
||||||
|
* > Returned string list must be free()'d */
|
||||||
|
struct string_list *manual_content_scan_get_menu_core_name_list(void)
|
||||||
|
{
|
||||||
|
struct string_list *name_list = string_list_new();
|
||||||
|
core_info_list_t *core_info_list = NULL;
|
||||||
|
union string_list_elem_attr attr;
|
||||||
|
|
||||||
|
/* Sanity check */
|
||||||
|
if (!name_list)
|
||||||
|
goto error;
|
||||||
|
|
||||||
|
attr.i = 0;
|
||||||
|
|
||||||
|
/* Add 'DETECT' entry */
|
||||||
|
if (!string_list_append(name_list, msg_hash_to_str(
|
||||||
|
MENU_ENUM_LABEL_VALUE_MANUAL_CONTENT_SCAN_CORE_NAME_DETECT), attr))
|
||||||
|
goto error;
|
||||||
|
|
||||||
|
/* Get core list */
|
||||||
|
core_info_get_list(&core_info_list);
|
||||||
|
|
||||||
|
if (core_info_list)
|
||||||
|
{
|
||||||
|
core_info_t *core_info = NULL;
|
||||||
|
size_t i;
|
||||||
|
|
||||||
|
/* Sort cores alphabetically */
|
||||||
|
core_info_qsort(core_info_list, CORE_INFO_LIST_SORT_DISPLAY_NAME);
|
||||||
|
|
||||||
|
/* Loop through cores */
|
||||||
|
for (i = 0; i < core_info_list->count; i++)
|
||||||
|
{
|
||||||
|
core_info = NULL;
|
||||||
|
core_info = core_info_get(core_info_list, i);
|
||||||
|
|
||||||
|
if (core_info)
|
||||||
|
{
|
||||||
|
if (string_is_empty(core_info->display_name))
|
||||||
|
continue;
|
||||||
|
|
||||||
|
/* Add core name to list */
|
||||||
|
if (!string_list_append(name_list, core_info->display_name, attr))
|
||||||
|
goto error;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return name_list;
|
||||||
|
|
||||||
|
error:
|
||||||
|
if (name_list)
|
||||||
|
string_list_free(name_list);
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
/****************/
|
||||||
|
/* Task Helpers */
|
||||||
|
/****************/
|
||||||
|
|
||||||
|
/* Parses current manual content scan settings,
|
||||||
|
* and extracts all information required to configure
|
||||||
|
* a manual content scan task.
|
||||||
|
* Returns false if current settings are invalid. */
|
||||||
|
bool manual_content_scan_get_task_config(manual_content_scan_task_config_t *task_config)
|
||||||
|
{
|
||||||
|
settings_t *settings = config_get_ptr();
|
||||||
|
|
||||||
|
if (!task_config || !settings)
|
||||||
|
return false;
|
||||||
|
|
||||||
|
/* Ensure all 'task_config' strings are
|
||||||
|
* correctly initialised */
|
||||||
|
task_config->playlist_file[0] = '\0';
|
||||||
|
task_config->content_dir[0] = '\0';
|
||||||
|
task_config->system_name[0] = '\0';
|
||||||
|
task_config->database_name[0] = '\0';
|
||||||
|
task_config->core_name[0] = '\0';
|
||||||
|
task_config->core_path[0] = '\0';
|
||||||
|
task_config->file_exts[0] = '\0';
|
||||||
|
|
||||||
|
/* Get content directory */
|
||||||
|
if (string_is_empty(scan_settings.content_dir))
|
||||||
|
return false;
|
||||||
|
|
||||||
|
if (!path_is_directory(scan_settings.content_dir))
|
||||||
|
return false;
|
||||||
|
|
||||||
|
strlcpy(
|
||||||
|
task_config->content_dir,
|
||||||
|
scan_settings.content_dir,
|
||||||
|
sizeof(task_config->content_dir));
|
||||||
|
|
||||||
|
/* Get system name */
|
||||||
|
switch (scan_settings.system_name_type)
|
||||||
|
{
|
||||||
|
case MANUAL_CONTENT_SCAN_SYSTEM_NAME_CONTENT_DIR:
|
||||||
|
if (string_is_empty(scan_settings.system_name_content_dir))
|
||||||
|
return false;
|
||||||
|
|
||||||
|
strlcpy(
|
||||||
|
task_config->system_name,
|
||||||
|
scan_settings.system_name_content_dir,
|
||||||
|
sizeof(task_config->system_name));
|
||||||
|
|
||||||
|
break;
|
||||||
|
case MANUAL_CONTENT_SCAN_SYSTEM_NAME_CUSTOM:
|
||||||
|
if (string_is_empty(scan_settings.system_name_custom))
|
||||||
|
return false;
|
||||||
|
|
||||||
|
strlcpy(
|
||||||
|
task_config->system_name,
|
||||||
|
scan_settings.system_name_custom,
|
||||||
|
sizeof(task_config->system_name));
|
||||||
|
|
||||||
|
break;
|
||||||
|
case MANUAL_CONTENT_SCAN_SYSTEM_NAME_DATABASE:
|
||||||
|
if (string_is_empty(scan_settings.system_name_database))
|
||||||
|
return false;
|
||||||
|
|
||||||
|
strlcpy(
|
||||||
|
task_config->system_name,
|
||||||
|
scan_settings.system_name_database,
|
||||||
|
sizeof(task_config->system_name));
|
||||||
|
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Now we have a valid system name, can generate
|
||||||
|
* a 'database' name... */
|
||||||
|
strlcpy(
|
||||||
|
task_config->database_name,
|
||||||
|
task_config->system_name,
|
||||||
|
sizeof(task_config->database_name));
|
||||||
|
|
||||||
|
strlcat(
|
||||||
|
task_config->database_name,
|
||||||
|
file_path_str(FILE_PATH_LPL_EXTENSION),
|
||||||
|
sizeof(task_config->database_name));
|
||||||
|
|
||||||
|
/* ...which can in turn be used to generate the
|
||||||
|
* playlist path */
|
||||||
|
if (string_is_empty(settings->paths.directory_playlist))
|
||||||
|
return false;
|
||||||
|
|
||||||
|
fill_pathname_join(
|
||||||
|
task_config->playlist_file,
|
||||||
|
settings->paths.directory_playlist,
|
||||||
|
task_config->database_name,
|
||||||
|
sizeof(task_config->playlist_file));
|
||||||
|
|
||||||
|
if (string_is_empty(task_config->playlist_file))
|
||||||
|
return false;
|
||||||
|
|
||||||
|
/* Get core name and path */
|
||||||
|
switch (scan_settings.core_type)
|
||||||
|
{
|
||||||
|
case MANUAL_CONTENT_SCAN_CORE_DETECT:
|
||||||
|
task_config->core_set = false;
|
||||||
|
break;
|
||||||
|
case MANUAL_CONTENT_SCAN_CORE_SET:
|
||||||
|
task_config->core_set = true;
|
||||||
|
|
||||||
|
if (string_is_empty(scan_settings.core_name))
|
||||||
|
return false;
|
||||||
|
if (string_is_empty(scan_settings.core_path))
|
||||||
|
return false;
|
||||||
|
|
||||||
|
strlcpy(
|
||||||
|
task_config->core_name,
|
||||||
|
scan_settings.core_name,
|
||||||
|
sizeof(task_config->core_name));
|
||||||
|
|
||||||
|
strlcpy(
|
||||||
|
task_config->core_path,
|
||||||
|
scan_settings.core_path,
|
||||||
|
sizeof(task_config->core_path));
|
||||||
|
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Get file extensions list
|
||||||
|
* > Note that compressed files are included by
|
||||||
|
* default, regardless of extension filter
|
||||||
|
* (since these can always be handled by the
|
||||||
|
* frontend) */
|
||||||
|
task_config->include_compressed_content = true;
|
||||||
|
|
||||||
|
if (!string_is_empty(scan_settings.file_exts_custom))
|
||||||
|
{
|
||||||
|
strlcpy(
|
||||||
|
task_config->file_exts,
|
||||||
|
scan_settings.file_exts_custom,
|
||||||
|
sizeof(task_config->file_exts));
|
||||||
|
|
||||||
|
/* User has explicitly specified which file
|
||||||
|
* types are allowed - have to exclude compressed
|
||||||
|
* content when calling dir_list_new() */
|
||||||
|
task_config->include_compressed_content = false;
|
||||||
|
}
|
||||||
|
else if (scan_settings.core_type == MANUAL_CONTENT_SCAN_CORE_SET)
|
||||||
|
{
|
||||||
|
if (!string_is_empty(scan_settings.file_exts_core))
|
||||||
|
strlcpy(
|
||||||
|
task_config->file_exts,
|
||||||
|
scan_settings.file_exts_core,
|
||||||
|
sizeof(task_config->file_exts));
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Our extension lists are space delimited
|
||||||
|
* > dir_list_new() expects vertical bar
|
||||||
|
* delimiters, so find and replace */
|
||||||
|
if (!string_is_empty(task_config->file_exts))
|
||||||
|
string_replace_all_chars(task_config->file_exts, ' ', '|');
|
||||||
|
|
||||||
|
/* Copy 'overwrite playlist' setting */
|
||||||
|
task_config->overwrite_playlist = scan_settings.overwrite_playlist;
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Creates a list of all valid content in the specified
|
||||||
|
* content directory
|
||||||
|
* > Returns NULL in the event of failure
|
||||||
|
* > Returned string list must be free()'d */
|
||||||
|
struct string_list *manual_content_scan_get_content_list(manual_content_scan_task_config_t *task_config)
|
||||||
|
{
|
||||||
|
struct string_list *dir_list = NULL;
|
||||||
|
bool filter_exts;
|
||||||
|
|
||||||
|
/* Sanity check */
|
||||||
|
if (!task_config)
|
||||||
|
goto error;
|
||||||
|
|
||||||
|
if (string_is_empty(task_config->content_dir))
|
||||||
|
goto error;
|
||||||
|
|
||||||
|
/* Get directory listing
|
||||||
|
* > Exclude directories and hidden files
|
||||||
|
* > Scan recursively */
|
||||||
|
dir_list = dir_list_new(
|
||||||
|
task_config->content_dir,
|
||||||
|
string_is_empty(task_config->file_exts) ? NULL : task_config->file_exts,
|
||||||
|
false, /* include_dirs */
|
||||||
|
false, /* include_hidden */
|
||||||
|
task_config->include_compressed_content,
|
||||||
|
true /* recursive */
|
||||||
|
);
|
||||||
|
|
||||||
|
/* Sanity check */
|
||||||
|
if (!dir_list)
|
||||||
|
goto error;
|
||||||
|
|
||||||
|
if (dir_list->size < 1)
|
||||||
|
goto error;
|
||||||
|
|
||||||
|
/* Ensure list is in alphabetical order
|
||||||
|
* > Not strictly required, but task status
|
||||||
|
* messages will be unintuitive if we leave
|
||||||
|
* the order 'random' */
|
||||||
|
dir_list_sort(dir_list, true);
|
||||||
|
|
||||||
|
return dir_list;
|
||||||
|
|
||||||
|
error:
|
||||||
|
if (dir_list)
|
||||||
|
string_list_free(dir_list);
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Adds specified content to playlist, if not already
|
||||||
|
* present */
|
||||||
|
void manual_content_scan_add_content_to_playlist(
|
||||||
|
manual_content_scan_task_config_t *task_config,
|
||||||
|
playlist_t *playlist, const char *content_path)
|
||||||
|
{
|
||||||
|
/* Sanity check */
|
||||||
|
if (!task_config || !playlist || string_is_empty(content_path))
|
||||||
|
return;
|
||||||
|
|
||||||
|
if (!path_is_valid(content_path))
|
||||||
|
return;
|
||||||
|
|
||||||
|
/* Check whether content is already included
|
||||||
|
* in playlist */
|
||||||
|
if (!playlist_entry_exists(playlist, content_path))
|
||||||
|
{
|
||||||
|
struct playlist_entry entry = {0};
|
||||||
|
char label[PATH_MAX_LENGTH];
|
||||||
|
|
||||||
|
label[0] = '\0';
|
||||||
|
|
||||||
|
/* Get entry label */
|
||||||
|
fill_short_pathname_representation(
|
||||||
|
label, content_path, sizeof(label));
|
||||||
|
|
||||||
|
if (string_is_empty(label))
|
||||||
|
return;
|
||||||
|
|
||||||
|
/* Configure playlist entry
|
||||||
|
* > The push function reads our entry as const,
|
||||||
|
* so these casts are safe */
|
||||||
|
entry.path = (char*)content_path;
|
||||||
|
entry.label = label;
|
||||||
|
entry.core_path = (char*)"DETECT";
|
||||||
|
entry.core_name = (char*)"DETECT";
|
||||||
|
entry.crc32 = (char*)"00000000|crc";
|
||||||
|
entry.db_name = task_config->database_name;
|
||||||
|
|
||||||
|
/* Add entry to playlist */
|
||||||
|
playlist_push(playlist, &entry);
|
||||||
|
}
|
||||||
|
}
|
201
manual_content_scan.h
Normal file
201
manual_content_scan.h
Normal file
@ -0,0 +1,201 @@
|
|||||||
|
/* Copyright (C) 2010-2019 The RetroArch team
|
||||||
|
*
|
||||||
|
* ---------------------------------------------------------------------------------------
|
||||||
|
* The following license statement only applies to this file (manual_content_scan.c).
|
||||||
|
* ---------------------------------------------------------------------------------------
|
||||||
|
*
|
||||||
|
* Permission is hereby granted, free of charge,
|
||||||
|
* to any person obtaining a copy of this software and associated documentation files (the "Software"),
|
||||||
|
* to deal in the Software without restriction, including without limitation the rights to
|
||||||
|
* use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software,
|
||||||
|
* and to permit persons to whom the Software is furnished to do so, subject to the following conditions:
|
||||||
|
*
|
||||||
|
* The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.
|
||||||
|
*
|
||||||
|
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED,
|
||||||
|
* INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||||
|
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
|
||||||
|
* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
|
||||||
|
* WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||||
|
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifndef __MANUAL_CONTENT_SCAN_H
|
||||||
|
#define __MANUAL_CONTENT_SCAN_H
|
||||||
|
|
||||||
|
#include <retro_common_api.h>
|
||||||
|
#include <libretro.h>
|
||||||
|
|
||||||
|
#include <boolean.h>
|
||||||
|
|
||||||
|
#include <lists/string_list.h>
|
||||||
|
|
||||||
|
#include "playlist.h"
|
||||||
|
|
||||||
|
RETRO_BEGIN_DECLS
|
||||||
|
|
||||||
|
/* Defines all possible system name types
|
||||||
|
* > Use content directory name
|
||||||
|
* > Use custom name
|
||||||
|
* > Use database name */
|
||||||
|
enum manual_content_scan_system_name_type
|
||||||
|
{
|
||||||
|
MANUAL_CONTENT_SCAN_SYSTEM_NAME_CONTENT_DIR = 0,
|
||||||
|
MANUAL_CONTENT_SCAN_SYSTEM_NAME_CUSTOM,
|
||||||
|
MANUAL_CONTENT_SCAN_SYSTEM_NAME_DATABASE
|
||||||
|
};
|
||||||
|
|
||||||
|
/* Defines all possible core name types
|
||||||
|
* > Autodetect core (DETECT)
|
||||||
|
* > Use manually set core */
|
||||||
|
enum manual_content_scan_core_type
|
||||||
|
{
|
||||||
|
MANUAL_CONTENT_SCAN_CORE_DETECT = 0,
|
||||||
|
MANUAL_CONTENT_SCAN_CORE_SET
|
||||||
|
};
|
||||||
|
|
||||||
|
/* Holds all configuration parameters required
|
||||||
|
* for a manual content scan task */
|
||||||
|
typedef struct
|
||||||
|
{
|
||||||
|
char playlist_file[PATH_MAX_LENGTH];
|
||||||
|
char content_dir[PATH_MAX_LENGTH];
|
||||||
|
char system_name[PATH_MAX_LENGTH];
|
||||||
|
char database_name[PATH_MAX_LENGTH];
|
||||||
|
char core_name[PATH_MAX_LENGTH];
|
||||||
|
char core_path[PATH_MAX_LENGTH];
|
||||||
|
char file_exts[PATH_MAX_LENGTH];
|
||||||
|
bool core_set;
|
||||||
|
bool overwrite_playlist;
|
||||||
|
bool include_compressed_content;
|
||||||
|
} manual_content_scan_task_config_t;
|
||||||
|
|
||||||
|
/*****************/
|
||||||
|
/* Configuration */
|
||||||
|
/*****************/
|
||||||
|
|
||||||
|
/* Pointer access
|
||||||
|
* > This is a little ugly, but it allows us to
|
||||||
|
* make use of standard 'menu_settings' code
|
||||||
|
* for several config parameters (rather than
|
||||||
|
* implementing unnecessary custom menu entries) */
|
||||||
|
|
||||||
|
/* Returns a pointer to the internal
|
||||||
|
* 'system_name_custom' string */
|
||||||
|
char *manual_content_scan_get_system_name_custom_ptr(void);
|
||||||
|
|
||||||
|
/* Returns size of the internal
|
||||||
|
* 'system_name_custom' string */
|
||||||
|
size_t manual_content_scan_get_system_name_custom_size(void);
|
||||||
|
|
||||||
|
/* Returns a pointer to the internal
|
||||||
|
* 'file_exts_custom' string */
|
||||||
|
char *manual_content_scan_get_file_exts_custom_ptr(void);
|
||||||
|
|
||||||
|
/* Returns size of the internal
|
||||||
|
* 'file_exts_custom' string */
|
||||||
|
size_t manual_content_scan_get_file_exts_custom_size(void);
|
||||||
|
|
||||||
|
/* Returns a pointer to the internal
|
||||||
|
* 'overwrite_playlist' bool */
|
||||||
|
bool *manual_content_scan_get_overwrite_playlist_ptr(void);
|
||||||
|
|
||||||
|
/* Sanitisation */
|
||||||
|
|
||||||
|
/* Removes invalid characters from
|
||||||
|
* 'system_name_custom' string */
|
||||||
|
void manual_content_scan_scrub_system_name_custom(void);
|
||||||
|
|
||||||
|
/* Removes period (full stop) characters from
|
||||||
|
* 'file_exts_custom' string and converts to
|
||||||
|
* lower case */
|
||||||
|
void manual_content_scan_scrub_file_exts_custom(void);
|
||||||
|
|
||||||
|
/* Menu setters */
|
||||||
|
|
||||||
|
/* Sets content directory for next manual scan
|
||||||
|
* operation.
|
||||||
|
* Returns true if content directory is valid. */
|
||||||
|
bool manual_content_scan_set_menu_content_dir(const char *content_dir);
|
||||||
|
|
||||||
|
/* Sets system name for the next manual scan
|
||||||
|
* operation.
|
||||||
|
* Returns true if system name is valid.
|
||||||
|
* NOTE:
|
||||||
|
* > Only sets 'system_name_type' and 'system_name_database'
|
||||||
|
* > 'system_name_content_dir' and 'system_name_custom' are
|
||||||
|
* (by necessity) handled elsewhere
|
||||||
|
* > This may look fishy, but it's not - it's a menu-specific
|
||||||
|
* function, and this is simply the cleanest way to handle
|
||||||
|
* the setting... */
|
||||||
|
bool manual_content_scan_set_menu_system_name(
|
||||||
|
enum manual_content_scan_system_name_type system_name_type,
|
||||||
|
const char *system_name);
|
||||||
|
|
||||||
|
/* Sets core name for the next manual scan
|
||||||
|
* operation (+ core path and other associated
|
||||||
|
* parameters).
|
||||||
|
* Returns true if core name is valid. */
|
||||||
|
bool manual_content_scan_set_menu_core_name(
|
||||||
|
enum manual_content_scan_core_type core_type,
|
||||||
|
const char *core_name);
|
||||||
|
|
||||||
|
/* Menu getters */
|
||||||
|
|
||||||
|
/* Fetches content directory for next manual scan
|
||||||
|
* operation.
|
||||||
|
* Returns true if content directory is valid. */
|
||||||
|
bool manual_content_scan_get_menu_content_dir(const char **content_dir);
|
||||||
|
|
||||||
|
/* Fetches system name for the next manual scan operation.
|
||||||
|
* Returns true if system name is valid.
|
||||||
|
* NOTE: This corresponds to the 'System Name' value
|
||||||
|
* displayed in menus - this is not identical to the
|
||||||
|
* actual system name used when generating the playlist */
|
||||||
|
bool manual_content_scan_get_menu_system_name(const char **system_name);
|
||||||
|
|
||||||
|
/* Fetches core name for the next manual scan operation.
|
||||||
|
* Returns true if core name is valid. */
|
||||||
|
bool manual_content_scan_get_menu_core_name(const char **core_name);
|
||||||
|
|
||||||
|
/* Menu utility functions */
|
||||||
|
|
||||||
|
/* Creates a list of all possible 'system name' menu
|
||||||
|
* strings, for use in 'menu_displaylist' drop-down
|
||||||
|
* lists and 'menu_cbs_left/right'
|
||||||
|
* > Returns NULL in the event of failure
|
||||||
|
* > Returned string list must be free()'d */
|
||||||
|
struct string_list *manual_content_scan_get_menu_system_name_list(void);
|
||||||
|
|
||||||
|
/* Creates a list of all possible 'core name' menu
|
||||||
|
* strings, for use in 'menu_displaylist' drop-down
|
||||||
|
* lists and 'menu_cbs_left/right'
|
||||||
|
* > Returns NULL in the event of failure
|
||||||
|
* > Returned string list must be free()'d */
|
||||||
|
struct string_list *manual_content_scan_get_menu_core_name_list(void);
|
||||||
|
|
||||||
|
/****************/
|
||||||
|
/* Task Helpers */
|
||||||
|
/****************/
|
||||||
|
|
||||||
|
/* Parses current manual content scan settings,
|
||||||
|
* and extracts all information required to configure
|
||||||
|
* a manual content scan task.
|
||||||
|
* Returns false if current settings are invalid. */
|
||||||
|
bool manual_content_scan_get_task_config(manual_content_scan_task_config_t *task_config);
|
||||||
|
|
||||||
|
/* Creates a list of all valid content in the specified
|
||||||
|
* content directory
|
||||||
|
* > Returns NULL in the event of failure
|
||||||
|
* > Returned string list must be free()'d */
|
||||||
|
struct string_list *manual_content_scan_get_content_list(manual_content_scan_task_config_t *task_config);
|
||||||
|
|
||||||
|
/* Adds specified content to playlist, if not already
|
||||||
|
* present */
|
||||||
|
void manual_content_scan_add_content_to_playlist(
|
||||||
|
manual_content_scan_task_config_t *task_config,
|
||||||
|
playlist_t *playlist, const char *content_path);
|
||||||
|
|
||||||
|
RETRO_END_DECLS
|
||||||
|
|
||||||
|
#endif
|
@ -217,6 +217,8 @@ generic_deferred_push(deferred_push_switch_gpu_profile, DISPLAYLIST_
|
|||||||
generic_deferred_push(deferred_push_switch_backlight_control, DISPLAYLIST_SWITCH_BACKLIGHT_CONTROL)
|
generic_deferred_push(deferred_push_switch_backlight_control, DISPLAYLIST_SWITCH_BACKLIGHT_CONTROL)
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
generic_deferred_push(deferred_push_manual_content_scan_list, DISPLAYLIST_MANUAL_CONTENT_SCAN_LIST)
|
||||||
|
|
||||||
static int deferred_push_cursor_manager_list_deferred(
|
static int deferred_push_cursor_manager_list_deferred(
|
||||||
menu_displaylist_info_t *info)
|
menu_displaylist_info_t *info)
|
||||||
{
|
{
|
||||||
@ -636,6 +638,8 @@ generic_deferred_push_clear_general(deferred_push_dropdown_box_list_playlist_def
|
|||||||
generic_deferred_push_clear_general(deferred_push_dropdown_box_list_playlist_label_display_mode, PUSH_DEFAULT, DISPLAYLIST_DROPDOWN_LIST_PLAYLIST_LABEL_DISPLAY_MODE)
|
generic_deferred_push_clear_general(deferred_push_dropdown_box_list_playlist_label_display_mode, PUSH_DEFAULT, DISPLAYLIST_DROPDOWN_LIST_PLAYLIST_LABEL_DISPLAY_MODE)
|
||||||
generic_deferred_push_clear_general(deferred_push_dropdown_box_list_playlist_right_thumbnail_mode, PUSH_DEFAULT, DISPLAYLIST_DROPDOWN_LIST_PLAYLIST_RIGHT_THUMBNAIL_MODE)
|
generic_deferred_push_clear_general(deferred_push_dropdown_box_list_playlist_right_thumbnail_mode, PUSH_DEFAULT, DISPLAYLIST_DROPDOWN_LIST_PLAYLIST_RIGHT_THUMBNAIL_MODE)
|
||||||
generic_deferred_push_clear_general(deferred_push_dropdown_box_list_playlist_left_thumbnail_mode, PUSH_DEFAULT, DISPLAYLIST_DROPDOWN_LIST_PLAYLIST_LEFT_THUMBNAIL_MODE)
|
generic_deferred_push_clear_general(deferred_push_dropdown_box_list_playlist_left_thumbnail_mode, PUSH_DEFAULT, DISPLAYLIST_DROPDOWN_LIST_PLAYLIST_LEFT_THUMBNAIL_MODE)
|
||||||
|
generic_deferred_push_clear_general(deferred_push_dropdown_box_list_manual_content_scan_system_name, PUSH_DEFAULT, DISPLAYLIST_DROPDOWN_LIST_MANUAL_CONTENT_SCAN_SYSTEM_NAME)
|
||||||
|
generic_deferred_push_clear_general(deferred_push_dropdown_box_list_manual_content_scan_core_name, PUSH_DEFAULT, DISPLAYLIST_DROPDOWN_LIST_MANUAL_CONTENT_SCAN_CORE_NAME)
|
||||||
|
|
||||||
static int menu_cbs_init_bind_deferred_push_compare_label(
|
static int menu_cbs_init_bind_deferred_push_compare_label(
|
||||||
menu_file_list_cbs_t *cbs,
|
menu_file_list_cbs_t *cbs,
|
||||||
@ -691,6 +695,16 @@ static int menu_cbs_init_bind_deferred_push_compare_label(
|
|||||||
BIND_ACTION_DEFERRED_PUSH(cbs, deferred_push_dropdown_box_list_playlist_left_thumbnail_mode);
|
BIND_ACTION_DEFERRED_PUSH(cbs, deferred_push_dropdown_box_list_playlist_left_thumbnail_mode);
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
else if (string_is_equal(label, msg_hash_to_str(MENU_ENUM_LABEL_DEFERRED_DROPDOWN_BOX_LIST_MANUAL_CONTENT_SCAN_SYSTEM_NAME)))
|
||||||
|
{
|
||||||
|
BIND_ACTION_DEFERRED_PUSH(cbs, deferred_push_dropdown_box_list_manual_content_scan_system_name);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
else if (string_is_equal(label, msg_hash_to_str(MENU_ENUM_LABEL_DEFERRED_DROPDOWN_BOX_LIST_MANUAL_CONTENT_SCAN_CORE_NAME)))
|
||||||
|
{
|
||||||
|
BIND_ACTION_DEFERRED_PUSH(cbs, deferred_push_dropdown_box_list_manual_content_scan_core_name);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
else if (string_is_equal(label, msg_hash_to_str(MENU_ENUM_LABEL_DEFERRED_BROWSE_URL_LIST)))
|
else if (string_is_equal(label, msg_hash_to_str(MENU_ENUM_LABEL_DEFERRED_BROWSE_URL_LIST)))
|
||||||
{
|
{
|
||||||
BIND_ACTION_DEFERRED_PUSH(cbs, deferred_push_browse_url_list);
|
BIND_ACTION_DEFERRED_PUSH(cbs, deferred_push_browse_url_list);
|
||||||
@ -1439,6 +1453,9 @@ static int menu_cbs_init_bind_deferred_push_compare_label(
|
|||||||
case MENU_ENUM_LABEL_FAVORITES:
|
case MENU_ENUM_LABEL_FAVORITES:
|
||||||
BIND_ACTION_DEFERRED_PUSH(cbs, deferred_push_detect_core_list);
|
BIND_ACTION_DEFERRED_PUSH(cbs, deferred_push_detect_core_list);
|
||||||
break;
|
break;
|
||||||
|
case MENU_ENUM_LABEL_DEFERRED_MANUAL_CONTENT_SCAN_LIST:
|
||||||
|
BIND_ACTION_DEFERRED_PUSH(cbs, deferred_push_manual_content_scan_list);
|
||||||
|
break;
|
||||||
default:
|
default:
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
@ -1655,6 +1672,9 @@ static int menu_cbs_init_bind_deferred_push_compare_label(
|
|||||||
case MENU_LABEL_FAVORITES:
|
case MENU_LABEL_FAVORITES:
|
||||||
BIND_ACTION_DEFERRED_PUSH(cbs, deferred_push_detect_core_list);
|
BIND_ACTION_DEFERRED_PUSH(cbs, deferred_push_detect_core_list);
|
||||||
break;
|
break;
|
||||||
|
case MENU_LABEL_DEFERRED_MANUAL_CONTENT_SCAN_LIST:
|
||||||
|
BIND_ACTION_DEFERRED_PUSH(cbs, deferred_push_manual_content_scan_list);
|
||||||
|
break;
|
||||||
default:
|
default:
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
@ -43,6 +43,7 @@
|
|||||||
#include "../../verbosity.h"
|
#include "../../verbosity.h"
|
||||||
#include "../../wifi/wifi_driver.h"
|
#include "../../wifi/wifi_driver.h"
|
||||||
#include "../../playlist.h"
|
#include "../../playlist.h"
|
||||||
|
#include "../../manual_content_scan.h"
|
||||||
|
|
||||||
#ifdef HAVE_NETWORKING
|
#ifdef HAVE_NETWORKING
|
||||||
#include "../../network/netplay/netplay.h"
|
#include "../../network/netplay/netplay.h"
|
||||||
@ -1292,6 +1293,66 @@ static void menu_action_setting_disp_set_label_achievement_information(
|
|||||||
strlcpy(s2, path, len2);
|
strlcpy(s2, path, len2);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static void menu_action_setting_disp_set_label_manual_content_scan_dir(file_list_t* list,
|
||||||
|
unsigned *w, unsigned type, unsigned i,
|
||||||
|
const char *label,
|
||||||
|
char *s, size_t len,
|
||||||
|
const char *path,
|
||||||
|
char *s2, size_t len2)
|
||||||
|
{
|
||||||
|
const char *content_dir = NULL;
|
||||||
|
|
||||||
|
*s = '\0';
|
||||||
|
*w = 19;
|
||||||
|
|
||||||
|
strlcpy(s2, path, len2);
|
||||||
|
|
||||||
|
if (!manual_content_scan_get_menu_content_dir(&content_dir))
|
||||||
|
return;
|
||||||
|
|
||||||
|
strlcpy(s, content_dir, len);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void menu_action_setting_disp_set_label_manual_content_scan_system_name(file_list_t* list,
|
||||||
|
unsigned *w, unsigned type, unsigned i,
|
||||||
|
const char *label,
|
||||||
|
char *s, size_t len,
|
||||||
|
const char *path,
|
||||||
|
char *s2, size_t len2)
|
||||||
|
{
|
||||||
|
const char *system_name = NULL;
|
||||||
|
|
||||||
|
*s = '\0';
|
||||||
|
*w = 19;
|
||||||
|
|
||||||
|
strlcpy(s2, path, len2);
|
||||||
|
|
||||||
|
if (!manual_content_scan_get_menu_system_name(&system_name))
|
||||||
|
return;
|
||||||
|
|
||||||
|
strlcpy(s, system_name, len);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void menu_action_setting_disp_set_label_manual_content_scan_core_name(file_list_t* list,
|
||||||
|
unsigned *w, unsigned type, unsigned i,
|
||||||
|
const char *label,
|
||||||
|
char *s, size_t len,
|
||||||
|
const char *path,
|
||||||
|
char *s2, size_t len2)
|
||||||
|
{
|
||||||
|
const char *core_name = NULL;
|
||||||
|
|
||||||
|
*s = '\0';
|
||||||
|
*w = 19;
|
||||||
|
|
||||||
|
strlcpy(s2, path, len2);
|
||||||
|
|
||||||
|
if (!manual_content_scan_get_menu_core_name(&core_name))
|
||||||
|
return;
|
||||||
|
|
||||||
|
strlcpy(s, core_name, len);
|
||||||
|
}
|
||||||
|
|
||||||
static void menu_action_setting_disp_set_label_no_items(
|
static void menu_action_setting_disp_set_label_no_items(
|
||||||
file_list_t* list,
|
file_list_t* list,
|
||||||
unsigned *w, unsigned type, unsigned i,
|
unsigned *w, unsigned type, unsigned i,
|
||||||
@ -1502,6 +1563,18 @@ static int menu_cbs_init_bind_get_string_representation_compare_label(
|
|||||||
BIND_ACTION_GET_VALUE(cbs,
|
BIND_ACTION_GET_VALUE(cbs,
|
||||||
menu_action_setting_disp_set_label_playlist_left_thumbnail_mode);
|
menu_action_setting_disp_set_label_playlist_left_thumbnail_mode);
|
||||||
break;
|
break;
|
||||||
|
case MENU_ENUM_LABEL_MANUAL_CONTENT_SCAN_DIR:
|
||||||
|
BIND_ACTION_GET_VALUE(cbs,
|
||||||
|
menu_action_setting_disp_set_label_manual_content_scan_dir);
|
||||||
|
break;
|
||||||
|
case MENU_ENUM_LABEL_MANUAL_CONTENT_SCAN_SYSTEM_NAME:
|
||||||
|
BIND_ACTION_GET_VALUE(cbs,
|
||||||
|
menu_action_setting_disp_set_label_manual_content_scan_system_name);
|
||||||
|
break;
|
||||||
|
case MENU_ENUM_LABEL_MANUAL_CONTENT_SCAN_CORE_NAME:
|
||||||
|
BIND_ACTION_GET_VALUE(cbs,
|
||||||
|
menu_action_setting_disp_set_label_manual_content_scan_core_name);
|
||||||
|
break;
|
||||||
default:
|
default:
|
||||||
return - 1;
|
return - 1;
|
||||||
}
|
}
|
||||||
|
@ -41,6 +41,7 @@
|
|||||||
#include "../../retroarch.h"
|
#include "../../retroarch.h"
|
||||||
#include "../../network/netplay/netplay.h"
|
#include "../../network/netplay/netplay.h"
|
||||||
#include "../../playlist.h"
|
#include "../../playlist.h"
|
||||||
|
#include "../../manual_content_scan.h"
|
||||||
|
|
||||||
#ifndef BIND_ACTION_LEFT
|
#ifndef BIND_ACTION_LEFT
|
||||||
#define BIND_ACTION_LEFT(cbs, name) \
|
#define BIND_ACTION_LEFT(cbs, name) \
|
||||||
@ -515,6 +516,116 @@ static int playlist_left_thumbnail_mode_left(unsigned type, const char *label,
|
|||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static int manual_content_scan_system_name_left(unsigned type, const char *label,
|
||||||
|
bool wraparound)
|
||||||
|
{
|
||||||
|
struct string_list *system_name_list =
|
||||||
|
manual_content_scan_get_menu_system_name_list();
|
||||||
|
const char *current_system_name = NULL;
|
||||||
|
enum manual_content_scan_system_name_type next_system_name_type =
|
||||||
|
MANUAL_CONTENT_SCAN_SYSTEM_NAME_DATABASE;
|
||||||
|
const char *next_system_name = NULL;
|
||||||
|
unsigned current_index = 0;
|
||||||
|
unsigned next_index = 0;
|
||||||
|
unsigned i;
|
||||||
|
|
||||||
|
if (!system_name_list)
|
||||||
|
return -1;
|
||||||
|
|
||||||
|
/* Get currently selected system name */
|
||||||
|
if (manual_content_scan_get_menu_system_name(¤t_system_name))
|
||||||
|
{
|
||||||
|
/* Get index of currently selected system name */
|
||||||
|
for (i = 0; i < system_name_list->size; i++)
|
||||||
|
{
|
||||||
|
const char *system_name = system_name_list->elems[i].data;
|
||||||
|
|
||||||
|
if (string_is_equal(current_system_name, system_name))
|
||||||
|
{
|
||||||
|
current_index = i;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Decrement index */
|
||||||
|
if (current_index > 0)
|
||||||
|
next_index = current_index - 1;
|
||||||
|
else if (wraparound && (system_name_list->size > 1))
|
||||||
|
next_index = system_name_list->size - 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Get new system name parameters */
|
||||||
|
if (next_index == (unsigned)MANUAL_CONTENT_SCAN_SYSTEM_NAME_CONTENT_DIR)
|
||||||
|
next_system_name_type = MANUAL_CONTENT_SCAN_SYSTEM_NAME_CONTENT_DIR;
|
||||||
|
else if (next_index == (unsigned)MANUAL_CONTENT_SCAN_SYSTEM_NAME_CUSTOM)
|
||||||
|
next_system_name_type = MANUAL_CONTENT_SCAN_SYSTEM_NAME_CUSTOM;
|
||||||
|
|
||||||
|
next_system_name = system_name_list->elems[next_index].data;
|
||||||
|
|
||||||
|
/* Set system name */
|
||||||
|
manual_content_scan_set_menu_system_name(
|
||||||
|
next_system_name_type, next_system_name);
|
||||||
|
|
||||||
|
/* Clean up */
|
||||||
|
string_list_free(system_name_list);
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
static int manual_content_scan_core_name_left(unsigned type, const char *label,
|
||||||
|
bool wraparound)
|
||||||
|
{
|
||||||
|
struct string_list *core_name_list =
|
||||||
|
manual_content_scan_get_menu_core_name_list();
|
||||||
|
const char *current_core_name = NULL;
|
||||||
|
enum manual_content_scan_core_type next_core_type =
|
||||||
|
MANUAL_CONTENT_SCAN_CORE_SET;
|
||||||
|
const char *next_core_name = NULL;
|
||||||
|
unsigned current_index = 0;
|
||||||
|
unsigned next_index = 0;
|
||||||
|
unsigned i;
|
||||||
|
|
||||||
|
if (!core_name_list)
|
||||||
|
return -1;
|
||||||
|
|
||||||
|
/* Get currently selected core name */
|
||||||
|
if (manual_content_scan_get_menu_core_name(¤t_core_name))
|
||||||
|
{
|
||||||
|
/* Get index of currently selected core name */
|
||||||
|
for (i = 0; i < core_name_list->size; i++)
|
||||||
|
{
|
||||||
|
const char *core_name = core_name_list->elems[i].data;
|
||||||
|
|
||||||
|
if (string_is_equal(current_core_name, core_name))
|
||||||
|
{
|
||||||
|
current_index = i;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Decrement index */
|
||||||
|
if (current_index > 0)
|
||||||
|
next_index = current_index - 1;
|
||||||
|
else if (wraparound && (core_name_list->size > 1))
|
||||||
|
next_index = core_name_list->size - 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Get new core name parameters */
|
||||||
|
if (next_index == (unsigned)MANUAL_CONTENT_SCAN_CORE_DETECT)
|
||||||
|
next_core_type = MANUAL_CONTENT_SCAN_CORE_DETECT;
|
||||||
|
|
||||||
|
next_core_name = core_name_list->elems[next_index].data;
|
||||||
|
|
||||||
|
/* Set core name */
|
||||||
|
manual_content_scan_set_menu_core_name(
|
||||||
|
next_core_type, next_core_name);
|
||||||
|
|
||||||
|
/* Clean up */
|
||||||
|
string_list_free(core_name_list);
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
static int core_setting_left(unsigned type, const char *label,
|
static int core_setting_left(unsigned type, const char *label,
|
||||||
bool wraparound)
|
bool wraparound)
|
||||||
{
|
{
|
||||||
@ -766,6 +877,12 @@ static int menu_cbs_init_bind_left_compare_label(menu_file_list_cbs_t *cbs,
|
|||||||
case MENU_ENUM_LABEL_PLAYLIST_MANAGER_LEFT_THUMBNAIL_MODE:
|
case MENU_ENUM_LABEL_PLAYLIST_MANAGER_LEFT_THUMBNAIL_MODE:
|
||||||
BIND_ACTION_LEFT(cbs, playlist_left_thumbnail_mode_left);
|
BIND_ACTION_LEFT(cbs, playlist_left_thumbnail_mode_left);
|
||||||
break;
|
break;
|
||||||
|
case MENU_ENUM_LABEL_MANUAL_CONTENT_SCAN_SYSTEM_NAME:
|
||||||
|
BIND_ACTION_LEFT(cbs, manual_content_scan_system_name_left);
|
||||||
|
break;
|
||||||
|
case MENU_ENUM_LABEL_MANUAL_CONTENT_SCAN_CORE_NAME:
|
||||||
|
BIND_ACTION_LEFT(cbs, manual_content_scan_core_name_left);
|
||||||
|
break;
|
||||||
default:
|
default:
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
@ -861,6 +978,7 @@ static int menu_cbs_init_bind_left_compare_type(menu_file_list_cbs_t *cbs,
|
|||||||
case FILE_TYPE_DOWNLOAD_THUMBNAIL_CONTENT:
|
case FILE_TYPE_DOWNLOAD_THUMBNAIL_CONTENT:
|
||||||
case FILE_TYPE_DOWNLOAD_URL:
|
case FILE_TYPE_DOWNLOAD_URL:
|
||||||
case FILE_TYPE_SCAN_DIRECTORY:
|
case FILE_TYPE_SCAN_DIRECTORY:
|
||||||
|
case FILE_TYPE_MANUAL_SCAN_DIRECTORY:
|
||||||
case FILE_TYPE_FONT:
|
case FILE_TYPE_FONT:
|
||||||
case MENU_SETTING_GROUP:
|
case MENU_SETTING_GROUP:
|
||||||
case MENU_SETTINGS_CORE_INFO_NONE:
|
case MENU_SETTINGS_CORE_INFO_NONE:
|
||||||
|
@ -75,6 +75,7 @@
|
|||||||
#include "../../lakka.h"
|
#include "../../lakka.h"
|
||||||
#include "../../wifi/wifi_driver.h"
|
#include "../../wifi/wifi_driver.h"
|
||||||
#include "../../gfx/video_display_server.h"
|
#include "../../gfx/video_display_server.h"
|
||||||
|
#include "../../manual_content_scan.h"
|
||||||
|
|
||||||
#include <net/net_http.h>
|
#include <net/net_http.h>
|
||||||
|
|
||||||
@ -182,6 +183,10 @@ static enum msg_hash_enums action_ok_dl_to_enum(unsigned lbl)
|
|||||||
return MENU_ENUM_LABEL_DEFERRED_DROPDOWN_BOX_LIST_PLAYLIST_RIGHT_THUMBNAIL_MODE;
|
return MENU_ENUM_LABEL_DEFERRED_DROPDOWN_BOX_LIST_PLAYLIST_RIGHT_THUMBNAIL_MODE;
|
||||||
case ACTION_OK_DL_DROPDOWN_BOX_LIST_PLAYLIST_LEFT_THUMBNAIL_MODE:
|
case ACTION_OK_DL_DROPDOWN_BOX_LIST_PLAYLIST_LEFT_THUMBNAIL_MODE:
|
||||||
return MENU_ENUM_LABEL_DEFERRED_DROPDOWN_BOX_LIST_PLAYLIST_LEFT_THUMBNAIL_MODE;
|
return MENU_ENUM_LABEL_DEFERRED_DROPDOWN_BOX_LIST_PLAYLIST_LEFT_THUMBNAIL_MODE;
|
||||||
|
case ACTION_OK_DL_DROPDOWN_BOX_LIST_MANUAL_CONTENT_SCAN_SYSTEM_NAME:
|
||||||
|
return MENU_ENUM_LABEL_DEFERRED_DROPDOWN_BOX_LIST_MANUAL_CONTENT_SCAN_SYSTEM_NAME;
|
||||||
|
case ACTION_OK_DL_DROPDOWN_BOX_LIST_MANUAL_CONTENT_SCAN_CORE_NAME:
|
||||||
|
return MENU_ENUM_LABEL_DEFERRED_DROPDOWN_BOX_LIST_MANUAL_CONTENT_SCAN_CORE_NAME;
|
||||||
case ACTION_OK_DL_MIXER_STREAM_SETTINGS_LIST:
|
case ACTION_OK_DL_MIXER_STREAM_SETTINGS_LIST:
|
||||||
return MENU_ENUM_LABEL_DEFERRED_MIXER_STREAM_SETTINGS_LIST;
|
return MENU_ENUM_LABEL_DEFERRED_MIXER_STREAM_SETTINGS_LIST;
|
||||||
case ACTION_OK_DL_ACCOUNTS_LIST:
|
case ACTION_OK_DL_ACCOUNTS_LIST:
|
||||||
@ -306,6 +311,8 @@ static enum msg_hash_enums action_ok_dl_to_enum(unsigned lbl)
|
|||||||
return MENU_ENUM_LABEL_DEFERRED_VIDEO_SHADER_PRESET_SAVE_LIST;
|
return MENU_ENUM_LABEL_DEFERRED_VIDEO_SHADER_PRESET_SAVE_LIST;
|
||||||
case ACTION_OK_DL_SHADER_PRESET_REMOVE:
|
case ACTION_OK_DL_SHADER_PRESET_REMOVE:
|
||||||
return MENU_ENUM_LABEL_DEFERRED_VIDEO_SHADER_PRESET_REMOVE_LIST;
|
return MENU_ENUM_LABEL_DEFERRED_VIDEO_SHADER_PRESET_REMOVE_LIST;
|
||||||
|
case ACTION_OK_DL_MANUAL_CONTENT_SCAN_LIST:
|
||||||
|
return MENU_ENUM_LABEL_DEFERRED_MANUAL_CONTENT_SCAN_LIST;
|
||||||
default:
|
default:
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
@ -440,6 +447,24 @@ int generic_action_ok_displaylist_push(const char *path,
|
|||||||
info.enum_idx = MENU_ENUM_LABEL_DEFERRED_DROPDOWN_BOX_LIST_PLAYLIST_LEFT_THUMBNAIL_MODE;
|
info.enum_idx = MENU_ENUM_LABEL_DEFERRED_DROPDOWN_BOX_LIST_PLAYLIST_LEFT_THUMBNAIL_MODE;
|
||||||
dl_type = DISPLAYLIST_GENERIC;
|
dl_type = DISPLAYLIST_GENERIC;
|
||||||
break;
|
break;
|
||||||
|
case ACTION_OK_DL_DROPDOWN_BOX_LIST_MANUAL_CONTENT_SCAN_SYSTEM_NAME:
|
||||||
|
info.type = type;
|
||||||
|
info.directory_ptr = idx;
|
||||||
|
info_path = path;
|
||||||
|
info_label = msg_hash_to_str(
|
||||||
|
MENU_ENUM_LABEL_DEFERRED_DROPDOWN_BOX_LIST_MANUAL_CONTENT_SCAN_SYSTEM_NAME);
|
||||||
|
info.enum_idx = MENU_ENUM_LABEL_DEFERRED_DROPDOWN_BOX_LIST_MANUAL_CONTENT_SCAN_SYSTEM_NAME;
|
||||||
|
dl_type = DISPLAYLIST_GENERIC;
|
||||||
|
break;
|
||||||
|
case ACTION_OK_DL_DROPDOWN_BOX_LIST_MANUAL_CONTENT_SCAN_CORE_NAME:
|
||||||
|
info.type = type;
|
||||||
|
info.directory_ptr = idx;
|
||||||
|
info_path = path;
|
||||||
|
info_label = msg_hash_to_str(
|
||||||
|
MENU_ENUM_LABEL_DEFERRED_DROPDOWN_BOX_LIST_MANUAL_CONTENT_SCAN_CORE_NAME);
|
||||||
|
info.enum_idx = MENU_ENUM_LABEL_DEFERRED_DROPDOWN_BOX_LIST_MANUAL_CONTENT_SCAN_CORE_NAME;
|
||||||
|
dl_type = DISPLAYLIST_GENERIC;
|
||||||
|
break;
|
||||||
case ACTION_OK_DL_USER_BINDS_LIST:
|
case ACTION_OK_DL_USER_BINDS_LIST:
|
||||||
info.type = type;
|
info.type = type;
|
||||||
info.directory_ptr = idx;
|
info.directory_ptr = idx;
|
||||||
@ -600,6 +625,14 @@ int generic_action_ok_displaylist_push(const char *path,
|
|||||||
info_label = label;
|
info_label = label;
|
||||||
dl_type = DISPLAYLIST_FILE_BROWSER_SCAN_DIR;
|
dl_type = DISPLAYLIST_FILE_BROWSER_SCAN_DIR;
|
||||||
break;
|
break;
|
||||||
|
case ACTION_OK_DL_MANUAL_SCAN_DIR_LIST:
|
||||||
|
filebrowser_set_type(FILEBROWSER_MANUAL_SCAN_DIR);
|
||||||
|
info.type = FILE_TYPE_DIRECTORY;
|
||||||
|
info.directory_ptr = idx;
|
||||||
|
info_path = new_path;
|
||||||
|
info_label = label;
|
||||||
|
dl_type = DISPLAYLIST_FILE_BROWSER_SELECT_DIR;
|
||||||
|
break;
|
||||||
case ACTION_OK_DL_REMAP_FILE:
|
case ACTION_OK_DL_REMAP_FILE:
|
||||||
filebrowser_clear_type();
|
filebrowser_clear_type();
|
||||||
info.type = type;
|
info.type = type;
|
||||||
@ -1019,6 +1052,7 @@ int generic_action_ok_displaylist_push(const char *path,
|
|||||||
case ACTION_OK_DL_SHADER_PRESET_REMOVE:
|
case ACTION_OK_DL_SHADER_PRESET_REMOVE:
|
||||||
case ACTION_OK_DL_SHADER_PRESET_SAVE:
|
case ACTION_OK_DL_SHADER_PRESET_SAVE:
|
||||||
case ACTION_OK_DL_CDROM_INFO_LIST:
|
case ACTION_OK_DL_CDROM_INFO_LIST:
|
||||||
|
case ACTION_OK_DL_MANUAL_CONTENT_SCAN_LIST:
|
||||||
action_ok_dl_lbl(action_ok_dl_to_enum(action_type), DISPLAYLIST_GENERIC);
|
action_ok_dl_lbl(action_ok_dl_to_enum(action_type), DISPLAYLIST_GENERIC);
|
||||||
break;
|
break;
|
||||||
case ACTION_OK_DL_CDROM_INFO_DETAIL_LIST:
|
case ACTION_OK_DL_CDROM_INFO_DETAIL_LIST:
|
||||||
@ -2989,6 +3023,47 @@ static int action_ok_path_scan_directory(const char *path,
|
|||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
static int action_ok_path_manual_scan_directory(const char *path,
|
||||||
|
const char *label, unsigned type, size_t idx, size_t entry_idx)
|
||||||
|
{
|
||||||
|
const char *flush_char = msg_hash_to_str(MENU_ENUM_LABEL_DEFERRED_MANUAL_CONTENT_SCAN_LIST);
|
||||||
|
unsigned flush_type = 0;
|
||||||
|
const char *menu_path = NULL;
|
||||||
|
char content_dir[PATH_MAX_LENGTH];
|
||||||
|
|
||||||
|
content_dir[0] = '\0';
|
||||||
|
|
||||||
|
/* 'Reset' file browser */
|
||||||
|
filebrowser_clear_type();
|
||||||
|
|
||||||
|
/* Get user-selected scan directory */
|
||||||
|
menu_entries_get_last_stack(&menu_path,
|
||||||
|
NULL, NULL, NULL, NULL);
|
||||||
|
|
||||||
|
if (!string_is_empty(menu_path))
|
||||||
|
strlcpy(content_dir, menu_path, sizeof(content_dir));
|
||||||
|
|
||||||
|
#ifdef HAVE_COCOATOUCH
|
||||||
|
{
|
||||||
|
/* For iOS, set the path using realpath because the path name
|
||||||
|
* can start with /private and this ensures the path starts with it.
|
||||||
|
* This will allow the path to be properly substituted when
|
||||||
|
* fill_pathname_expand_special() is called. */
|
||||||
|
char real_content_dir[PATH_MAX_LENGTH] = {0};
|
||||||
|
realpath(content_dir, real_content_dir);
|
||||||
|
strlcpy(content_dir, real_content_dir, sizeof(content_dir));
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/* Update manual content scan settings */
|
||||||
|
manual_content_scan_set_menu_content_dir(content_dir);
|
||||||
|
|
||||||
|
/* Return to 'manual content scan' menu */
|
||||||
|
menu_entries_flush_stack(flush_char, flush_type);
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
static int action_ok_core_deferred_set(const char *new_core_path,
|
static int action_ok_core_deferred_set(const char *new_core_path,
|
||||||
const char *content_label, unsigned type, size_t idx, size_t entry_idx)
|
const char *content_label, unsigned type, size_t idx, size_t entry_idx)
|
||||||
{
|
{
|
||||||
@ -4671,6 +4746,7 @@ default_action_ok_func(action_ok_push_load_disc_list, ACTION_OK_DL_LOAD_DISC_LIS
|
|||||||
default_action_ok_func(action_ok_open_archive, ACTION_OK_DL_OPEN_ARCHIVE)
|
default_action_ok_func(action_ok_open_archive, ACTION_OK_DL_OPEN_ARCHIVE)
|
||||||
default_action_ok_func(action_ok_rgui_menu_theme_preset, ACTION_OK_DL_RGUI_MENU_THEME_PRESET)
|
default_action_ok_func(action_ok_rgui_menu_theme_preset, ACTION_OK_DL_RGUI_MENU_THEME_PRESET)
|
||||||
default_action_ok_func(action_ok_pl_thumbnails_updater_list, ACTION_OK_DL_PL_THUMBNAILS_UPDATER_LIST)
|
default_action_ok_func(action_ok_pl_thumbnails_updater_list, ACTION_OK_DL_PL_THUMBNAILS_UPDATER_LIST)
|
||||||
|
default_action_ok_func(action_ok_push_manual_content_scan_list, ACTION_OK_DL_MANUAL_CONTENT_SCAN_LIST)
|
||||||
|
|
||||||
static int action_ok_open_uwp_permission_settings(const char *path,
|
static int action_ok_open_uwp_permission_settings(const char *path,
|
||||||
const char *label, unsigned type, size_t idx, size_t entry_idx)
|
const char *label, unsigned type, size_t idx, size_t entry_idx)
|
||||||
@ -5161,6 +5237,17 @@ int action_ok_push_filebrowser_list_file_select(const char *path,
|
|||||||
entry_idx, ACTION_OK_DL_FILE_BROWSER_SELECT_DIR);
|
entry_idx, ACTION_OK_DL_FILE_BROWSER_SELECT_DIR);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
int action_ok_push_manual_content_scan_dir_select(const char *path,
|
||||||
|
const char *label, unsigned type, size_t idx, size_t entry_idx)
|
||||||
|
{
|
||||||
|
settings_t *settings = config_get_ptr();
|
||||||
|
|
||||||
|
filebrowser_clear_type();
|
||||||
|
return generic_action_ok_displaylist_push(path,
|
||||||
|
settings->paths.directory_menu_content, label, type, idx,
|
||||||
|
entry_idx, ACTION_OK_DL_MANUAL_SCAN_DIR_LIST);
|
||||||
|
}
|
||||||
|
|
||||||
/* TODO/FIXME */
|
/* TODO/FIXME */
|
||||||
static int action_ok_push_dropdown_setting_core_options_item_special(const char *path,
|
static int action_ok_push_dropdown_setting_core_options_item_special(const char *path,
|
||||||
const char *label, unsigned type, size_t idx, size_t entry_idx)
|
const char *label, unsigned type, size_t idx, size_t entry_idx)
|
||||||
@ -5532,6 +5619,54 @@ static int action_ok_push_dropdown_item_playlist_left_thumbnail_mode(const char
|
|||||||
return action_cancel_pop_default(NULL, NULL, 0, 0);
|
return action_cancel_pop_default(NULL, NULL, 0, 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static int action_ok_push_dropdown_item_manual_content_scan_system_name(const char *path,
|
||||||
|
const char *label, unsigned type, size_t idx, size_t entry_idx)
|
||||||
|
{
|
||||||
|
const char* system_name = path;
|
||||||
|
enum manual_content_scan_system_name_type system_name_type =
|
||||||
|
MANUAL_CONTENT_SCAN_SYSTEM_NAME_DATABASE;
|
||||||
|
|
||||||
|
(void)label;
|
||||||
|
(void)type;
|
||||||
|
(void)entry_idx;
|
||||||
|
|
||||||
|
/* Get system name type (i.e. check if setting is
|
||||||
|
* 'use content directory' or 'use custom') */
|
||||||
|
if (idx == (size_t)MANUAL_CONTENT_SCAN_SYSTEM_NAME_CONTENT_DIR)
|
||||||
|
system_name_type = MANUAL_CONTENT_SCAN_SYSTEM_NAME_CONTENT_DIR;
|
||||||
|
else if (idx == (size_t)MANUAL_CONTENT_SCAN_SYSTEM_NAME_CUSTOM)
|
||||||
|
system_name_type = MANUAL_CONTENT_SCAN_SYSTEM_NAME_CUSTOM;
|
||||||
|
|
||||||
|
/* Set system name */
|
||||||
|
manual_content_scan_set_menu_system_name(
|
||||||
|
system_name_type, system_name);
|
||||||
|
|
||||||
|
return action_cancel_pop_default(NULL, NULL, 0, 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
static int action_ok_push_dropdown_item_manual_content_scan_core_name(const char *path,
|
||||||
|
const char *label, unsigned type, size_t idx, size_t entry_idx)
|
||||||
|
{
|
||||||
|
const char* core_name = path;
|
||||||
|
enum manual_content_scan_core_type core_type =
|
||||||
|
MANUAL_CONTENT_SCAN_CORE_SET;
|
||||||
|
|
||||||
|
(void)label;
|
||||||
|
(void)type;
|
||||||
|
(void)entry_idx;
|
||||||
|
|
||||||
|
/* Get core type (i.e. check if setting is
|
||||||
|
* DETECT/Unspecified) */
|
||||||
|
if (idx == (size_t)MANUAL_CONTENT_SCAN_CORE_DETECT)
|
||||||
|
core_type = MANUAL_CONTENT_SCAN_CORE_DETECT;
|
||||||
|
|
||||||
|
/* Set core name */
|
||||||
|
manual_content_scan_set_menu_core_name(
|
||||||
|
core_type, core_name);
|
||||||
|
|
||||||
|
return action_cancel_pop_default(NULL, NULL, 0, 0);
|
||||||
|
}
|
||||||
|
|
||||||
static int action_ok_push_default(const char *path,
|
static int action_ok_push_default(const char *path,
|
||||||
const char *label, unsigned type, size_t idx, size_t entry_idx)
|
const char *label, unsigned type, size_t idx, size_t entry_idx)
|
||||||
{
|
{
|
||||||
@ -5750,6 +5885,33 @@ static int action_ok_playlist_left_thumbnail_mode(const char *path,
|
|||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static int action_ok_manual_content_scan_system_name(const char *path,
|
||||||
|
const char *label, unsigned type, size_t idx, size_t entry_idx)
|
||||||
|
{
|
||||||
|
generic_action_ok_displaylist_push(
|
||||||
|
NULL,
|
||||||
|
NULL, NULL, 0, idx, 0,
|
||||||
|
ACTION_OK_DL_DROPDOWN_BOX_LIST_MANUAL_CONTENT_SCAN_SYSTEM_NAME);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
static int action_ok_manual_content_scan_core_name(const char *path,
|
||||||
|
const char *label, unsigned type, size_t idx, size_t entry_idx)
|
||||||
|
{
|
||||||
|
generic_action_ok_displaylist_push(
|
||||||
|
NULL,
|
||||||
|
NULL, NULL, 0, idx, 0,
|
||||||
|
ACTION_OK_DL_DROPDOWN_BOX_LIST_MANUAL_CONTENT_SCAN_CORE_NAME);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
static int action_ok_manual_content_scan_start(const char *path,
|
||||||
|
const char *label, unsigned type, size_t idx, size_t entry_idx)
|
||||||
|
{
|
||||||
|
task_push_manual_content_scan();
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
static int action_ok_netplay_enable_host(const char *path,
|
static int action_ok_netplay_enable_host(const char *path,
|
||||||
const char *label, unsigned type, size_t idx, size_t entry_idx)
|
const char *label, unsigned type, size_t idx, size_t entry_idx)
|
||||||
{
|
{
|
||||||
@ -6698,6 +6860,21 @@ static int menu_cbs_init_bind_ok_compare_label(menu_file_list_cbs_t *cbs,
|
|||||||
case MENU_ENUM_LABEL_ACHIEVEMENT_RESUME:
|
case MENU_ENUM_LABEL_ACHIEVEMENT_RESUME:
|
||||||
BIND_ACTION_OK(cbs, action_ok_cheevos_toggle_hardcore_mode);
|
BIND_ACTION_OK(cbs, action_ok_cheevos_toggle_hardcore_mode);
|
||||||
break;
|
break;
|
||||||
|
case MENU_ENUM_LABEL_MANUAL_CONTENT_SCAN_LIST:
|
||||||
|
BIND_ACTION_OK(cbs, action_ok_push_manual_content_scan_list);
|
||||||
|
break;
|
||||||
|
case MENU_ENUM_LABEL_MANUAL_CONTENT_SCAN_DIR:
|
||||||
|
BIND_ACTION_OK(cbs, action_ok_push_manual_content_scan_dir_select);
|
||||||
|
break;
|
||||||
|
case MENU_ENUM_LABEL_MANUAL_CONTENT_SCAN_SYSTEM_NAME:
|
||||||
|
BIND_ACTION_OK(cbs, action_ok_manual_content_scan_system_name);
|
||||||
|
break;
|
||||||
|
case MENU_ENUM_LABEL_MANUAL_CONTENT_SCAN_CORE_NAME:
|
||||||
|
BIND_ACTION_OK(cbs, action_ok_manual_content_scan_core_name);
|
||||||
|
break;
|
||||||
|
case MENU_ENUM_LABEL_MANUAL_CONTENT_SCAN_START:
|
||||||
|
BIND_ACTION_OK(cbs, action_ok_manual_content_scan_start);
|
||||||
|
break;
|
||||||
default:
|
default:
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
@ -6826,6 +7003,12 @@ static int menu_cbs_init_bind_ok_compare_label(menu_file_list_cbs_t *cbs,
|
|||||||
case MENU_LABEL_PLAYLIST_MANAGER_LEFT_THUMBNAIL_MODE:
|
case MENU_LABEL_PLAYLIST_MANAGER_LEFT_THUMBNAIL_MODE:
|
||||||
BIND_ACTION_OK(cbs, action_ok_playlist_left_thumbnail_mode);
|
BIND_ACTION_OK(cbs, action_ok_playlist_left_thumbnail_mode);
|
||||||
break;
|
break;
|
||||||
|
case MENU_LABEL_MANUAL_CONTENT_SCAN_SYSTEM_NAME:
|
||||||
|
BIND_ACTION_OK(cbs, action_ok_manual_content_scan_system_name);
|
||||||
|
break;
|
||||||
|
case MENU_LABEL_MANUAL_CONTENT_SCAN_CORE_NAME:
|
||||||
|
BIND_ACTION_OK(cbs, action_ok_manual_content_scan_core_name);
|
||||||
|
break;
|
||||||
default:
|
default:
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
@ -6958,6 +7141,12 @@ static int menu_cbs_init_bind_ok_compare_type(menu_file_list_cbs_t *cbs,
|
|||||||
case MENU_SETTING_DROPDOWN_ITEM_PLAYLIST_LEFT_THUMBNAIL_MODE:
|
case MENU_SETTING_DROPDOWN_ITEM_PLAYLIST_LEFT_THUMBNAIL_MODE:
|
||||||
BIND_ACTION_OK(cbs, action_ok_push_dropdown_item_playlist_left_thumbnail_mode);
|
BIND_ACTION_OK(cbs, action_ok_push_dropdown_item_playlist_left_thumbnail_mode);
|
||||||
break;
|
break;
|
||||||
|
case MENU_SETTING_DROPDOWN_ITEM_MANUAL_CONTENT_SCAN_SYSTEM_NAME:
|
||||||
|
BIND_ACTION_OK(cbs, action_ok_push_dropdown_item_manual_content_scan_system_name);
|
||||||
|
break;
|
||||||
|
case MENU_SETTING_DROPDOWN_ITEM_MANUAL_CONTENT_SCAN_CORE_NAME:
|
||||||
|
BIND_ACTION_OK(cbs, action_ok_push_dropdown_item_manual_content_scan_core_name);
|
||||||
|
break;
|
||||||
case MENU_SETTING_ACTION_CORE_DISK_OPTIONS:
|
case MENU_SETTING_ACTION_CORE_DISK_OPTIONS:
|
||||||
BIND_ACTION_OK(cbs, action_ok_push_default);
|
BIND_ACTION_OK(cbs, action_ok_push_default);
|
||||||
break;
|
break;
|
||||||
@ -7043,6 +7232,9 @@ static int menu_cbs_init_bind_ok_compare_type(menu_file_list_cbs_t *cbs,
|
|||||||
BIND_ACTION_OK(cbs, action_ok_path_scan_directory);
|
BIND_ACTION_OK(cbs, action_ok_path_scan_directory);
|
||||||
break;
|
break;
|
||||||
#endif
|
#endif
|
||||||
|
case FILE_TYPE_MANUAL_SCAN_DIRECTORY:
|
||||||
|
BIND_ACTION_OK(cbs, action_ok_path_manual_scan_directory);
|
||||||
|
break;
|
||||||
case FILE_TYPE_CONFIG:
|
case FILE_TYPE_CONFIG:
|
||||||
BIND_ACTION_OK(cbs, action_ok_config_load);
|
BIND_ACTION_OK(cbs, action_ok_config_load);
|
||||||
break;
|
break;
|
||||||
|
@ -42,6 +42,7 @@
|
|||||||
#include "../../ui/ui_companion_driver.h"
|
#include "../../ui/ui_companion_driver.h"
|
||||||
#include "../../network/netplay/netplay.h"
|
#include "../../network/netplay/netplay.h"
|
||||||
#include "../../playlist.h"
|
#include "../../playlist.h"
|
||||||
|
#include "../../manual_content_scan.h"
|
||||||
|
|
||||||
#ifndef BIND_ACTION_RIGHT
|
#ifndef BIND_ACTION_RIGHT
|
||||||
#define BIND_ACTION_RIGHT(cbs, name) \
|
#define BIND_ACTION_RIGHT(cbs, name) \
|
||||||
@ -628,6 +629,134 @@ static int playlist_left_thumbnail_mode_right(unsigned type, const char *label,
|
|||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static int manual_content_scan_system_name_right(unsigned type, const char *label,
|
||||||
|
bool wraparound)
|
||||||
|
{
|
||||||
|
struct string_list *system_name_list =
|
||||||
|
manual_content_scan_get_menu_system_name_list();
|
||||||
|
const char *current_system_name = NULL;
|
||||||
|
enum manual_content_scan_system_name_type next_system_name_type =
|
||||||
|
MANUAL_CONTENT_SCAN_SYSTEM_NAME_DATABASE;
|
||||||
|
const char *next_system_name = NULL;
|
||||||
|
unsigned current_index = 0;
|
||||||
|
unsigned next_index = 0;
|
||||||
|
unsigned i;
|
||||||
|
|
||||||
|
if (!system_name_list)
|
||||||
|
return -1;
|
||||||
|
|
||||||
|
/* Get currently selected system name */
|
||||||
|
if (manual_content_scan_get_menu_system_name(¤t_system_name))
|
||||||
|
{
|
||||||
|
/* Get index of currently selected system name */
|
||||||
|
for (i = 0; i < system_name_list->size; i++)
|
||||||
|
{
|
||||||
|
const char *system_name = system_name_list->elems[i].data;
|
||||||
|
|
||||||
|
if (string_is_equal(current_system_name, system_name))
|
||||||
|
{
|
||||||
|
current_index = i;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Increment index */
|
||||||
|
next_index = current_index + 1;
|
||||||
|
if (next_index >= system_name_list->size)
|
||||||
|
{
|
||||||
|
if (wraparound)
|
||||||
|
next_index = 0;
|
||||||
|
else
|
||||||
|
{
|
||||||
|
if (system_name_list->size > 0)
|
||||||
|
next_index = system_name_list->size - 1;
|
||||||
|
else
|
||||||
|
next_index = 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Get new system name parameters */
|
||||||
|
if (next_index == (unsigned)MANUAL_CONTENT_SCAN_SYSTEM_NAME_CONTENT_DIR)
|
||||||
|
next_system_name_type = MANUAL_CONTENT_SCAN_SYSTEM_NAME_CONTENT_DIR;
|
||||||
|
else if (next_index == (unsigned)MANUAL_CONTENT_SCAN_SYSTEM_NAME_CUSTOM)
|
||||||
|
next_system_name_type = MANUAL_CONTENT_SCAN_SYSTEM_NAME_CUSTOM;
|
||||||
|
|
||||||
|
next_system_name = system_name_list->elems[next_index].data;
|
||||||
|
|
||||||
|
/* Set system name */
|
||||||
|
manual_content_scan_set_menu_system_name(
|
||||||
|
next_system_name_type, next_system_name);
|
||||||
|
|
||||||
|
/* Clean up */
|
||||||
|
string_list_free(system_name_list);
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
static int manual_content_scan_core_name_right(unsigned type, const char *label,
|
||||||
|
bool wraparound)
|
||||||
|
{
|
||||||
|
struct string_list *core_name_list =
|
||||||
|
manual_content_scan_get_menu_core_name_list();
|
||||||
|
const char *current_core_name = NULL;
|
||||||
|
enum manual_content_scan_core_type next_core_type =
|
||||||
|
MANUAL_CONTENT_SCAN_CORE_SET;
|
||||||
|
const char *next_core_name = NULL;
|
||||||
|
unsigned current_index = 0;
|
||||||
|
unsigned next_index = 0;
|
||||||
|
unsigned i;
|
||||||
|
|
||||||
|
if (!core_name_list)
|
||||||
|
return -1;
|
||||||
|
|
||||||
|
/* Get currently selected core name */
|
||||||
|
if (manual_content_scan_get_menu_core_name(¤t_core_name))
|
||||||
|
{
|
||||||
|
/* Get index of currently selected core name */
|
||||||
|
for (i = 0; i < core_name_list->size; i++)
|
||||||
|
{
|
||||||
|
const char *core_name = core_name_list->elems[i].data;
|
||||||
|
|
||||||
|
if (string_is_equal(current_core_name, core_name))
|
||||||
|
{
|
||||||
|
current_index = i;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Increment index */
|
||||||
|
next_index = current_index + 1;
|
||||||
|
if (next_index >= core_name_list->size)
|
||||||
|
{
|
||||||
|
if (wraparound)
|
||||||
|
next_index = 0;
|
||||||
|
else
|
||||||
|
{
|
||||||
|
if (core_name_list->size > 0)
|
||||||
|
next_index = core_name_list->size - 1;
|
||||||
|
else
|
||||||
|
next_index = 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Get new core name parameters */
|
||||||
|
if (next_index == (unsigned)MANUAL_CONTENT_SCAN_CORE_DETECT)
|
||||||
|
next_core_type = MANUAL_CONTENT_SCAN_CORE_DETECT;
|
||||||
|
|
||||||
|
next_core_name = core_name_list->elems[next_index].data;
|
||||||
|
|
||||||
|
/* Set core name */
|
||||||
|
manual_content_scan_set_menu_core_name(
|
||||||
|
next_core_type, next_core_name);
|
||||||
|
|
||||||
|
/* Clean up */
|
||||||
|
string_list_free(core_name_list);
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
int core_setting_right(unsigned type, const char *label,
|
int core_setting_right(unsigned type, const char *label,
|
||||||
bool wraparound)
|
bool wraparound)
|
||||||
{
|
{
|
||||||
@ -735,6 +864,7 @@ static int menu_cbs_init_bind_right_compare_type(menu_file_list_cbs_t *cbs,
|
|||||||
case FILE_TYPE_DOWNLOAD_THUMBNAIL_CONTENT:
|
case FILE_TYPE_DOWNLOAD_THUMBNAIL_CONTENT:
|
||||||
case FILE_TYPE_DOWNLOAD_URL:
|
case FILE_TYPE_DOWNLOAD_URL:
|
||||||
case FILE_TYPE_SCAN_DIRECTORY:
|
case FILE_TYPE_SCAN_DIRECTORY:
|
||||||
|
case FILE_TYPE_MANUAL_SCAN_DIRECTORY:
|
||||||
case FILE_TYPE_FONT:
|
case FILE_TYPE_FONT:
|
||||||
case MENU_SETTING_GROUP:
|
case MENU_SETTING_GROUP:
|
||||||
case MENU_SETTINGS_CORE_INFO_NONE:
|
case MENU_SETTINGS_CORE_INFO_NONE:
|
||||||
@ -915,6 +1045,12 @@ static int menu_cbs_init_bind_right_compare_label(menu_file_list_cbs_t *cbs,
|
|||||||
case MENU_ENUM_LABEL_PLAYLIST_MANAGER_LEFT_THUMBNAIL_MODE:
|
case MENU_ENUM_LABEL_PLAYLIST_MANAGER_LEFT_THUMBNAIL_MODE:
|
||||||
BIND_ACTION_RIGHT(cbs, playlist_left_thumbnail_mode_right);
|
BIND_ACTION_RIGHT(cbs, playlist_left_thumbnail_mode_right);
|
||||||
break;
|
break;
|
||||||
|
case MENU_ENUM_LABEL_MANUAL_CONTENT_SCAN_SYSTEM_NAME:
|
||||||
|
BIND_ACTION_RIGHT(cbs, manual_content_scan_system_name_right);
|
||||||
|
break;
|
||||||
|
case MENU_ENUM_LABEL_MANUAL_CONTENT_SCAN_CORE_NAME:
|
||||||
|
BIND_ACTION_RIGHT(cbs, manual_content_scan_core_name_right);
|
||||||
|
break;
|
||||||
default:
|
default:
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
@ -38,6 +38,7 @@
|
|||||||
#include "../../retroarch.h"
|
#include "../../retroarch.h"
|
||||||
#include "../../performance_counters.h"
|
#include "../../performance_counters.h"
|
||||||
#include "../../playlist.h"
|
#include "../../playlist.h"
|
||||||
|
#include "../../manual_content_scan.h"
|
||||||
|
|
||||||
#include "../../input/input_remapping.h"
|
#include "../../input/input_remapping.h"
|
||||||
|
|
||||||
@ -302,6 +303,29 @@ static int action_start_playlist_left_thumbnail_mode(unsigned type, const char *
|
|||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static int action_start_manual_content_scan_dir(unsigned type, const char *label)
|
||||||
|
{
|
||||||
|
/* Reset content directory */
|
||||||
|
manual_content_scan_set_menu_content_dir("");
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
static int action_start_manual_content_scan_system_name(unsigned type, const char *label)
|
||||||
|
{
|
||||||
|
/* Reset system name */
|
||||||
|
manual_content_scan_set_menu_system_name(
|
||||||
|
MANUAL_CONTENT_SCAN_SYSTEM_NAME_CONTENT_DIR, "");
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
static int action_start_manual_content_scan_core_name(unsigned type, const char *label)
|
||||||
|
{
|
||||||
|
/* Reset core name */
|
||||||
|
manual_content_scan_set_menu_core_name(
|
||||||
|
MANUAL_CONTENT_SCAN_CORE_DETECT, "");
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
static int action_start_video_resolution(unsigned type, const char *label)
|
static int action_start_video_resolution(unsigned type, const char *label)
|
||||||
{
|
{
|
||||||
unsigned width = 0, height = 0;
|
unsigned width = 0, height = 0;
|
||||||
@ -405,6 +429,15 @@ static int menu_cbs_init_bind_start_compare_label(menu_file_list_cbs_t *cbs)
|
|||||||
case MENU_ENUM_LABEL_PLAYLIST_MANAGER_LEFT_THUMBNAIL_MODE:
|
case MENU_ENUM_LABEL_PLAYLIST_MANAGER_LEFT_THUMBNAIL_MODE:
|
||||||
BIND_ACTION_START(cbs, action_start_playlist_left_thumbnail_mode);
|
BIND_ACTION_START(cbs, action_start_playlist_left_thumbnail_mode);
|
||||||
break;
|
break;
|
||||||
|
case MENU_ENUM_LABEL_MANUAL_CONTENT_SCAN_DIR:
|
||||||
|
BIND_ACTION_START(cbs, action_start_manual_content_scan_dir);
|
||||||
|
break;
|
||||||
|
case MENU_ENUM_LABEL_MANUAL_CONTENT_SCAN_SYSTEM_NAME:
|
||||||
|
BIND_ACTION_START(cbs, action_start_manual_content_scan_system_name);
|
||||||
|
break;
|
||||||
|
case MENU_ENUM_LABEL_MANUAL_CONTENT_SCAN_CORE_NAME:
|
||||||
|
BIND_ACTION_START(cbs, action_start_manual_content_scan_core_name);
|
||||||
|
break;
|
||||||
default:
|
default:
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
@ -714,6 +714,14 @@ default_sublabel_macro(action_bind_sublabel_thumbnails_updater_list,
|
|||||||
default_sublabel_macro(action_bind_sublabel_pl_thumbnails_updater_list, MENU_ENUM_SUBLABEL_PL_THUMBNAILS_UPDATER_LIST)
|
default_sublabel_macro(action_bind_sublabel_pl_thumbnails_updater_list, MENU_ENUM_SUBLABEL_PL_THUMBNAILS_UPDATER_LIST)
|
||||||
default_sublabel_macro(action_bind_sublabel_help_send_debug_info, MENU_ENUM_SUBLABEL_HELP_SEND_DEBUG_INFO)
|
default_sublabel_macro(action_bind_sublabel_help_send_debug_info, MENU_ENUM_SUBLABEL_HELP_SEND_DEBUG_INFO)
|
||||||
default_sublabel_macro(action_bind_sublabel_rdb_entry_detail, MENU_ENUM_SUBLABEL_RDB_ENTRY_DETAIL)
|
default_sublabel_macro(action_bind_sublabel_rdb_entry_detail, MENU_ENUM_SUBLABEL_RDB_ENTRY_DETAIL)
|
||||||
|
default_sublabel_macro(action_bind_sublabel_manual_content_scan_list, MENU_ENUM_SUBLABEL_MANUAL_CONTENT_SCAN_LIST)
|
||||||
|
default_sublabel_macro(action_bind_sublabel_manual_content_scan_dir, MENU_ENUM_SUBLABEL_MANUAL_CONTENT_SCAN_DIR)
|
||||||
|
default_sublabel_macro(action_bind_sublabel_manual_content_scan_system_name, MENU_ENUM_SUBLABEL_MANUAL_CONTENT_SCAN_SYSTEM_NAME)
|
||||||
|
default_sublabel_macro(action_bind_sublabel_manual_content_scan_system_name_custom, MENU_ENUM_SUBLABEL_MANUAL_CONTENT_SCAN_SYSTEM_NAME_CUSTOM)
|
||||||
|
default_sublabel_macro(action_bind_sublabel_manual_content_scan_core_name, MENU_ENUM_SUBLABEL_MANUAL_CONTENT_SCAN_CORE_NAME)
|
||||||
|
default_sublabel_macro(action_bind_sublabel_manual_content_scan_file_exts, MENU_ENUM_SUBLABEL_MANUAL_CONTENT_SCAN_FILE_EXTS)
|
||||||
|
default_sublabel_macro(action_bind_sublabel_manual_content_scan_overwrite, MENU_ENUM_SUBLABEL_MANUAL_CONTENT_SCAN_OVERWRITE)
|
||||||
|
default_sublabel_macro(action_bind_sublabel_manual_content_scan_start, MENU_ENUM_SUBLABEL_MANUAL_CONTENT_SCAN_START)
|
||||||
|
|
||||||
static int action_bind_sublabel_systeminfo_controller_entry(
|
static int action_bind_sublabel_systeminfo_controller_entry(
|
||||||
file_list_t *list,
|
file_list_t *list,
|
||||||
@ -3049,6 +3057,30 @@ int menu_cbs_init_bind_sublabel(menu_file_list_cbs_t *cbs,
|
|||||||
case MENU_ENUM_LABEL_RDB_ENTRY_DETAIL:
|
case MENU_ENUM_LABEL_RDB_ENTRY_DETAIL:
|
||||||
BIND_ACTION_SUBLABEL(cbs, action_bind_sublabel_rdb_entry_detail);
|
BIND_ACTION_SUBLABEL(cbs, action_bind_sublabel_rdb_entry_detail);
|
||||||
break;
|
break;
|
||||||
|
case MENU_ENUM_LABEL_MANUAL_CONTENT_SCAN_LIST:
|
||||||
|
BIND_ACTION_SUBLABEL(cbs, action_bind_sublabel_manual_content_scan_list);
|
||||||
|
break;
|
||||||
|
case MENU_ENUM_LABEL_MANUAL_CONTENT_SCAN_DIR:
|
||||||
|
BIND_ACTION_SUBLABEL(cbs, action_bind_sublabel_manual_content_scan_dir);
|
||||||
|
break;
|
||||||
|
case MENU_ENUM_LABEL_MANUAL_CONTENT_SCAN_SYSTEM_NAME:
|
||||||
|
BIND_ACTION_SUBLABEL(cbs, action_bind_sublabel_manual_content_scan_system_name);
|
||||||
|
break;
|
||||||
|
case MENU_ENUM_LABEL_MANUAL_CONTENT_SCAN_SYSTEM_NAME_CUSTOM:
|
||||||
|
BIND_ACTION_SUBLABEL(cbs, action_bind_sublabel_manual_content_scan_system_name_custom);
|
||||||
|
break;
|
||||||
|
case MENU_ENUM_LABEL_MANUAL_CONTENT_SCAN_CORE_NAME:
|
||||||
|
BIND_ACTION_SUBLABEL(cbs, action_bind_sublabel_manual_content_scan_core_name);
|
||||||
|
break;
|
||||||
|
case MENU_ENUM_LABEL_MANUAL_CONTENT_SCAN_FILE_EXTS:
|
||||||
|
BIND_ACTION_SUBLABEL(cbs, action_bind_sublabel_manual_content_scan_file_exts);
|
||||||
|
break;
|
||||||
|
case MENU_ENUM_LABEL_MANUAL_CONTENT_SCAN_OVERWRITE:
|
||||||
|
BIND_ACTION_SUBLABEL(cbs, action_bind_sublabel_manual_content_scan_overwrite);
|
||||||
|
break;
|
||||||
|
case MENU_ENUM_LABEL_MANUAL_CONTENT_SCAN_START:
|
||||||
|
BIND_ACTION_SUBLABEL(cbs, action_bind_sublabel_manual_content_scan_start);
|
||||||
|
break;
|
||||||
default:
|
default:
|
||||||
case MSG_UNKNOWN:
|
case MSG_UNKNOWN:
|
||||||
return -1;
|
return -1;
|
||||||
|
@ -65,6 +65,8 @@ static int action_get_title_action_generic(const char *path, const char *label,
|
|||||||
const char *title = msg_hash_to_str(lbl); \
|
const char *title = msg_hash_to_str(lbl); \
|
||||||
if (!string_is_empty(path) && !string_is_empty(title)) \
|
if (!string_is_empty(path) && !string_is_empty(title)) \
|
||||||
fill_pathname_join_delim(s, title, path, ' ', len); \
|
fill_pathname_join_delim(s, title, path, ' ', len); \
|
||||||
|
else if (!string_is_empty(title)) \
|
||||||
|
strlcpy(s, title, len); \
|
||||||
return 1; \
|
return 1; \
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -396,10 +398,12 @@ default_title_macro(action_get_title_goto_music, MENU_ENUM_LABEL_
|
|||||||
default_title_macro(action_get_title_goto_video, MENU_ENUM_LABEL_VALUE_GOTO_VIDEO)
|
default_title_macro(action_get_title_goto_video, MENU_ENUM_LABEL_VALUE_GOTO_VIDEO)
|
||||||
default_title_macro(action_get_title_collection, MENU_ENUM_LABEL_VALUE_PLAYLISTS_TAB)
|
default_title_macro(action_get_title_collection, MENU_ENUM_LABEL_VALUE_PLAYLISTS_TAB)
|
||||||
default_title_macro(action_get_title_deferred_core_list, MENU_ENUM_LABEL_VALUE_SUPPORTED_CORES)
|
default_title_macro(action_get_title_deferred_core_list, MENU_ENUM_LABEL_VALUE_SUPPORTED_CORES)
|
||||||
|
|
||||||
default_title_macro(action_get_title_dropdown_resolution_item, MENU_ENUM_LABEL_VALUE_SCREEN_RESOLUTION)
|
default_title_macro(action_get_title_dropdown_resolution_item, MENU_ENUM_LABEL_VALUE_SCREEN_RESOLUTION)
|
||||||
default_title_macro(action_get_title_dropdown_playlist_default_core_item, MENU_ENUM_LABEL_VALUE_PLAYLIST_MANAGER_DEFAULT_CORE)
|
default_title_macro(action_get_title_dropdown_playlist_default_core_item, MENU_ENUM_LABEL_VALUE_PLAYLIST_MANAGER_DEFAULT_CORE)
|
||||||
default_title_macro(action_get_title_dropdown_playlist_label_display_mode_item, MENU_ENUM_LABEL_VALUE_PLAYLIST_MANAGER_LABEL_DISPLAY_MODE)
|
default_title_macro(action_get_title_dropdown_playlist_label_display_mode_item, MENU_ENUM_LABEL_VALUE_PLAYLIST_MANAGER_LABEL_DISPLAY_MODE)
|
||||||
|
default_title_macro(action_get_title_manual_content_scan_list, MENU_ENUM_LABEL_VALUE_MANUAL_CONTENT_SCAN_LIST)
|
||||||
|
default_title_macro(action_get_title_dropdown_manual_content_scan_system_name_item, MENU_ENUM_LABEL_VALUE_MANUAL_CONTENT_SCAN_SYSTEM_NAME)
|
||||||
|
default_title_macro(action_get_title_dropdown_manual_content_scan_core_name_item, MENU_ENUM_LABEL_VALUE_MANUAL_CONTENT_SCAN_CORE_NAME)
|
||||||
|
|
||||||
default_fill_title_macro(action_get_title_disk_image_append, MENU_ENUM_LABEL_VALUE_DISK_IMAGE_APPEND)
|
default_fill_title_macro(action_get_title_disk_image_append, MENU_ENUM_LABEL_VALUE_DISK_IMAGE_APPEND)
|
||||||
default_fill_title_macro(action_get_title_cheat_file_load, MENU_ENUM_LABEL_VALUE_CHEAT_FILE)
|
default_fill_title_macro(action_get_title_cheat_file_load, MENU_ENUM_LABEL_VALUE_CHEAT_FILE)
|
||||||
@ -444,6 +448,7 @@ default_fill_title_macro(action_get_title_extraction_directory, MENU_ENUM_LABE
|
|||||||
default_fill_title_macro(action_get_title_menu, MENU_ENUM_LABEL_VALUE_MENU_SETTINGS)
|
default_fill_title_macro(action_get_title_menu, MENU_ENUM_LABEL_VALUE_MENU_SETTINGS)
|
||||||
default_fill_title_macro(action_get_title_font_path, MENU_ENUM_LABEL_VALUE_XMB_FONT)
|
default_fill_title_macro(action_get_title_font_path, MENU_ENUM_LABEL_VALUE_XMB_FONT)
|
||||||
default_fill_title_macro(action_get_title_log_dir, MENU_ENUM_LABEL_VALUE_LOG_DIR)
|
default_fill_title_macro(action_get_title_log_dir, MENU_ENUM_LABEL_VALUE_LOG_DIR)
|
||||||
|
default_fill_title_macro(action_get_title_manual_content_scan_dir, MENU_ENUM_LABEL_VALUE_MANUAL_CONTENT_SCAN_DIR)
|
||||||
|
|
||||||
default_title_copy_macro(action_get_title_help, MENU_ENUM_LABEL_VALUE_HELP_LIST)
|
default_title_copy_macro(action_get_title_help, MENU_ENUM_LABEL_VALUE_HELP_LIST)
|
||||||
default_title_copy_macro(action_get_title_input_settings, MENU_ENUM_LABEL_VALUE_INPUT_SETTINGS)
|
default_title_copy_macro(action_get_title_input_settings, MENU_ENUM_LABEL_VALUE_INPUT_SETTINGS)
|
||||||
@ -1226,6 +1231,12 @@ static int menu_cbs_init_bind_title_compare_label(menu_file_list_cbs_t *cbs,
|
|||||||
BIND_ACTION_GET_TITLE(cbs, action_get_title_switch_backlight_control);
|
BIND_ACTION_GET_TITLE(cbs, action_get_title_switch_backlight_control);
|
||||||
break;
|
break;
|
||||||
#endif
|
#endif
|
||||||
|
case MENU_ENUM_LABEL_MANUAL_CONTENT_SCAN_LIST:
|
||||||
|
BIND_ACTION_GET_TITLE(cbs, action_get_title_manual_content_scan_list);
|
||||||
|
break;
|
||||||
|
case MENU_ENUM_LABEL_MANUAL_CONTENT_SCAN_DIR:
|
||||||
|
BIND_ACTION_GET_TITLE(cbs, action_get_title_manual_content_scan_dir);
|
||||||
|
break;
|
||||||
default:
|
default:
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
@ -1363,6 +1374,9 @@ static int menu_cbs_init_bind_title_compare_label(menu_file_list_cbs_t *cbs,
|
|||||||
case MENU_LABEL_CORE_ASSETS_DIRECTORY:
|
case MENU_LABEL_CORE_ASSETS_DIRECTORY:
|
||||||
BIND_ACTION_GET_TITLE(cbs, action_get_title_core_assets_directory);
|
BIND_ACTION_GET_TITLE(cbs, action_get_title_core_assets_directory);
|
||||||
break;
|
break;
|
||||||
|
case MENU_LABEL_THUMBNAILS_DIRECTORY:
|
||||||
|
BIND_ACTION_GET_TITLE(cbs, action_get_title_thumbnail_directory);
|
||||||
|
break;
|
||||||
case MENU_LABEL_RGUI_CONFIG_DIRECTORY:
|
case MENU_LABEL_RGUI_CONFIG_DIRECTORY:
|
||||||
BIND_ACTION_GET_TITLE(cbs, action_get_title_config_directory);
|
BIND_ACTION_GET_TITLE(cbs, action_get_title_config_directory);
|
||||||
break;
|
break;
|
||||||
@ -1543,6 +1557,12 @@ static int menu_cbs_init_bind_title_compare_label(menu_file_list_cbs_t *cbs,
|
|||||||
BIND_ACTION_GET_TITLE(cbs, action_get_title_switch_backlight_control);
|
BIND_ACTION_GET_TITLE(cbs, action_get_title_switch_backlight_control);
|
||||||
break;
|
break;
|
||||||
#endif
|
#endif
|
||||||
|
case MENU_LABEL_DEFERRED_MANUAL_CONTENT_SCAN_LIST:
|
||||||
|
BIND_ACTION_GET_TITLE(cbs, action_get_title_manual_content_scan_list);
|
||||||
|
break;
|
||||||
|
case MENU_LABEL_MANUAL_CONTENT_SCAN_DIR:
|
||||||
|
BIND_ACTION_GET_TITLE(cbs, action_get_title_manual_content_scan_dir);
|
||||||
|
break;
|
||||||
default:
|
default:
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
@ -1651,6 +1671,18 @@ int menu_cbs_init_bind_title(menu_file_list_cbs_t *cbs,
|
|||||||
BIND_ACTION_GET_TITLE(cbs, action_get_title_dropdown_playlist_left_thumbnail_mode_item);
|
BIND_ACTION_GET_TITLE(cbs, action_get_title_dropdown_playlist_left_thumbnail_mode_item);
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
if (string_is_equal(label,
|
||||||
|
msg_hash_to_str(MENU_ENUM_LABEL_DEFERRED_DROPDOWN_BOX_LIST_MANUAL_CONTENT_SCAN_SYSTEM_NAME)))
|
||||||
|
{
|
||||||
|
BIND_ACTION_GET_TITLE(cbs, action_get_title_dropdown_manual_content_scan_system_name_item);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
if (string_is_equal(label,
|
||||||
|
msg_hash_to_str(MENU_ENUM_LABEL_DEFERRED_DROPDOWN_BOX_LIST_MANUAL_CONTENT_SCAN_CORE_NAME)))
|
||||||
|
{
|
||||||
|
BIND_ACTION_GET_TITLE(cbs, action_get_title_dropdown_manual_content_scan_core_name_item);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
if (string_is_equal(label, msg_hash_to_str(MENU_ENUM_LABEL_DEFERRED_RPL_ENTRY_ACTIONS)))
|
if (string_is_equal(label, msg_hash_to_str(MENU_ENUM_LABEL_DEFERRED_RPL_ENTRY_ACTIONS)))
|
||||||
{
|
{
|
||||||
BIND_ACTION_GET_TITLE(cbs, action_get_quick_menu_views_settings_list);
|
BIND_ACTION_GET_TITLE(cbs, action_get_quick_menu_views_settings_list);
|
||||||
@ -1676,6 +1708,11 @@ int menu_cbs_init_bind_title(menu_file_list_cbs_t *cbs,
|
|||||||
BIND_ACTION_GET_TITLE(cbs, action_get_title_collection);
|
BIND_ACTION_GET_TITLE(cbs, action_get_title_collection);
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
if (string_is_equal(label, msg_hash_to_str(MENU_ENUM_LABEL_DEFERRED_MANUAL_CONTENT_SCAN_LIST)))
|
||||||
|
{
|
||||||
|
BIND_ACTION_GET_TITLE(cbs, action_get_title_manual_content_scan_list);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
@ -2552,7 +2552,6 @@ enum materialui_entry_value_type materialui_get_entry_value_type(
|
|||||||
switch (entry_file_type)
|
switch (entry_file_type)
|
||||||
{
|
{
|
||||||
case FILE_TYPE_IN_CARCHIVE:
|
case FILE_TYPE_IN_CARCHIVE:
|
||||||
case FILE_TYPE_COMPRESSED:
|
|
||||||
case FILE_TYPE_MORE:
|
case FILE_TYPE_MORE:
|
||||||
case FILE_TYPE_CORE:
|
case FILE_TYPE_CORE:
|
||||||
case FILE_TYPE_DIRECT_LOAD:
|
case FILE_TYPE_DIRECT_LOAD:
|
||||||
@ -2564,6 +2563,15 @@ enum materialui_entry_value_type materialui_get_entry_value_type(
|
|||||||
case FILE_TYPE_IMAGE:
|
case FILE_TYPE_IMAGE:
|
||||||
case FILE_TYPE_MOVIE:
|
case FILE_TYPE_MOVIE:
|
||||||
break;
|
break;
|
||||||
|
case FILE_TYPE_COMPRESSED:
|
||||||
|
/* Note that we have to perform a backup check here,
|
||||||
|
* since the 'manual content scan - file extensions'
|
||||||
|
* setting may have a value of 'zip' or '7z' etc, which
|
||||||
|
* means it would otherwise get incorreclty identified as
|
||||||
|
* an achive file... */
|
||||||
|
if (entry_type != FILE_TYPE_CARCHIVE)
|
||||||
|
value_type = MUI_ENTRY_VALUE_TEXT;
|
||||||
|
break;
|
||||||
default:
|
default:
|
||||||
value_type = MUI_ENTRY_VALUE_TEXT;
|
value_type = MUI_ENTRY_VALUE_TEXT;
|
||||||
break;
|
break;
|
||||||
@ -2693,6 +2701,12 @@ static void materialui_render_menu_entry_default(
|
|||||||
switch (entry_file_type)
|
switch (entry_file_type)
|
||||||
{
|
{
|
||||||
case FILE_TYPE_COMPRESSED:
|
case FILE_TYPE_COMPRESSED:
|
||||||
|
/* Note that we have to perform a backup check here,
|
||||||
|
* since the 'manual content scan - file extensions'
|
||||||
|
* setting may have a value of 'zip' or '7z' etc, which
|
||||||
|
* means it would otherwise get incorreclty identified as
|
||||||
|
* an achive file... */
|
||||||
|
if (entry_type == FILE_TYPE_CARCHIVE)
|
||||||
icon_texture = mui->textures.list[MUI_TEXTURE_ARCHIVE];
|
icon_texture = mui->textures.list[MUI_TEXTURE_ARCHIVE];
|
||||||
break;
|
break;
|
||||||
case FILE_TYPE_IMAGE:
|
case FILE_TYPE_IMAGE:
|
||||||
@ -7613,7 +7627,8 @@ static void materialui_list_insert(
|
|||||||
node->has_icon = true;
|
node->has_icon = true;
|
||||||
}
|
}
|
||||||
else if (string_is_equal(label, msg_hash_to_str(MENU_ENUM_LABEL_SCAN_DIRECTORY)) ||
|
else if (string_is_equal(label, msg_hash_to_str(MENU_ENUM_LABEL_SCAN_DIRECTORY)) ||
|
||||||
string_is_equal(label, msg_hash_to_str(MENU_ENUM_LABEL_SCAN_FILE))
|
string_is_equal(label, msg_hash_to_str(MENU_ENUM_LABEL_SCAN_FILE)) ||
|
||||||
|
string_is_equal(label, msg_hash_to_str(MENU_ENUM_LABEL_MANUAL_CONTENT_SCAN_LIST))
|
||||||
)
|
)
|
||||||
{
|
{
|
||||||
node->icon_texture_index = MUI_TEXTURE_ADD;
|
node->icon_texture_index = MUI_TEXTURE_ADD;
|
||||||
|
@ -250,6 +250,7 @@ menu_texture_item ozone_entries_icon_get_texture(ozone_handle_t *ozone,
|
|||||||
return ozone->icons_textures[OZONE_ENTRIES_ICONS_TEXTURE_USER];
|
return ozone->icons_textures[OZONE_ENTRIES_ICONS_TEXTURE_USER];
|
||||||
case MENU_ENUM_LABEL_DIRECTORY_SETTINGS:
|
case MENU_ENUM_LABEL_DIRECTORY_SETTINGS:
|
||||||
case MENU_ENUM_LABEL_SCAN_DIRECTORY:
|
case MENU_ENUM_LABEL_SCAN_DIRECTORY:
|
||||||
|
case MENU_ENUM_LABEL_MANUAL_CONTENT_SCAN_LIST:
|
||||||
case MENU_ENUM_LABEL_REMAP_FILE_SAVE_CONTENT_DIR:
|
case MENU_ENUM_LABEL_REMAP_FILE_SAVE_CONTENT_DIR:
|
||||||
case MENU_ENUM_LABEL_SAVE_CURRENT_CONFIG_OVERRIDE_CONTENT_DIR:
|
case MENU_ENUM_LABEL_SAVE_CURRENT_CONFIG_OVERRIDE_CONTENT_DIR:
|
||||||
case MENU_ENUM_LABEL_VIDEO_SHADER_PRESET_SAVE_PARENT:
|
case MENU_ENUM_LABEL_VIDEO_SHADER_PRESET_SAVE_PARENT:
|
||||||
|
@ -2379,6 +2379,7 @@ static uintptr_t xmb_icon_get_id(xmb_handle_t *xmb,
|
|||||||
return xmb->textures.list[XMB_TEXTURE_RESUME];
|
return xmb->textures.list[XMB_TEXTURE_RESUME];
|
||||||
case MENU_ENUM_LABEL_DIRECTORY_SETTINGS:
|
case MENU_ENUM_LABEL_DIRECTORY_SETTINGS:
|
||||||
case MENU_ENUM_LABEL_SCAN_DIRECTORY:
|
case MENU_ENUM_LABEL_SCAN_DIRECTORY:
|
||||||
|
case MENU_ENUM_LABEL_MANUAL_CONTENT_SCAN_LIST:
|
||||||
case MENU_ENUM_LABEL_REMAP_FILE_SAVE_CONTENT_DIR:
|
case MENU_ENUM_LABEL_REMAP_FILE_SAVE_CONTENT_DIR:
|
||||||
case MENU_ENUM_LABEL_SAVE_CURRENT_CONFIG_OVERRIDE_CONTENT_DIR:
|
case MENU_ENUM_LABEL_SAVE_CURRENT_CONFIG_OVERRIDE_CONTENT_DIR:
|
||||||
case MENU_ENUM_LABEL_VIDEO_SHADER_PRESET_SAVE_PARENT:
|
case MENU_ENUM_LABEL_VIDEO_SHADER_PRESET_SAVE_PARENT:
|
||||||
|
@ -52,11 +52,14 @@ enum
|
|||||||
ACTION_OK_DL_DROPDOWN_BOX_LIST_PLAYLIST_LABEL_DISPLAY_MODE,
|
ACTION_OK_DL_DROPDOWN_BOX_LIST_PLAYLIST_LABEL_DISPLAY_MODE,
|
||||||
ACTION_OK_DL_DROPDOWN_BOX_LIST_PLAYLIST_RIGHT_THUMBNAIL_MODE,
|
ACTION_OK_DL_DROPDOWN_BOX_LIST_PLAYLIST_RIGHT_THUMBNAIL_MODE,
|
||||||
ACTION_OK_DL_DROPDOWN_BOX_LIST_PLAYLIST_LEFT_THUMBNAIL_MODE,
|
ACTION_OK_DL_DROPDOWN_BOX_LIST_PLAYLIST_LEFT_THUMBNAIL_MODE,
|
||||||
|
ACTION_OK_DL_DROPDOWN_BOX_LIST_MANUAL_CONTENT_SCAN_SYSTEM_NAME,
|
||||||
|
ACTION_OK_DL_DROPDOWN_BOX_LIST_MANUAL_CONTENT_SCAN_CORE_NAME,
|
||||||
ACTION_OK_DL_OPEN_ARCHIVE,
|
ACTION_OK_DL_OPEN_ARCHIVE,
|
||||||
ACTION_OK_DL_OPEN_ARCHIVE_DETECT_CORE,
|
ACTION_OK_DL_OPEN_ARCHIVE_DETECT_CORE,
|
||||||
ACTION_OK_DL_MUSIC,
|
ACTION_OK_DL_MUSIC,
|
||||||
ACTION_OK_DL_NETPLAY,
|
ACTION_OK_DL_NETPLAY,
|
||||||
ACTION_OK_DL_SCAN_DIR_LIST,
|
ACTION_OK_DL_SCAN_DIR_LIST,
|
||||||
|
ACTION_OK_DL_MANUAL_SCAN_DIR_LIST,
|
||||||
ACTION_OK_DL_HELP,
|
ACTION_OK_DL_HELP,
|
||||||
ACTION_OK_DL_RPL_ENTRY,
|
ACTION_OK_DL_RPL_ENTRY,
|
||||||
ACTION_OK_DL_RDB_ENTRY,
|
ACTION_OK_DL_RDB_ENTRY,
|
||||||
@ -166,7 +169,8 @@ enum
|
|||||||
ACTION_OK_DL_BROWSE_URL_START,
|
ACTION_OK_DL_BROWSE_URL_START,
|
||||||
ACTION_OK_DL_CONTENT_SETTINGS,
|
ACTION_OK_DL_CONTENT_SETTINGS,
|
||||||
ACTION_OK_DL_CDROM_INFO_DETAIL_LIST,
|
ACTION_OK_DL_CDROM_INFO_DETAIL_LIST,
|
||||||
ACTION_OK_DL_RGUI_MENU_THEME_PRESET
|
ACTION_OK_DL_RGUI_MENU_THEME_PRESET,
|
||||||
|
ACTION_OK_DL_MANUAL_CONTENT_SCAN_LIST
|
||||||
};
|
};
|
||||||
|
|
||||||
/* Function callbacks */
|
/* Function callbacks */
|
||||||
|
@ -98,6 +98,7 @@
|
|||||||
#include "../tasks/tasks_internal.h"
|
#include "../tasks/tasks_internal.h"
|
||||||
#include "../dynamic.h"
|
#include "../dynamic.h"
|
||||||
#include "../runtime_file.h"
|
#include "../runtime_file.h"
|
||||||
|
#include "../manual_content_scan.h"
|
||||||
|
|
||||||
static char new_path_entry[4096] = {0};
|
static char new_path_entry[4096] = {0};
|
||||||
static char new_lbl_entry[4096] = {0};
|
static char new_lbl_entry[4096] = {0};
|
||||||
@ -2334,9 +2335,9 @@ static unsigned menu_displaylist_parse_playlists(
|
|||||||
|
|
||||||
if (!horizontal)
|
if (!horizontal)
|
||||||
{
|
{
|
||||||
#ifdef HAVE_LIBRETRODB
|
|
||||||
if (settings->bools.menu_content_show_add)
|
if (settings->bools.menu_content_show_add)
|
||||||
{
|
{
|
||||||
|
#ifdef HAVE_LIBRETRODB
|
||||||
if (menu_entries_append_enum(info->list,
|
if (menu_entries_append_enum(info->list,
|
||||||
msg_hash_to_str(MENU_ENUM_LABEL_VALUE_SCAN_DIRECTORY),
|
msg_hash_to_str(MENU_ENUM_LABEL_VALUE_SCAN_DIRECTORY),
|
||||||
msg_hash_to_str(MENU_ENUM_LABEL_SCAN_DIRECTORY),
|
msg_hash_to_str(MENU_ENUM_LABEL_SCAN_DIRECTORY),
|
||||||
@ -2349,8 +2350,15 @@ static unsigned menu_displaylist_parse_playlists(
|
|||||||
MENU_ENUM_LABEL_SCAN_FILE,
|
MENU_ENUM_LABEL_SCAN_FILE,
|
||||||
MENU_SETTING_ACTION, 0, 0))
|
MENU_SETTING_ACTION, 0, 0))
|
||||||
count++;
|
count++;
|
||||||
}
|
|
||||||
#endif
|
#endif
|
||||||
|
if (menu_entries_append_enum(info->list,
|
||||||
|
msg_hash_to_str(MENU_ENUM_LABEL_VALUE_MANUAL_CONTENT_SCAN_LIST),
|
||||||
|
msg_hash_to_str(MENU_ENUM_LABEL_MANUAL_CONTENT_SCAN_LIST),
|
||||||
|
MENU_ENUM_LABEL_MANUAL_CONTENT_SCAN_LIST,
|
||||||
|
MENU_SETTING_ACTION, 0, 0))
|
||||||
|
count++;
|
||||||
|
}
|
||||||
|
|
||||||
if (settings->bools.menu_content_show_favorites)
|
if (settings->bools.menu_content_show_favorites)
|
||||||
if (menu_entries_append_enum(info->list,
|
if (menu_entries_append_enum(info->list,
|
||||||
msg_hash_to_str(MENU_ENUM_LABEL_VALUE_GOTO_FAVORITES),
|
msg_hash_to_str(MENU_ENUM_LABEL_VALUE_GOTO_FAVORITES),
|
||||||
@ -3667,6 +3675,64 @@ static unsigned populate_playlist_thumbnail_mode_dropdown_list(
|
|||||||
return count;
|
return count;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static bool menu_displaylist_parse_manual_content_scan_list(
|
||||||
|
menu_displaylist_info_t *info)
|
||||||
|
{
|
||||||
|
unsigned count = 0;
|
||||||
|
|
||||||
|
/* Content directory */
|
||||||
|
if (menu_entries_append_enum(info->list,
|
||||||
|
msg_hash_to_str(MENU_ENUM_LABEL_VALUE_MANUAL_CONTENT_SCAN_DIR),
|
||||||
|
msg_hash_to_str(MENU_ENUM_LABEL_MANUAL_CONTENT_SCAN_DIR),
|
||||||
|
MENU_ENUM_LABEL_MANUAL_CONTENT_SCAN_DIR,
|
||||||
|
MENU_SETTING_MANUAL_CONTENT_SCAN_DIR, 0, 0))
|
||||||
|
count++;
|
||||||
|
|
||||||
|
/* System name */
|
||||||
|
if (menu_entries_append_enum(info->list,
|
||||||
|
msg_hash_to_str(MENU_ENUM_LABEL_VALUE_MANUAL_CONTENT_SCAN_SYSTEM_NAME),
|
||||||
|
msg_hash_to_str(MENU_ENUM_LABEL_MANUAL_CONTENT_SCAN_SYSTEM_NAME),
|
||||||
|
MENU_ENUM_LABEL_MANUAL_CONTENT_SCAN_SYSTEM_NAME,
|
||||||
|
MENU_SETTING_MANUAL_CONTENT_SCAN_SYSTEM_NAME, 0, 0))
|
||||||
|
count++;
|
||||||
|
|
||||||
|
/* Custom system name */
|
||||||
|
if (menu_displaylist_parse_settings_enum(info->list,
|
||||||
|
MENU_ENUM_LABEL_MANUAL_CONTENT_SCAN_SYSTEM_NAME_CUSTOM, PARSE_ONLY_STRING,
|
||||||
|
false) == 0)
|
||||||
|
count++;
|
||||||
|
|
||||||
|
/* Core name */
|
||||||
|
if (menu_entries_append_enum(info->list,
|
||||||
|
msg_hash_to_str(MENU_ENUM_LABEL_VALUE_MANUAL_CONTENT_SCAN_CORE_NAME),
|
||||||
|
msg_hash_to_str(MENU_ENUM_LABEL_MANUAL_CONTENT_SCAN_CORE_NAME),
|
||||||
|
MENU_ENUM_LABEL_MANUAL_CONTENT_SCAN_CORE_NAME,
|
||||||
|
MENU_SETTING_MANUAL_CONTENT_SCAN_CORE_NAME, 0, 0))
|
||||||
|
count++;
|
||||||
|
|
||||||
|
/* File extensions */
|
||||||
|
if (menu_displaylist_parse_settings_enum(info->list,
|
||||||
|
MENU_ENUM_LABEL_MANUAL_CONTENT_SCAN_FILE_EXTS, PARSE_ONLY_STRING,
|
||||||
|
false) == 0)
|
||||||
|
count++;
|
||||||
|
|
||||||
|
/* Overwrite playlist */
|
||||||
|
if (menu_displaylist_parse_settings_enum(info->list,
|
||||||
|
MENU_ENUM_LABEL_MANUAL_CONTENT_SCAN_OVERWRITE, PARSE_ONLY_BOOL,
|
||||||
|
false) == 0)
|
||||||
|
count++;
|
||||||
|
|
||||||
|
/* Start scan */
|
||||||
|
if (menu_entries_append_enum(info->list,
|
||||||
|
msg_hash_to_str(MENU_ENUM_LABEL_VALUE_MANUAL_CONTENT_SCAN_START),
|
||||||
|
msg_hash_to_str(MENU_ENUM_LABEL_MANUAL_CONTENT_SCAN_START),
|
||||||
|
MENU_ENUM_LABEL_MANUAL_CONTENT_SCAN_START,
|
||||||
|
MENU_SETTING_ACTION_MANUAL_CONTENT_SCAN_START, 0, 0))
|
||||||
|
count++;
|
||||||
|
|
||||||
|
return (count > 0);
|
||||||
|
}
|
||||||
|
|
||||||
unsigned menu_displaylist_build_list(file_list_t *list, enum menu_displaylist_ctl_state type)
|
unsigned menu_displaylist_build_list(file_list_t *list, enum menu_displaylist_ctl_state type)
|
||||||
{
|
{
|
||||||
unsigned i;
|
unsigned i;
|
||||||
@ -3863,6 +3929,12 @@ unsigned menu_displaylist_build_list(file_list_t *list, enum menu_displaylist_ct
|
|||||||
MENU_SETTING_ACTION, 0, 0))
|
MENU_SETTING_ACTION, 0, 0))
|
||||||
count++;
|
count++;
|
||||||
#endif
|
#endif
|
||||||
|
if (menu_entries_append_enum(list,
|
||||||
|
msg_hash_to_str(MENU_ENUM_LABEL_VALUE_MANUAL_CONTENT_SCAN_LIST),
|
||||||
|
msg_hash_to_str(MENU_ENUM_LABEL_MANUAL_CONTENT_SCAN_LIST),
|
||||||
|
MENU_ENUM_LABEL_MANUAL_CONTENT_SCAN_LIST,
|
||||||
|
MENU_SETTING_ACTION, 0, 0))
|
||||||
|
count++;
|
||||||
break;
|
break;
|
||||||
case DISPLAYLIST_NETWORK_INFO:
|
case DISPLAYLIST_NETWORK_INFO:
|
||||||
#if defined(HAVE_NETWORKING) && !defined(HAVE_SOCKET_LEGACY) && (!defined(SWITCH) || defined(SWITCH) && defined(HAVE_LIBNX))
|
#if defined(HAVE_NETWORKING) && !defined(HAVE_SOCKET_LEGACY) && (!defined(SWITCH) || defined(SWITCH) && defined(HAVE_LIBNX))
|
||||||
@ -4125,6 +4197,84 @@ unsigned menu_displaylist_build_list(file_list_t *list, enum menu_displaylist_ct
|
|||||||
case DISPLAYLIST_DROPDOWN_LIST_PLAYLIST_LEFT_THUMBNAIL_MODE:
|
case DISPLAYLIST_DROPDOWN_LIST_PLAYLIST_LEFT_THUMBNAIL_MODE:
|
||||||
count = populate_playlist_thumbnail_mode_dropdown_list(list, PLAYLIST_THUMBNAIL_LEFT);
|
count = populate_playlist_thumbnail_mode_dropdown_list(list, PLAYLIST_THUMBNAIL_LEFT);
|
||||||
break;
|
break;
|
||||||
|
case DISPLAYLIST_DROPDOWN_LIST_MANUAL_CONTENT_SCAN_SYSTEM_NAME:
|
||||||
|
{
|
||||||
|
/* Get system name list */
|
||||||
|
struct string_list *system_name_list = manual_content_scan_get_menu_system_name_list();
|
||||||
|
|
||||||
|
if (system_name_list)
|
||||||
|
{
|
||||||
|
const char *current_system_name = NULL;
|
||||||
|
unsigned i;
|
||||||
|
|
||||||
|
/* Get currently selected system name */
|
||||||
|
manual_content_scan_get_menu_system_name(¤t_system_name);
|
||||||
|
|
||||||
|
/* Loop through names */
|
||||||
|
for (i = 0; i < system_name_list->size; i++)
|
||||||
|
{
|
||||||
|
/* Note: manual_content_scan_get_system_name_list()
|
||||||
|
* ensures that system_name cannot be empty here */
|
||||||
|
const char *system_name = system_name_list->elems[i].data;
|
||||||
|
|
||||||
|
/* Add menu entry */
|
||||||
|
if (menu_entries_append_enum(list,
|
||||||
|
system_name,
|
||||||
|
"",
|
||||||
|
MENU_ENUM_LABEL_NO_ITEMS,
|
||||||
|
MENU_SETTING_DROPDOWN_ITEM_MANUAL_CONTENT_SCAN_SYSTEM_NAME,
|
||||||
|
i, 0))
|
||||||
|
count++;
|
||||||
|
|
||||||
|
/* Check whether current entry is checked */
|
||||||
|
if (string_is_equal(current_system_name, system_name))
|
||||||
|
menu_entries_set_checked(list, i, true);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Clean up */
|
||||||
|
string_list_free(system_name_list);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case DISPLAYLIST_DROPDOWN_LIST_MANUAL_CONTENT_SCAN_CORE_NAME:
|
||||||
|
{
|
||||||
|
/* Get core name list */
|
||||||
|
struct string_list *core_name_list = manual_content_scan_get_menu_core_name_list();
|
||||||
|
|
||||||
|
if (core_name_list)
|
||||||
|
{
|
||||||
|
const char *current_core_name = NULL;
|
||||||
|
unsigned i;
|
||||||
|
|
||||||
|
/* Get currently selected core name */
|
||||||
|
manual_content_scan_get_menu_core_name(¤t_core_name);
|
||||||
|
|
||||||
|
/* Loop through names */
|
||||||
|
for (i = 0; i < core_name_list->size; i++)
|
||||||
|
{
|
||||||
|
/* Note: manual_content_scan_get_core_name_list()
|
||||||
|
* ensures that core_name cannot be empty here */
|
||||||
|
const char *core_name = core_name_list->elems[i].data;
|
||||||
|
|
||||||
|
/* Add menu entry */
|
||||||
|
if (menu_entries_append_enum(list,
|
||||||
|
core_name,
|
||||||
|
"",
|
||||||
|
MENU_ENUM_LABEL_NO_ITEMS,
|
||||||
|
MENU_SETTING_DROPDOWN_ITEM_MANUAL_CONTENT_SCAN_CORE_NAME,
|
||||||
|
i, 0))
|
||||||
|
count++;
|
||||||
|
|
||||||
|
/* Check whether current entry is checked */
|
||||||
|
if (string_is_equal(current_core_name, core_name))
|
||||||
|
menu_entries_set_checked(list, i, true);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Clean up */
|
||||||
|
string_list_free(core_name_list);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
break;
|
||||||
case DISPLAYLIST_PERFCOUNTERS_CORE:
|
case DISPLAYLIST_PERFCOUNTERS_CORE:
|
||||||
case DISPLAYLIST_PERFCOUNTERS_FRONTEND:
|
case DISPLAYLIST_PERFCOUNTERS_FRONTEND:
|
||||||
{
|
{
|
||||||
@ -7213,6 +7363,8 @@ bool menu_displaylist_ctl(enum menu_displaylist_ctl_state type,
|
|||||||
case DISPLAYLIST_DROPDOWN_LIST_PLAYLIST_LABEL_DISPLAY_MODE:
|
case DISPLAYLIST_DROPDOWN_LIST_PLAYLIST_LABEL_DISPLAY_MODE:
|
||||||
case DISPLAYLIST_DROPDOWN_LIST_PLAYLIST_RIGHT_THUMBNAIL_MODE:
|
case DISPLAYLIST_DROPDOWN_LIST_PLAYLIST_RIGHT_THUMBNAIL_MODE:
|
||||||
case DISPLAYLIST_DROPDOWN_LIST_PLAYLIST_LEFT_THUMBNAIL_MODE:
|
case DISPLAYLIST_DROPDOWN_LIST_PLAYLIST_LEFT_THUMBNAIL_MODE:
|
||||||
|
case DISPLAYLIST_DROPDOWN_LIST_MANUAL_CONTENT_SCAN_SYSTEM_NAME:
|
||||||
|
case DISPLAYLIST_DROPDOWN_LIST_MANUAL_CONTENT_SCAN_CORE_NAME:
|
||||||
case DISPLAYLIST_PERFCOUNTERS_CORE:
|
case DISPLAYLIST_PERFCOUNTERS_CORE:
|
||||||
case DISPLAYLIST_PERFCOUNTERS_FRONTEND:
|
case DISPLAYLIST_PERFCOUNTERS_FRONTEND:
|
||||||
case DISPLAYLIST_MENU_SETTINGS_LIST:
|
case DISPLAYLIST_MENU_SETTINGS_LIST:
|
||||||
@ -7238,6 +7390,8 @@ bool menu_displaylist_ctl(enum menu_displaylist_ctl_state type,
|
|||||||
case DISPLAYLIST_DROPDOWN_LIST_PLAYLIST_LABEL_DISPLAY_MODE:
|
case DISPLAYLIST_DROPDOWN_LIST_PLAYLIST_LABEL_DISPLAY_MODE:
|
||||||
case DISPLAYLIST_DROPDOWN_LIST_PLAYLIST_RIGHT_THUMBNAIL_MODE:
|
case DISPLAYLIST_DROPDOWN_LIST_PLAYLIST_RIGHT_THUMBNAIL_MODE:
|
||||||
case DISPLAYLIST_DROPDOWN_LIST_PLAYLIST_LEFT_THUMBNAIL_MODE:
|
case DISPLAYLIST_DROPDOWN_LIST_PLAYLIST_LEFT_THUMBNAIL_MODE:
|
||||||
|
case DISPLAYLIST_DROPDOWN_LIST_MANUAL_CONTENT_SCAN_SYSTEM_NAME:
|
||||||
|
case DISPLAYLIST_DROPDOWN_LIST_MANUAL_CONTENT_SCAN_CORE_NAME:
|
||||||
menu_entries_append_enum(info->list,
|
menu_entries_append_enum(info->list,
|
||||||
msg_hash_to_str(MENU_ENUM_LABEL_VALUE_NO_ENTRIES_TO_DISPLAY),
|
msg_hash_to_str(MENU_ENUM_LABEL_VALUE_NO_ENTRIES_TO_DISPLAY),
|
||||||
msg_hash_to_str(MENU_ENUM_LABEL_NO_ENTRIES_TO_DISPLAY),
|
msg_hash_to_str(MENU_ENUM_LABEL_NO_ENTRIES_TO_DISPLAY),
|
||||||
@ -7701,6 +7855,12 @@ bool menu_displaylist_ctl(enum menu_displaylist_ctl_state type,
|
|||||||
MENU_SETTING_ACTION, 0, 0))
|
MENU_SETTING_ACTION, 0, 0))
|
||||||
count++;
|
count++;
|
||||||
#endif
|
#endif
|
||||||
|
if (menu_entries_append_enum(info->list,
|
||||||
|
msg_hash_to_str(MENU_ENUM_LABEL_VALUE_MANUAL_CONTENT_SCAN_LIST),
|
||||||
|
msg_hash_to_str(MENU_ENUM_LABEL_MANUAL_CONTENT_SCAN_LIST),
|
||||||
|
MENU_ENUM_LABEL_MANUAL_CONTENT_SCAN_LIST,
|
||||||
|
MENU_SETTING_ACTION, 0, 0))
|
||||||
|
count++;
|
||||||
|
|
||||||
if (count == 0)
|
if (count == 0)
|
||||||
menu_entries_append_enum(info->list,
|
menu_entries_append_enum(info->list,
|
||||||
@ -8967,6 +9127,18 @@ bool menu_displaylist_ctl(enum menu_displaylist_ctl_state type,
|
|||||||
menu_entries_ctl(MENU_ENTRIES_CTL_CLEAR, info->list);
|
menu_entries_ctl(MENU_ENTRIES_CTL_CLEAR, info->list);
|
||||||
use_filebrowser = true;
|
use_filebrowser = true;
|
||||||
break;
|
break;
|
||||||
|
case DISPLAYLIST_MANUAL_CONTENT_SCAN_LIST:
|
||||||
|
menu_entries_ctl(MENU_ENTRIES_CTL_CLEAR, info->list);
|
||||||
|
|
||||||
|
if (!menu_displaylist_parse_manual_content_scan_list(info))
|
||||||
|
menu_entries_append_enum(info->list,
|
||||||
|
msg_hash_to_str(MENU_ENUM_LABEL_VALUE_NO_ENTRIES_TO_DISPLAY),
|
||||||
|
msg_hash_to_str(MENU_ENUM_LABEL_NO_ENTRIES_TO_DISPLAY),
|
||||||
|
MENU_ENUM_LABEL_NO_ENTRIES_TO_DISPLAY,
|
||||||
|
FILE_TYPE_NONE, 0, 0);
|
||||||
|
|
||||||
|
info->need_push = true;
|
||||||
|
break;
|
||||||
case DISPLAYLIST_DROPDOWN_LIST:
|
case DISPLAYLIST_DROPDOWN_LIST:
|
||||||
{
|
{
|
||||||
menu_entries_ctl(MENU_ENTRIES_CTL_CLEAR, info->list);
|
menu_entries_ctl(MENU_ENTRIES_CTL_CLEAR, info->list);
|
||||||
|
@ -60,6 +60,8 @@ enum menu_displaylist_ctl_state
|
|||||||
DISPLAYLIST_DROPDOWN_LIST_PLAYLIST_LABEL_DISPLAY_MODE,
|
DISPLAYLIST_DROPDOWN_LIST_PLAYLIST_LABEL_DISPLAY_MODE,
|
||||||
DISPLAYLIST_DROPDOWN_LIST_PLAYLIST_RIGHT_THUMBNAIL_MODE,
|
DISPLAYLIST_DROPDOWN_LIST_PLAYLIST_RIGHT_THUMBNAIL_MODE,
|
||||||
DISPLAYLIST_DROPDOWN_LIST_PLAYLIST_LEFT_THUMBNAIL_MODE,
|
DISPLAYLIST_DROPDOWN_LIST_PLAYLIST_LEFT_THUMBNAIL_MODE,
|
||||||
|
DISPLAYLIST_DROPDOWN_LIST_MANUAL_CONTENT_SCAN_SYSTEM_NAME,
|
||||||
|
DISPLAYLIST_DROPDOWN_LIST_MANUAL_CONTENT_SCAN_CORE_NAME,
|
||||||
DISPLAYLIST_CDROM_DETAIL_INFO,
|
DISPLAYLIST_CDROM_DETAIL_INFO,
|
||||||
DISPLAYLIST_INFO,
|
DISPLAYLIST_INFO,
|
||||||
DISPLAYLIST_HELP,
|
DISPLAYLIST_HELP,
|
||||||
@ -212,6 +214,7 @@ enum menu_displaylist_ctl_state
|
|||||||
#if defined(HAVE_LAKKA_SWITCH) || defined(HAVE_LIBNX)
|
#if defined(HAVE_LAKKA_SWITCH) || defined(HAVE_LIBNX)
|
||||||
DISPLAYLIST_SWITCH_CPU_PROFILE,
|
DISPLAYLIST_SWITCH_CPU_PROFILE,
|
||||||
#endif
|
#endif
|
||||||
|
DISPLAYLIST_MANUAL_CONTENT_SCAN_LIST,
|
||||||
DISPLAYLIST_PENDING_CLEAR
|
DISPLAYLIST_PENDING_CLEAR
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -91,6 +91,8 @@ enum menu_settings_type
|
|||||||
MENU_SETTING_DROPDOWN_ITEM_PLAYLIST_LABEL_DISPLAY_MODE,
|
MENU_SETTING_DROPDOWN_ITEM_PLAYLIST_LABEL_DISPLAY_MODE,
|
||||||
MENU_SETTING_DROPDOWN_ITEM_PLAYLIST_RIGHT_THUMBNAIL_MODE,
|
MENU_SETTING_DROPDOWN_ITEM_PLAYLIST_RIGHT_THUMBNAIL_MODE,
|
||||||
MENU_SETTING_DROPDOWN_ITEM_PLAYLIST_LEFT_THUMBNAIL_MODE,
|
MENU_SETTING_DROPDOWN_ITEM_PLAYLIST_LEFT_THUMBNAIL_MODE,
|
||||||
|
MENU_SETTING_DROPDOWN_ITEM_MANUAL_CONTENT_SCAN_SYSTEM_NAME,
|
||||||
|
MENU_SETTING_DROPDOWN_ITEM_MANUAL_CONTENT_SCAN_CORE_NAME,
|
||||||
MENU_SETTING_DROPDOWN_SETTING_CORE_OPTIONS_ITEM,
|
MENU_SETTING_DROPDOWN_SETTING_CORE_OPTIONS_ITEM,
|
||||||
MENU_SETTING_DROPDOWN_SETTING_STRING_OPTIONS_ITEM,
|
MENU_SETTING_DROPDOWN_SETTING_STRING_OPTIONS_ITEM,
|
||||||
MENU_SETTING_DROPDOWN_SETTING_FLOAT_ITEM,
|
MENU_SETTING_DROPDOWN_SETTING_FLOAT_ITEM,
|
||||||
@ -206,6 +208,11 @@ enum menu_settings_type
|
|||||||
MENU_SET_CDROM_INFO,
|
MENU_SET_CDROM_INFO,
|
||||||
MENU_SETTING_ACTION_DELETE_PLAYLIST,
|
MENU_SETTING_ACTION_DELETE_PLAYLIST,
|
||||||
|
|
||||||
|
MENU_SETTING_MANUAL_CONTENT_SCAN_DIR,
|
||||||
|
MENU_SETTING_MANUAL_CONTENT_SCAN_SYSTEM_NAME,
|
||||||
|
MENU_SETTING_MANUAL_CONTENT_SCAN_CORE_NAME,
|
||||||
|
MENU_SETTING_ACTION_MANUAL_CONTENT_SCAN_START,
|
||||||
|
|
||||||
MENU_SETTINGS_LAST
|
MENU_SETTINGS_LAST
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -95,6 +95,7 @@
|
|||||||
#include "../managers/cheat_manager.h"
|
#include "../managers/cheat_manager.h"
|
||||||
#include "../verbosity.h"
|
#include "../verbosity.h"
|
||||||
#include "../playlist.h"
|
#include "../playlist.h"
|
||||||
|
#include "../manual_content_scan.h"
|
||||||
|
|
||||||
#include "../tasks/tasks_internal.h"
|
#include "../tasks/tasks_internal.h"
|
||||||
|
|
||||||
@ -157,7 +158,8 @@ enum settings_list_type
|
|||||||
SETTINGS_LIST_USER_ACCOUNTS_TWITCH,
|
SETTINGS_LIST_USER_ACCOUNTS_TWITCH,
|
||||||
SETTINGS_LIST_DIRECTORY,
|
SETTINGS_LIST_DIRECTORY,
|
||||||
SETTINGS_LIST_PRIVACY,
|
SETTINGS_LIST_PRIVACY,
|
||||||
SETTINGS_LIST_MIDI
|
SETTINGS_LIST_MIDI,
|
||||||
|
SETTINGS_LIST_MANUAL_CONTENT_SCAN
|
||||||
};
|
};
|
||||||
|
|
||||||
struct bool_entry
|
struct bool_entry
|
||||||
@ -6679,6 +6681,17 @@ void general_write_handler(rarch_setting_t *setting)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
case MENU_ENUM_LABEL_MANUAL_CONTENT_SCAN_SYSTEM_NAME_CUSTOM:
|
||||||
|
/* Ensure that custom system name includes no
|
||||||
|
* invalid characters */
|
||||||
|
manual_content_scan_scrub_system_name_custom();
|
||||||
|
break;
|
||||||
|
case MENU_ENUM_LABEL_MANUAL_CONTENT_SCAN_FILE_EXTS:
|
||||||
|
/* Ensure that custom file extension list includes
|
||||||
|
* no period (full stop) characters, and converts
|
||||||
|
* string to lower case */
|
||||||
|
manual_content_scan_scrub_file_exts_custom();
|
||||||
|
break;
|
||||||
default:
|
default:
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
@ -16430,6 +16443,63 @@ static bool setting_append_list(
|
|||||||
(*list)[list_info->index - 1].action_ok = &setting_action_ok_uint;
|
(*list)[list_info->index - 1].action_ok = &setting_action_ok_uint;
|
||||||
menu_settings_list_current_add_range(list, list_info, 0.0f, 100.0f, 1.0f, true, true);
|
menu_settings_list_current_add_range(list, list_info, 0.0f, 100.0f, 1.0f, true, true);
|
||||||
|
|
||||||
|
END_SUB_GROUP(list, list_info, parent_group);
|
||||||
|
END_GROUP(list, list_info, parent_group);
|
||||||
|
break;
|
||||||
|
case SETTINGS_LIST_MANUAL_CONTENT_SCAN:
|
||||||
|
START_GROUP(list, list_info, &group_info,
|
||||||
|
msg_hash_to_str(MENU_ENUM_LABEL_VALUE_MANUAL_CONTENT_SCAN_LIST), parent_group);
|
||||||
|
|
||||||
|
parent_group = msg_hash_to_str(MENU_ENUM_LABEL_MANUAL_CONTENT_SCAN_LIST);
|
||||||
|
|
||||||
|
START_SUB_GROUP(list, list_info, "State",
|
||||||
|
&group_info, &subgroup_info, parent_group);
|
||||||
|
|
||||||
|
CONFIG_STRING(
|
||||||
|
list, list_info,
|
||||||
|
manual_content_scan_get_system_name_custom_ptr(),
|
||||||
|
manual_content_scan_get_system_name_custom_size(),
|
||||||
|
MENU_ENUM_LABEL_MANUAL_CONTENT_SCAN_SYSTEM_NAME_CUSTOM,
|
||||||
|
MENU_ENUM_LABEL_VALUE_MANUAL_CONTENT_SCAN_SYSTEM_NAME_CUSTOM,
|
||||||
|
"",
|
||||||
|
&group_info,
|
||||||
|
&subgroup_info,
|
||||||
|
parent_group,
|
||||||
|
general_write_handler,
|
||||||
|
general_read_handler);
|
||||||
|
SETTINGS_DATA_LIST_CURRENT_ADD_FLAGS(list, list_info, SD_FLAG_ALLOW_INPUT);
|
||||||
|
(*list)[list_info->index - 1].ui_type = ST_UI_TYPE_STRING_LINE_EDIT;
|
||||||
|
|
||||||
|
CONFIG_STRING(
|
||||||
|
list, list_info,
|
||||||
|
manual_content_scan_get_file_exts_custom_ptr(),
|
||||||
|
manual_content_scan_get_file_exts_custom_size(),
|
||||||
|
MENU_ENUM_LABEL_MANUAL_CONTENT_SCAN_FILE_EXTS,
|
||||||
|
MENU_ENUM_LABEL_VALUE_MANUAL_CONTENT_SCAN_FILE_EXTS,
|
||||||
|
"",
|
||||||
|
&group_info,
|
||||||
|
&subgroup_info,
|
||||||
|
parent_group,
|
||||||
|
general_write_handler,
|
||||||
|
general_read_handler);
|
||||||
|
SETTINGS_DATA_LIST_CURRENT_ADD_FLAGS(list, list_info, SD_FLAG_ALLOW_INPUT);
|
||||||
|
(*list)[list_info->index - 1].ui_type = ST_UI_TYPE_STRING_LINE_EDIT;
|
||||||
|
|
||||||
|
CONFIG_BOOL(
|
||||||
|
list, list_info,
|
||||||
|
manual_content_scan_get_overwrite_playlist_ptr(),
|
||||||
|
MENU_ENUM_LABEL_MANUAL_CONTENT_SCAN_OVERWRITE,
|
||||||
|
MENU_ENUM_LABEL_VALUE_MANUAL_CONTENT_SCAN_OVERWRITE,
|
||||||
|
false,
|
||||||
|
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_SUB_GROUP(list, list_info, parent_group);
|
||||||
END_GROUP(list, list_info, parent_group);
|
END_GROUP(list, list_info, parent_group);
|
||||||
break;
|
break;
|
||||||
@ -16566,7 +16636,8 @@ static rarch_setting_t *menu_setting_new_internal(rarch_setting_info_t *list_inf
|
|||||||
SETTINGS_LIST_USER_ACCOUNTS_TWITCH,
|
SETTINGS_LIST_USER_ACCOUNTS_TWITCH,
|
||||||
SETTINGS_LIST_DIRECTORY,
|
SETTINGS_LIST_DIRECTORY,
|
||||||
SETTINGS_LIST_PRIVACY,
|
SETTINGS_LIST_PRIVACY,
|
||||||
SETTINGS_LIST_MIDI
|
SETTINGS_LIST_MIDI,
|
||||||
|
SETTINGS_LIST_MANUAL_CONTENT_SCAN
|
||||||
};
|
};
|
||||||
const char *root = msg_hash_to_str(MENU_ENUM_LABEL_MAIN_MENU);
|
const char *root = msg_hash_to_str(MENU_ENUM_LABEL_MAIN_MENU);
|
||||||
rarch_setting_t *list = (rarch_setting_t*)calloc(
|
rarch_setting_t *list = (rarch_setting_t*)calloc(
|
||||||
|
@ -127,6 +127,14 @@ void filebrowser_parse(menu_displaylist_info_t *info, unsigned type_data)
|
|||||||
FILE_TYPE_SCAN_DIRECTORY, 0 ,0);
|
FILE_TYPE_SCAN_DIRECTORY, 0 ,0);
|
||||||
#endif
|
#endif
|
||||||
break;
|
break;
|
||||||
|
case FILEBROWSER_MANUAL_SCAN_DIR:
|
||||||
|
if (info)
|
||||||
|
menu_entries_prepend(info->list,
|
||||||
|
msg_hash_to_str(MENU_ENUM_LABEL_VALUE_SCAN_THIS_DIRECTORY),
|
||||||
|
msg_hash_to_str(MENU_ENUM_LABEL_SCAN_THIS_DIRECTORY),
|
||||||
|
MENU_ENUM_LABEL_SCAN_THIS_DIRECTORY,
|
||||||
|
FILE_TYPE_MANUAL_SCAN_DIRECTORY, 0 ,0);
|
||||||
|
break;
|
||||||
case FILEBROWSER_SELECT_DIR:
|
case FILEBROWSER_SELECT_DIR:
|
||||||
if (info)
|
if (info)
|
||||||
menu_entries_prepend(info->list,
|
menu_entries_prepend(info->list,
|
||||||
@ -212,6 +220,8 @@ void filebrowser_parse(menu_displaylist_info_t *info, unsigned type_data)
|
|||||||
continue;
|
continue;
|
||||||
if (filebrowser_types == FILEBROWSER_SCAN_DIR)
|
if (filebrowser_types == FILEBROWSER_SCAN_DIR)
|
||||||
continue;
|
continue;
|
||||||
|
if (filebrowser_types == FILEBROWSER_MANUAL_SCAN_DIR)
|
||||||
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Need to preserve slash first time. */
|
/* Need to preserve slash first time. */
|
||||||
|
@ -32,6 +32,7 @@ enum filebrowser_enums
|
|||||||
FILEBROWSER_SELECT_DIR,
|
FILEBROWSER_SELECT_DIR,
|
||||||
FILEBROWSER_SCAN_DIR,
|
FILEBROWSER_SCAN_DIR,
|
||||||
FILEBROWSER_SCAN_FILE,
|
FILEBROWSER_SCAN_FILE,
|
||||||
|
FILEBROWSER_MANUAL_SCAN_DIR,
|
||||||
FILEBROWSER_SELECT_FILE,
|
FILEBROWSER_SELECT_FILE,
|
||||||
FILEBROWSER_SELECT_FILE_SUBSYSTEM,
|
FILEBROWSER_SELECT_FILE_SUBSYSTEM,
|
||||||
FILEBROWSER_SELECT_IMAGE,
|
FILEBROWSER_SELECT_IMAGE,
|
||||||
|
32
msg_hash.h
32
msg_hash.h
@ -151,6 +151,8 @@ enum msg_file_type
|
|||||||
* menu_cbs_init_bind_get_string_representation_compare_type() breaks... */
|
* menu_cbs_init_bind_get_string_representation_compare_type() breaks... */
|
||||||
FILE_TYPE_DOWNLOAD_PL_THUMBNAIL_CONTENT,
|
FILE_TYPE_DOWNLOAD_PL_THUMBNAIL_CONTENT,
|
||||||
|
|
||||||
|
FILE_TYPE_MANUAL_SCAN_DIRECTORY,
|
||||||
|
|
||||||
FILE_TYPE_LAST
|
FILE_TYPE_LAST
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -1245,6 +1247,8 @@ enum msg_hash_enums
|
|||||||
MENU_ENUM_LABEL_DEFERRED_DROPDOWN_BOX_LIST_PLAYLIST_LABEL_DISPLAY_MODE,
|
MENU_ENUM_LABEL_DEFERRED_DROPDOWN_BOX_LIST_PLAYLIST_LABEL_DISPLAY_MODE,
|
||||||
MENU_ENUM_LABEL_DEFERRED_DROPDOWN_BOX_LIST_PLAYLIST_RIGHT_THUMBNAIL_MODE,
|
MENU_ENUM_LABEL_DEFERRED_DROPDOWN_BOX_LIST_PLAYLIST_RIGHT_THUMBNAIL_MODE,
|
||||||
MENU_ENUM_LABEL_DEFERRED_DROPDOWN_BOX_LIST_PLAYLIST_LEFT_THUMBNAIL_MODE,
|
MENU_ENUM_LABEL_DEFERRED_DROPDOWN_BOX_LIST_PLAYLIST_LEFT_THUMBNAIL_MODE,
|
||||||
|
MENU_ENUM_LABEL_DEFERRED_DROPDOWN_BOX_LIST_MANUAL_CONTENT_SCAN_SYSTEM_NAME,
|
||||||
|
MENU_ENUM_LABEL_DEFERRED_DROPDOWN_BOX_LIST_MANUAL_CONTENT_SCAN_CORE_NAME,
|
||||||
MENU_ENUM_LABEL_DEFERRED_MIXER_STREAM_SETTINGS_LIST,
|
MENU_ENUM_LABEL_DEFERRED_MIXER_STREAM_SETTINGS_LIST,
|
||||||
MENU_ENUM_LABEL_DEFERRED_CONFIGURATIONS_LIST,
|
MENU_ENUM_LABEL_DEFERRED_CONFIGURATIONS_LIST,
|
||||||
MENU_ENUM_LABEL_DEFERRED_FAVORITES_LIST,
|
MENU_ENUM_LABEL_DEFERRED_FAVORITES_LIST,
|
||||||
@ -1343,6 +1347,7 @@ enum msg_hash_enums
|
|||||||
MENU_ENUM_LABEL_DEFERRED_ACCOUNTS_YOUTUBE_LIST,
|
MENU_ENUM_LABEL_DEFERRED_ACCOUNTS_YOUTUBE_LIST,
|
||||||
MENU_ENUM_LABEL_DEFERRED_ACCOUNTS_LIST,
|
MENU_ENUM_LABEL_DEFERRED_ACCOUNTS_LIST,
|
||||||
MENU_ENUM_LABEL_DEFERRED_INFORMATION,
|
MENU_ENUM_LABEL_DEFERRED_INFORMATION,
|
||||||
|
MENU_ENUM_LABEL_DEFERRED_MANUAL_CONTENT_SCAN_LIST,
|
||||||
|
|
||||||
MENU_LABEL(FILE_DETECT_CORE_LIST_PUSH_DIR),
|
MENU_LABEL(FILE_DETECT_CORE_LIST_PUSH_DIR),
|
||||||
MENU_LABEL(DOWNLOADED_FILE_DETECT_CORE_LIST),
|
MENU_LABEL(DOWNLOADED_FILE_DETECT_CORE_LIST),
|
||||||
@ -2658,6 +2663,27 @@ enum msg_hash_enums
|
|||||||
MSG_NO_DISC_INSERTED,
|
MSG_NO_DISC_INSERTED,
|
||||||
MENU_LABEL(DELETE_PLAYLIST),
|
MENU_LABEL(DELETE_PLAYLIST),
|
||||||
|
|
||||||
|
/* Manual content scan */
|
||||||
|
MENU_LABEL(MANUAL_CONTENT_SCAN_LIST),
|
||||||
|
MENU_LABEL(MANUAL_CONTENT_SCAN_DIR),
|
||||||
|
MENU_LABEL(MANUAL_CONTENT_SCAN_SYSTEM_NAME),
|
||||||
|
MENU_LABEL(MANUAL_CONTENT_SCAN_SYSTEM_NAME_CUSTOM),
|
||||||
|
MENU_LABEL(MANUAL_CONTENT_SCAN_CORE_NAME),
|
||||||
|
MENU_LABEL(MANUAL_CONTENT_SCAN_FILE_EXTS),
|
||||||
|
MENU_LABEL(MANUAL_CONTENT_SCAN_OVERWRITE),
|
||||||
|
MENU_LABEL(MANUAL_CONTENT_SCAN_START),
|
||||||
|
|
||||||
|
MENU_ENUM_LABEL_VALUE_MANUAL_CONTENT_SCAN_SYSTEM_NAME_USE_CONTENT_DIR,
|
||||||
|
MENU_ENUM_LABEL_VALUE_MANUAL_CONTENT_SCAN_SYSTEM_NAME_USE_CUSTOM,
|
||||||
|
|
||||||
|
MENU_ENUM_LABEL_VALUE_MANUAL_CONTENT_SCAN_CORE_NAME_DETECT,
|
||||||
|
|
||||||
|
MSG_MANUAL_CONTENT_SCAN_INVALID_CONFIG,
|
||||||
|
MSG_MANUAL_CONTENT_SCAN_INVALID_CONTENT,
|
||||||
|
MSG_MANUAL_CONTENT_SCAN_START,
|
||||||
|
MSG_MANUAL_CONTENT_SCAN_IN_PROGRESS,
|
||||||
|
MSG_MANUAL_CONTENT_SCAN_END,
|
||||||
|
|
||||||
MSG_LAST
|
MSG_LAST
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -2715,6 +2741,7 @@ enum msg_hash_enums
|
|||||||
#define MENU_LABEL_DEFERRED_CONFIGURATIONS_LIST 0x679a1b0bU
|
#define MENU_LABEL_DEFERRED_CONFIGURATIONS_LIST 0x679a1b0bU
|
||||||
#define MENU_LABEL_DEFERRED_BROWSE_URL_START 0xcef58296U
|
#define MENU_LABEL_DEFERRED_BROWSE_URL_START 0xcef58296U
|
||||||
#define MENU_LABEL_DEFERRED_INFORMATION 0x3FCC9F2BU
|
#define MENU_LABEL_DEFERRED_INFORMATION 0x3FCC9F2BU
|
||||||
|
#define MENU_LABEL_DEFERRED_MANUAL_CONTENT_SCAN_LIST 0x479546DCU
|
||||||
|
|
||||||
/* Cheevos settings */
|
/* Cheevos settings */
|
||||||
|
|
||||||
@ -2910,6 +2937,11 @@ enum msg_hash_enums
|
|||||||
#define MENU_LABEL_HELP_CHANGE_VIRTUAL_GAMEPAD 0x6e66ef07U
|
#define MENU_LABEL_HELP_CHANGE_VIRTUAL_GAMEPAD 0x6e66ef07U
|
||||||
#define MENU_LABEL_HELP_AUDIO_VIDEO_TROUBLESHOOTING 0xd44d395cU
|
#define MENU_LABEL_HELP_AUDIO_VIDEO_TROUBLESHOOTING 0xd44d395cU
|
||||||
|
|
||||||
|
/* Manual content scan */
|
||||||
|
#define MENU_LABEL_MANUAL_CONTENT_SCAN_DIR 0x6674149FU
|
||||||
|
#define MENU_LABEL_MANUAL_CONTENT_SCAN_SYSTEM_NAME 0xA3EC34C5U
|
||||||
|
#define MENU_LABEL_MANUAL_CONTENT_SCAN_CORE_NAME 0xD13B7849U
|
||||||
|
|
||||||
/* Main menu */
|
/* Main menu */
|
||||||
#define MENU_LABEL_LOAD_CONTENT_LIST 0x5745de1fU
|
#define MENU_LABEL_LOAD_CONTENT_LIST 0x5745de1fU
|
||||||
#define MENU_LABEL_LOAD_CONTENT_HISTORY 0xfe1d79e5U
|
#define MENU_LABEL_LOAD_CONTENT_HISTORY 0xfe1d79e5U
|
||||||
|
@ -368,8 +368,7 @@ void playlist_get_index_by_path(playlist_t *playlist,
|
|||||||
}
|
}
|
||||||
|
|
||||||
bool playlist_entry_exists(playlist_t *playlist,
|
bool playlist_entry_exists(playlist_t *playlist,
|
||||||
const char *path,
|
const char *path)
|
||||||
const char *crc32)
|
|
||||||
{
|
{
|
||||||
size_t i;
|
size_t i;
|
||||||
char real_search_path[PATH_MAX_LENGTH];
|
char real_search_path[PATH_MAX_LENGTH];
|
||||||
|
@ -214,8 +214,7 @@ void playlist_get_index_by_path(playlist_t *playlist,
|
|||||||
const struct playlist_entry **entry);
|
const struct playlist_entry **entry);
|
||||||
|
|
||||||
bool playlist_entry_exists(playlist_t *playlist,
|
bool playlist_entry_exists(playlist_t *playlist,
|
||||||
const char *path,
|
const char *path);
|
||||||
const char *crc32);
|
|
||||||
|
|
||||||
char *playlist_get_conf_path(playlist_t *playlist);
|
char *playlist_get_conf_path(playlist_t *playlist);
|
||||||
|
|
||||||
|
@ -850,7 +850,7 @@ static int database_info_list_iterate_found_match(
|
|||||||
fprintf(stderr, "entry path str: %s\n", entry_path_str);
|
fprintf(stderr, "entry path str: %s\n", entry_path_str);
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
if (!playlist_entry_exists(playlist, entry_path_str, db_crc))
|
if (!playlist_entry_exists(playlist, entry_path_str))
|
||||||
{
|
{
|
||||||
struct playlist_entry entry;
|
struct playlist_entry entry;
|
||||||
|
|
||||||
@ -1052,8 +1052,7 @@ static int task_database_iterate_playlist_lutro(
|
|||||||
|
|
||||||
free(db_playlist_path);
|
free(db_playlist_path);
|
||||||
|
|
||||||
if (!playlist_entry_exists(playlist,
|
if (!playlist_entry_exists(playlist, path))
|
||||||
path, "DETECT"))
|
|
||||||
{
|
{
|
||||||
struct playlist_entry entry;
|
struct playlist_entry entry;
|
||||||
char *game_title = (char*)malloc(PATH_MAX_LENGTH * sizeof(char));
|
char *game_title = (char*)malloc(PATH_MAX_LENGTH * sizeof(char));
|
||||||
|
354
tasks/task_manual_content_scan.c
Normal file
354
tasks/task_manual_content_scan.c
Normal file
@ -0,0 +1,354 @@
|
|||||||
|
/* RetroArch - A frontend for libretro.
|
||||||
|
* Copyright (C) 2011-2017 - Daniel De Matteis
|
||||||
|
* Copyright (C) 2014-2017 - Jean-André Santoni
|
||||||
|
* 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 <http://www.gnu.org/licenses/>.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include <stdlib.h>
|
||||||
|
#include <string.h>
|
||||||
|
#include <stdio.h>
|
||||||
|
#include <ctype.h>
|
||||||
|
#include <boolean.h>
|
||||||
|
|
||||||
|
#include <string/stdstring.h>
|
||||||
|
#include <lists/string_list.h>
|
||||||
|
#include <file/file_path.h>
|
||||||
|
|
||||||
|
#include "tasks_internal.h"
|
||||||
|
|
||||||
|
#include "../retroarch.h"
|
||||||
|
#include "../msg_hash.h"
|
||||||
|
#include "../playlist.h"
|
||||||
|
#include "../manual_content_scan.h"
|
||||||
|
|
||||||
|
#ifdef RARCH_INTERNAL
|
||||||
|
#ifdef HAVE_MENU
|
||||||
|
#include "../menu/menu_driver.h"
|
||||||
|
#endif
|
||||||
|
#endif
|
||||||
|
|
||||||
|
enum manual_scan_status
|
||||||
|
{
|
||||||
|
MANUAL_SCAN_BEGIN = 0,
|
||||||
|
MANUAL_SCAN_ITERATE_CONTENT,
|
||||||
|
MANUAL_SCAN_END
|
||||||
|
};
|
||||||
|
|
||||||
|
typedef struct manual_scan_handle
|
||||||
|
{
|
||||||
|
manual_content_scan_task_config_t *task_config;
|
||||||
|
playlist_t *playlist;
|
||||||
|
struct string_list *content_list;
|
||||||
|
size_t list_size;
|
||||||
|
size_t list_index;
|
||||||
|
enum manual_scan_status status;
|
||||||
|
} manual_scan_handle_t;
|
||||||
|
|
||||||
|
/* Frees task handle + all constituent objects */
|
||||||
|
static void free_manual_content_scan_handle(manual_scan_handle_t *manual_scan)
|
||||||
|
{
|
||||||
|
if (!manual_scan)
|
||||||
|
return;
|
||||||
|
|
||||||
|
if (manual_scan->task_config)
|
||||||
|
{
|
||||||
|
free(manual_scan->task_config);
|
||||||
|
manual_scan->task_config = NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (manual_scan->playlist)
|
||||||
|
{
|
||||||
|
playlist_free(manual_scan->playlist);
|
||||||
|
manual_scan->playlist = NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (manual_scan->content_list)
|
||||||
|
{
|
||||||
|
string_list_free(manual_scan->content_list);
|
||||||
|
manual_scan->content_list = NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
free(manual_scan);
|
||||||
|
manual_scan = NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
static void task_manual_content_scan_handler(retro_task_t *task)
|
||||||
|
{
|
||||||
|
manual_scan_handle_t *manual_scan = NULL;
|
||||||
|
|
||||||
|
if (!task)
|
||||||
|
goto task_finished;
|
||||||
|
|
||||||
|
manual_scan = (manual_scan_handle_t*)task->state;
|
||||||
|
|
||||||
|
if (!manual_scan)
|
||||||
|
goto task_finished;
|
||||||
|
|
||||||
|
if (task_get_cancelled(task))
|
||||||
|
goto task_finished;
|
||||||
|
|
||||||
|
switch (manual_scan->status)
|
||||||
|
{
|
||||||
|
case MANUAL_SCAN_BEGIN:
|
||||||
|
{
|
||||||
|
/* Get content list */
|
||||||
|
manual_scan->content_list = manual_content_scan_get_content_list(
|
||||||
|
manual_scan->task_config);
|
||||||
|
|
||||||
|
if (!manual_scan->content_list)
|
||||||
|
{
|
||||||
|
runloop_msg_queue_push(
|
||||||
|
msg_hash_to_str(MSG_MANUAL_CONTENT_SCAN_INVALID_CONTENT),
|
||||||
|
1, 100, true,
|
||||||
|
NULL, MESSAGE_QUEUE_ICON_DEFAULT, MESSAGE_QUEUE_CATEGORY_INFO);
|
||||||
|
goto task_finished;
|
||||||
|
}
|
||||||
|
|
||||||
|
manual_scan->list_size = manual_scan->content_list->size;
|
||||||
|
|
||||||
|
/* Open playlist */
|
||||||
|
manual_scan->playlist = playlist_init(
|
||||||
|
manual_scan->task_config->playlist_file, COLLECTION_SIZE);
|
||||||
|
|
||||||
|
if (!manual_scan->playlist)
|
||||||
|
goto task_finished;
|
||||||
|
|
||||||
|
/* Reset playlist, if required */
|
||||||
|
if (manual_scan->task_config->overwrite_playlist)
|
||||||
|
playlist_clear(manual_scan->playlist);
|
||||||
|
|
||||||
|
/* Set default core, if required */
|
||||||
|
if (manual_scan->task_config->core_set)
|
||||||
|
{
|
||||||
|
playlist_set_default_core_path(
|
||||||
|
manual_scan->playlist, manual_scan->task_config->core_path);
|
||||||
|
playlist_set_default_core_name(
|
||||||
|
manual_scan->playlist, manual_scan->task_config->core_name);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* All good - can start iterating */
|
||||||
|
manual_scan->status = MANUAL_SCAN_ITERATE_CONTENT;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case MANUAL_SCAN_ITERATE_CONTENT:
|
||||||
|
{
|
||||||
|
const char *content_path =
|
||||||
|
manual_scan->content_list->elems[manual_scan->list_index].data;
|
||||||
|
|
||||||
|
if (!string_is_empty(content_path))
|
||||||
|
{
|
||||||
|
const char *content_file = path_basename(content_path);
|
||||||
|
char task_title[PATH_MAX_LENGTH];
|
||||||
|
|
||||||
|
task_title[0] = '\0';
|
||||||
|
|
||||||
|
/* Update progress display */
|
||||||
|
task_free_title(task);
|
||||||
|
|
||||||
|
strlcpy(
|
||||||
|
task_title, msg_hash_to_str(MSG_MANUAL_CONTENT_SCAN_IN_PROGRESS),
|
||||||
|
sizeof(task_title));
|
||||||
|
|
||||||
|
if (!string_is_empty(content_file))
|
||||||
|
strlcat(task_title, content_file, sizeof(task_title));
|
||||||
|
|
||||||
|
task_set_title(task, strdup(task_title));
|
||||||
|
task_set_progress(task, (manual_scan->list_index * 100) / manual_scan->list_size);
|
||||||
|
|
||||||
|
/* Add content to playlist */
|
||||||
|
manual_content_scan_add_content_to_playlist(
|
||||||
|
manual_scan->task_config, manual_scan->playlist,
|
||||||
|
content_path);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Increment content index */
|
||||||
|
manual_scan->list_index++;
|
||||||
|
if (manual_scan->list_index >= manual_scan->list_size)
|
||||||
|
manual_scan->status = MANUAL_SCAN_END;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case MANUAL_SCAN_END:
|
||||||
|
{
|
||||||
|
playlist_t *cached_playlist = playlist_get_cached();
|
||||||
|
char task_title[PATH_MAX_LENGTH];
|
||||||
|
|
||||||
|
task_title[0] = '\0';
|
||||||
|
|
||||||
|
/* Ensure playlist is alphabetically sorted */
|
||||||
|
playlist_qsort(manual_scan->playlist);
|
||||||
|
|
||||||
|
/* Save playlist changes to disk */
|
||||||
|
playlist_write_file(manual_scan->playlist);
|
||||||
|
|
||||||
|
/* If this is the currently cached playlist, then
|
||||||
|
* it must be re-cached (otherwise changes will be
|
||||||
|
* lost if the currently cached playlist is saved
|
||||||
|
* to disk for any reason...) */
|
||||||
|
if (cached_playlist)
|
||||||
|
{
|
||||||
|
if (string_is_equal(
|
||||||
|
manual_scan->task_config->playlist_file,
|
||||||
|
playlist_get_conf_path(cached_playlist)))
|
||||||
|
{
|
||||||
|
playlist_free_cached();
|
||||||
|
playlist_init_cached(
|
||||||
|
manual_scan->task_config->playlist_file, COLLECTION_SIZE);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Update progress display */
|
||||||
|
task_free_title(task);
|
||||||
|
|
||||||
|
strlcpy(
|
||||||
|
task_title, msg_hash_to_str(MSG_MANUAL_CONTENT_SCAN_END),
|
||||||
|
sizeof(task_title));
|
||||||
|
strlcat(task_title, manual_scan->task_config->system_name,
|
||||||
|
sizeof(task_title));
|
||||||
|
|
||||||
|
task_set_title(task, strdup(task_title));
|
||||||
|
}
|
||||||
|
/* fall-through */
|
||||||
|
default:
|
||||||
|
task_set_progress(task, 100);
|
||||||
|
goto task_finished;
|
||||||
|
}
|
||||||
|
|
||||||
|
return;
|
||||||
|
|
||||||
|
task_finished:
|
||||||
|
|
||||||
|
if (task)
|
||||||
|
task_set_finished(task, true);
|
||||||
|
|
||||||
|
free_manual_content_scan_handle(manual_scan);
|
||||||
|
}
|
||||||
|
|
||||||
|
static bool task_manual_content_scan_finder(retro_task_t *task, void *user_data)
|
||||||
|
{
|
||||||
|
manual_scan_handle_t *manual_scan = NULL;
|
||||||
|
|
||||||
|
if (!task || !user_data)
|
||||||
|
return false;
|
||||||
|
|
||||||
|
if (task->handler != task_manual_content_scan_handler)
|
||||||
|
return false;
|
||||||
|
|
||||||
|
manual_scan = (manual_scan_handle_t*)task->state;
|
||||||
|
if (!manual_scan)
|
||||||
|
return false;
|
||||||
|
|
||||||
|
return string_is_equal(
|
||||||
|
(const char*)user_data, manual_scan->task_config->playlist_file);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void cb_task_manual_content_scan_refresh_menu(
|
||||||
|
retro_task_t *task, void *task_data,
|
||||||
|
void *user_data, const char *err)
|
||||||
|
{
|
||||||
|
#if defined(RARCH_INTERNAL) && defined(HAVE_MENU)
|
||||||
|
menu_ctx_environment_t menu_environ;
|
||||||
|
menu_environ.type = MENU_ENVIRON_RESET_HORIZONTAL_LIST;
|
||||||
|
menu_environ.data = NULL;
|
||||||
|
|
||||||
|
menu_driver_ctl(RARCH_MENU_CTL_ENVIRONMENT, &menu_environ);
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
|
bool task_push_manual_content_scan(void)
|
||||||
|
{
|
||||||
|
task_finder_data_t find_data;
|
||||||
|
char task_title[PATH_MAX_LENGTH];
|
||||||
|
retro_task_t *task = NULL;
|
||||||
|
manual_scan_handle_t *manual_scan = (manual_scan_handle_t*)
|
||||||
|
calloc(1, sizeof(manual_scan_handle_t));
|
||||||
|
|
||||||
|
task_title[0] = '\0';
|
||||||
|
|
||||||
|
/* Sanity check */
|
||||||
|
if (!manual_scan)
|
||||||
|
goto error;
|
||||||
|
|
||||||
|
/* Configure handle */
|
||||||
|
manual_scan->task_config = NULL;
|
||||||
|
manual_scan->playlist = NULL;
|
||||||
|
manual_scan->content_list = NULL;
|
||||||
|
manual_scan->list_size = 0;
|
||||||
|
manual_scan->list_index = 0;
|
||||||
|
manual_scan->status = MANUAL_SCAN_BEGIN;
|
||||||
|
|
||||||
|
/* > Get current manual content scan configuration */
|
||||||
|
manual_scan->task_config = (manual_content_scan_task_config_t*)
|
||||||
|
calloc(1, sizeof(manual_content_scan_task_config_t));
|
||||||
|
|
||||||
|
if (!manual_scan->task_config)
|
||||||
|
goto error;
|
||||||
|
|
||||||
|
if (!manual_content_scan_get_task_config(manual_scan->task_config))
|
||||||
|
{
|
||||||
|
runloop_msg_queue_push(
|
||||||
|
msg_hash_to_str(MSG_MANUAL_CONTENT_SCAN_INVALID_CONFIG),
|
||||||
|
1, 100, true,
|
||||||
|
NULL, MESSAGE_QUEUE_ICON_DEFAULT, MESSAGE_QUEUE_CATEGORY_INFO);
|
||||||
|
goto error;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Concurrent scanning of content to the same
|
||||||
|
* playlist is not allowed */
|
||||||
|
find_data.func = task_manual_content_scan_finder;
|
||||||
|
find_data.userdata = (void*)manual_scan->task_config->playlist_file;
|
||||||
|
|
||||||
|
if (task_queue_find(&find_data))
|
||||||
|
goto error;
|
||||||
|
|
||||||
|
/* Create task */
|
||||||
|
task = task_init();
|
||||||
|
|
||||||
|
if (!task)
|
||||||
|
goto error;
|
||||||
|
|
||||||
|
/* > Get task title */
|
||||||
|
strlcpy(
|
||||||
|
task_title, msg_hash_to_str(MSG_MANUAL_CONTENT_SCAN_START),
|
||||||
|
sizeof(task_title));
|
||||||
|
strlcat(task_title, manual_scan->task_config->system_name,
|
||||||
|
sizeof(task_title));
|
||||||
|
|
||||||
|
/* > Configure task */
|
||||||
|
task->handler = task_manual_content_scan_handler;
|
||||||
|
task->state = manual_scan;
|
||||||
|
task->title = strdup(task_title);
|
||||||
|
task->alternative_look = true;
|
||||||
|
task->progress = 0;
|
||||||
|
task->callback = cb_task_manual_content_scan_refresh_menu;
|
||||||
|
|
||||||
|
/* > Push task */
|
||||||
|
task_queue_push(task);
|
||||||
|
|
||||||
|
return true;
|
||||||
|
|
||||||
|
error:
|
||||||
|
|
||||||
|
/* Clean up task */
|
||||||
|
if (task)
|
||||||
|
{
|
||||||
|
free(task);
|
||||||
|
task = NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Clean up handle */
|
||||||
|
free_manual_content_scan_handle(manual_scan);
|
||||||
|
manual_scan = NULL;
|
||||||
|
|
||||||
|
return false;
|
||||||
|
}
|
@ -98,6 +98,8 @@ bool task_push_dbscan(
|
|||||||
retro_task_callback_t cb);
|
retro_task_callback_t cb);
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
bool task_push_manual_content_scan(void);
|
||||||
|
|
||||||
#ifdef HAVE_OVERLAY
|
#ifdef HAVE_OVERLAY
|
||||||
bool task_push_overlay_load_default(
|
bool task_push_overlay_load_default(
|
||||||
retro_task_callback_t cb,
|
retro_task_callback_t cb,
|
||||||
|
Loading…
x
Reference in New Issue
Block a user