mirror of
https://github.com/libretro/RetroArch.git
synced 2024-11-23 16:09:47 +00:00
Add content import/scan via CLI
This commit is contained in:
parent
15e04b8767
commit
f5f1d35370
@ -1294,8 +1294,9 @@ bool gfx_display_init_first_driver(gfx_display_t *p_disp,
|
|||||||
video_is_threaded))
|
video_is_threaded))
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
RARCH_LOG("[Display]: Found display driver: \"%s\".\n",
|
if (video_driver)
|
||||||
gfx_display_ctx_drivers[i]->ident);
|
RARCH_LOG("[Display]: Found display driver: \"%s\".\n",
|
||||||
|
gfx_display_ctx_drivers[i]->ident);
|
||||||
p_disp->dispctx = gfx_display_ctx_drivers[i];
|
p_disp->dispctx = gfx_display_ctx_drivers[i];
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
97
retroarch.c
97
retroarch.c
@ -286,6 +286,7 @@ enum
|
|||||||
RA_OPT_MAX_FRAMES_SCREENSHOT,
|
RA_OPT_MAX_FRAMES_SCREENSHOT,
|
||||||
RA_OPT_MAX_FRAMES_SCREENSHOT_PATH,
|
RA_OPT_MAX_FRAMES_SCREENSHOT_PATH,
|
||||||
RA_OPT_SET_SHADER,
|
RA_OPT_SET_SHADER,
|
||||||
|
RA_OPT_DATABASE_SCAN,
|
||||||
RA_OPT_ACCESSIBILITY,
|
RA_OPT_ACCESSIBILITY,
|
||||||
RA_OPT_LOAD_MENU_ON_ERROR
|
RA_OPT_LOAD_MENU_ON_ERROR
|
||||||
};
|
};
|
||||||
@ -4932,8 +4933,7 @@ static void retroarch_print_help(const char *arg0)
|
|||||||
"Show version.\n"
|
"Show version.\n"
|
||||||
" --features "
|
" --features "
|
||||||
"Print available features compiled into program.\n"
|
"Print available features compiled into program.\n"
|
||||||
,
|
, sizeof(buf));
|
||||||
sizeof(buf));
|
|
||||||
#ifdef HAVE_MENU
|
#ifdef HAVE_MENU
|
||||||
strlcat(buf,
|
strlcat(buf,
|
||||||
" --menu "
|
" --menu "
|
||||||
@ -4942,8 +4942,7 @@ static void retroarch_print_help(const char *arg0)
|
|||||||
" starts directly in menu. If no arguments are passed to\n"
|
" starts directly in menu. If no arguments are passed to\n"
|
||||||
" "
|
" "
|
||||||
" the program, it is equivalent to using --menu as only argument.\n"
|
" the program, it is equivalent to using --menu as only argument.\n"
|
||||||
,
|
, sizeof(buf));
|
||||||
sizeof(buf));
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#ifdef HAVE_CONFIGFILE
|
#ifdef HAVE_CONFIGFILE
|
||||||
@ -5011,14 +5010,24 @@ static void retroarch_print_help(const char *arg0)
|
|||||||
" files are loaded as multiple arguments. If a content\n"
|
" files are loaded as multiple arguments. If a content\n"
|
||||||
" "
|
" "
|
||||||
" file is skipped, use a blank (\"\") command line argument.\n"
|
" file is skipped, use a blank (\"\") command line argument.\n"
|
||||||
|
, sizeof(buf));
|
||||||
|
strlcat(buf,
|
||||||
" "
|
" "
|
||||||
" Content must be loaded in an order which depends on the\n"
|
" Content must be loaded in an order which depends on the\n"
|
||||||
" "
|
" "
|
||||||
" particular subsystem used. See verbose log output to learn\n"
|
" particular subsystem used. See verbose log output to learn\n"
|
||||||
" "
|
" "
|
||||||
, sizeof(buf));
|
|
||||||
strlcat(buf,
|
|
||||||
" how a particular subsystem wants content to be loaded.\n"
|
" how a particular subsystem wants content to be loaded.\n"
|
||||||
|
, sizeof(buf));
|
||||||
|
|
||||||
|
#ifdef HAVE_LIBRETRODB
|
||||||
|
strlcat(buf,
|
||||||
|
" --scan=PATH|FILE "
|
||||||
|
"Import content from path.\n"
|
||||||
|
, sizeof(buf));
|
||||||
|
#endif
|
||||||
|
|
||||||
|
strlcat(buf,
|
||||||
" -f, --fullscreen "
|
" -f, --fullscreen "
|
||||||
"Start the program in fullscreen regardless of config setting.\n"
|
"Start the program in fullscreen regardless of config setting.\n"
|
||||||
" --set-shader=PATH "
|
" --set-shader=PATH "
|
||||||
@ -5063,7 +5072,8 @@ static void retroarch_print_help(const char *arg0)
|
|||||||
"Check frames when using netplay.\n"
|
"Check frames when using netplay.\n"
|
||||||
, sizeof(buf));
|
, sizeof(buf));
|
||||||
#ifdef HAVE_NETWORK_CMD
|
#ifdef HAVE_NETWORK_CMD
|
||||||
strlcat(buf, " --command "
|
strlcat(buf,
|
||||||
|
" --command "
|
||||||
"Sends a command over UDP to an already running program process.\n"
|
"Sends a command over UDP to an already running program process.\n"
|
||||||
" "
|
" "
|
||||||
" Available commands are listed if command is invalid.\n"
|
" Available commands are listed if command is invalid.\n"
|
||||||
@ -5082,24 +5092,27 @@ static void retroarch_print_help(const char *arg0)
|
|||||||
, sizeof(buf));
|
, sizeof(buf));
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
strlcat(buf, " -r, --record=FILE "
|
strlcat(buf,
|
||||||
|
" -r, --record=FILE "
|
||||||
"Path to record video file. Using mkv extension is recommended.\n"
|
"Path to record video file. Using mkv extension is recommended.\n"
|
||||||
" --recordconfig "
|
" --recordconfig "
|
||||||
"Path to settings used during recording.\n"
|
"Path to settings used during recording.\n"
|
||||||
" --size=WIDTHxHEIGHT "
|
" --size=WIDTHxHEIGHT "
|
||||||
"Overrides output video size when recording.\n"
|
"Overrides output video size when recording.\n"
|
||||||
,
|
, sizeof(buf));
|
||||||
sizeof(buf));
|
|
||||||
|
|
||||||
fputs(buf, stdout);
|
fputs(buf, stdout);
|
||||||
buf[0] = '\0';
|
buf[0] = '\0';
|
||||||
|
|
||||||
strlcat(buf, " -D, --detach "
|
strlcat(buf,
|
||||||
|
" -D, --detach "
|
||||||
"Detach program from the running console. Not relevant for all platforms.\n"
|
"Detach program from the running console. Not relevant for all platforms.\n"
|
||||||
" --max-frames=NUMBER "
|
" --max-frames=NUMBER "
|
||||||
"Runs for the specified number of frames, then exits.\n"
|
"Runs for the specified number of frames, then exits.\n"
|
||||||
, sizeof(buf));
|
, sizeof(buf));
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
#ifdef HAVE_PATCH
|
#ifdef HAVE_PATCH
|
||||||
strlcat(buf,
|
strlcat(buf,
|
||||||
" -U, --ups=FILE "
|
" -U, --ups=FILE "
|
||||||
@ -5123,8 +5136,10 @@ static void retroarch_print_help(const char *arg0)
|
|||||||
#endif
|
#endif
|
||||||
|
|
||||||
#ifdef HAVE_ACCESSIBILITY
|
#ifdef HAVE_ACCESSIBILITY
|
||||||
strlcat(buf, " --accessibility "
|
strlcat(buf,
|
||||||
"Enables accessibilty for blind users using text-to-speech.\n", sizeof(buf));
|
" --accessibility "
|
||||||
|
"Enables accessibilty for blind users using text-to-speech.\n"
|
||||||
|
, sizeof(buf));
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
strlcat(buf,
|
strlcat(buf,
|
||||||
@ -5136,8 +5151,7 @@ static void retroarch_print_help(const char *arg0)
|
|||||||
"Path for save files (*.srm). (DEPRECATED, use --appendconfig and savefile_directory)\n"
|
"Path for save files (*.srm). (DEPRECATED, use --appendconfig and savefile_directory)\n"
|
||||||
" -S, --savestate=PATH "
|
" -S, --savestate=PATH "
|
||||||
"Path for the save state files (*.state). (DEPRECATED, use --appendconfig and savestate_directory)\n"
|
"Path for the save state files (*.state). (DEPRECATED, use --appendconfig and savestate_directory)\n"
|
||||||
,
|
, sizeof(buf));
|
||||||
sizeof(buf));
|
|
||||||
|
|
||||||
fputs(buf, stdout);
|
fputs(buf, stdout);
|
||||||
}
|
}
|
||||||
@ -5280,6 +5294,11 @@ end:
|
|||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
#ifdef HAVE_LIBRETRODB
|
||||||
|
void handle_dbscan_finished(retro_task_t *task,
|
||||||
|
void *task_data, void *user_data, const char *err);
|
||||||
|
#endif
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* retroarch_parse_input_and_config:
|
* retroarch_parse_input_and_config:
|
||||||
* @argc : Count of (commandline) arguments.
|
* @argc : Count of (commandline) arguments.
|
||||||
@ -5309,6 +5328,10 @@ static bool retroarch_parse_input_and_config(
|
|||||||
#ifdef HAVE_ACCESSIBILITY
|
#ifdef HAVE_ACCESSIBILITY
|
||||||
access_state_t *access_st = access_state_get_ptr();
|
access_state_t *access_st = access_state_get_ptr();
|
||||||
#endif
|
#endif
|
||||||
|
#ifdef HAVE_LIBRETRODB
|
||||||
|
retro_task_callback_t cb_task_dbscan
|
||||||
|
= NULL;
|
||||||
|
#endif
|
||||||
|
|
||||||
const struct option opts[] = {
|
const struct option opts[] = {
|
||||||
#ifdef HAVE_DYNAMIC
|
#ifdef HAVE_DYNAMIC
|
||||||
@ -5364,6 +5387,9 @@ static bool retroarch_parse_input_and_config(
|
|||||||
{ "accessibility", 0, NULL, RA_OPT_ACCESSIBILITY},
|
{ "accessibility", 0, NULL, RA_OPT_ACCESSIBILITY},
|
||||||
{ "load-menu-on-error", 0, NULL, RA_OPT_LOAD_MENU_ON_ERROR },
|
{ "load-menu-on-error", 0, NULL, RA_OPT_LOAD_MENU_ON_ERROR },
|
||||||
{ "entryslot", 1, NULL, 'e' },
|
{ "entryslot", 1, NULL, 'e' },
|
||||||
|
#ifdef HAVE_LIBRETRODB
|
||||||
|
{ "scan", 1, NULL, RA_OPT_DATABASE_SCAN },
|
||||||
|
#endif
|
||||||
{ NULL, 0, NULL, 0 }
|
{ NULL, 0, NULL, 0 }
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -5532,6 +5558,15 @@ static bool retroarch_parse_input_and_config(
|
|||||||
rarch_log_file_set_override(optarg);
|
rarch_log_file_set_override(optarg);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
|
case RA_OPT_MENU:
|
||||||
|
explicit_menu = true;
|
||||||
|
break;
|
||||||
|
case RA_OPT_DATABASE_SCAN:
|
||||||
|
#ifdef HAVE_LIBRETRODB
|
||||||
|
verbosity_enable();
|
||||||
|
#endif
|
||||||
|
break;
|
||||||
|
|
||||||
/* Must handle '?' otherwise you get an infinite loop */
|
/* Must handle '?' otherwise you get an infinite loop */
|
||||||
case '?':
|
case '?':
|
||||||
frontend_driver_attach_console();
|
frontend_driver_attach_console();
|
||||||
@ -5915,6 +5950,38 @@ static bool retroarch_parse_input_and_config(
|
|||||||
"entry state slot index. Ignoring.\n", optarg);
|
"entry state slot index. Ignoring.\n", optarg);
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
case RA_OPT_DATABASE_SCAN:
|
||||||
|
#ifdef HAVE_LIBRETRODB
|
||||||
|
{
|
||||||
|
settings_t *settings = config_get_ptr();
|
||||||
|
bool show_hidden_files = settings->bools.show_hidden_files;
|
||||||
|
const char *directory_playlist = settings->paths.directory_playlist;
|
||||||
|
const char *path_content_db = settings->paths.path_content_database;
|
||||||
|
int reinit_flags = DRIVERS_CMD_ALL &
|
||||||
|
~(DRIVER_VIDEO_MASK | DRIVER_AUDIO_MASK | DRIVER_INPUT_MASK | DRIVER_MIDI_MASK);
|
||||||
|
|
||||||
|
drivers_init(settings, reinit_flags, false);
|
||||||
|
retroarch_init_task_queue();
|
||||||
|
|
||||||
|
if (explicit_menu)
|
||||||
|
cb_task_dbscan = handle_dbscan_finished;
|
||||||
|
|
||||||
|
task_push_dbscan(
|
||||||
|
directory_playlist,
|
||||||
|
path_content_db,
|
||||||
|
optarg, path_is_directory(optarg),
|
||||||
|
show_hidden_files,
|
||||||
|
cb_task_dbscan);
|
||||||
|
|
||||||
|
if (!explicit_menu)
|
||||||
|
{
|
||||||
|
task_queue_wait(NULL, NULL);
|
||||||
|
driver_uninit(DRIVERS_CMD_ALL);
|
||||||
|
exit(0);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
break;
|
||||||
default:
|
default:
|
||||||
RARCH_ERR("%s\n", msg_hash_to_str(MSG_ERROR_PARSING_ARGUMENTS));
|
RARCH_ERR("%s\n", msg_hash_to_str(MSG_ERROR_PARSING_ARGUMENTS));
|
||||||
retroarch_fail(1, "retroarch_parse_input()");
|
retroarch_fail(1, "retroarch_parse_input()");
|
||||||
|
@ -89,12 +89,19 @@ static const char *database_info_get_current_element_name(
|
|||||||
{
|
{
|
||||||
if (!handle || !handle->list)
|
if (!handle || !handle->list)
|
||||||
return NULL;
|
return NULL;
|
||||||
|
#if 1
|
||||||
|
/* Don't skip pruned entries, otherwise iteration
|
||||||
|
* ends prematurely */
|
||||||
|
if (!handle->list->elems[handle->list_ptr].data)
|
||||||
|
return "";
|
||||||
|
#else
|
||||||
/* Skip pruned entries */
|
/* Skip pruned entries */
|
||||||
while (!handle->list->elems[handle->list_ptr].data)
|
while (!handle->list->elems[handle->list_ptr].data)
|
||||||
{
|
{
|
||||||
if (++handle->list_ptr >= handle->list->size)
|
if (++handle->list_ptr >= handle->list->size)
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
#endif
|
||||||
return handle->list->elems[handle->list_ptr].data;
|
return handle->list->elems[handle->list_ptr].data;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -103,16 +110,16 @@ static int task_database_iterate_start(retro_task_t *task,
|
|||||||
const char *name)
|
const char *name)
|
||||||
{
|
{
|
||||||
char msg[256];
|
char msg[256];
|
||||||
const char *basename_path = !string_is_empty(name) ?
|
const char *basename_path = !string_is_empty(name)
|
||||||
path_basename_nocompression(name) : "";
|
? path_basename_nocompression(name) : "";
|
||||||
|
|
||||||
msg[0] = '\0';
|
msg[0] = '\0';
|
||||||
|
|
||||||
snprintf(msg, sizeof(msg),
|
if (!string_is_empty(basename_path))
|
||||||
STRING_REP_USIZE "/" STRING_REP_USIZE ": %s %s...\n",
|
snprintf(msg, sizeof(msg),
|
||||||
(size_t)db->list_ptr,
|
STRING_REP_USIZE "/" STRING_REP_USIZE ": %s..\n",
|
||||||
|
db->list_ptr + 1,
|
||||||
(size_t)db->list->size,
|
(size_t)db->list->size,
|
||||||
msg_hash_to_str(MSG_SCANNING),
|
|
||||||
basename_path);
|
basename_path);
|
||||||
|
|
||||||
if (!string_is_empty(msg))
|
if (!string_is_empty(msg))
|
||||||
@ -124,6 +131,9 @@ static int task_database_iterate_start(retro_task_t *task,
|
|||||||
task_set_progress(task,
|
task_set_progress(task,
|
||||||
roundf((float)db->list_ptr /
|
roundf((float)db->list_ptr /
|
||||||
((float)db->list->size / 100.0f)));
|
((float)db->list->size / 100.0f)));
|
||||||
|
RARCH_LOG("[Scanner]: %s", msg);
|
||||||
|
if (verbosity_is_enabled())
|
||||||
|
printf("%s", msg);
|
||||||
#else
|
#else
|
||||||
fprintf(stderr, "msg: %s\n", msg);
|
fprintf(stderr, "msg: %s\n", msg);
|
||||||
#endif
|
#endif
|
||||||
@ -742,7 +752,7 @@ static int database_info_list_iterate_found_match(
|
|||||||
path_basename_nocompression(entry_path), "", str_len);
|
path_basename_nocompression(entry_path), "", str_len);
|
||||||
path_remove_extension(entry_label);
|
path_remove_extension(entry_label);
|
||||||
|
|
||||||
RARCH_LOG("[Database]: No match for: \"%s\", CRC: 0x%08X\n", entry_path_str, db_state->crc);
|
RARCH_LOG("[Scanner]: No match for: \"%s\", CRC: 0x%08X\n", entry_path_str, db_state->crc);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!string_is_empty(archive_name))
|
if (!string_is_empty(archive_name))
|
||||||
@ -793,6 +803,9 @@ static int database_info_list_iterate_found_match(
|
|||||||
entry.last_played_second= 0;
|
entry.last_played_second= 0;
|
||||||
|
|
||||||
playlist_push(playlist, &entry);
|
playlist_push(playlist, &entry);
|
||||||
|
RARCH_LOG("[Scanner]: Add \"%s\"\n", entry_label);
|
||||||
|
if (verbosity_is_enabled())
|
||||||
|
printf("Add \"%s\"\n", entry.label);
|
||||||
}
|
}
|
||||||
|
|
||||||
playlist_write_file(playlist);
|
playlist_write_file(playlist);
|
||||||
@ -828,8 +841,7 @@ static int database_info_list_iterate_found_match(
|
|||||||
/* End of entries in database info list and didn't find a
|
/* End of entries in database info list and didn't find a
|
||||||
* match, go to the next database. */
|
* match, go to the next database. */
|
||||||
static int database_info_list_iterate_next(
|
static int database_info_list_iterate_next(
|
||||||
database_state_handle_t *db_state
|
database_state_handle_t *db_state)
|
||||||
)
|
|
||||||
{
|
{
|
||||||
db_state->list_index++;
|
db_state->list_index++;
|
||||||
db_state->entry_index = 0;
|
db_state->entry_index = 0;
|
||||||
@ -997,8 +1009,7 @@ static int task_database_iterate_serial_lookup(
|
|||||||
db_handle_t *_db,
|
db_handle_t *_db,
|
||||||
database_state_handle_t *db_state,
|
database_state_handle_t *db_state,
|
||||||
database_info_handle_t *db, const char *name,
|
database_info_handle_t *db, const char *name,
|
||||||
bool path_contains_compressed_file
|
bool path_contains_compressed_file)
|
||||||
)
|
|
||||||
{
|
{
|
||||||
if (
|
if (
|
||||||
!db_state->list ||
|
!db_state->list ||
|
||||||
@ -1158,6 +1169,10 @@ static void task_database_handler(retro_task_t *task)
|
|||||||
db->flags & DB_HANDLE_FLAG_SHOW_HIDDEN_FILES,
|
db->flags & DB_HANDLE_FLAG_SHOW_HIDDEN_FILES,
|
||||||
false, false);
|
false, false);
|
||||||
|
|
||||||
|
RARCH_LOG("[Scanner]: %s\"%s\"..\n", msg_hash_to_str(MSG_MANUAL_CONTENT_SCAN_START), db->fullpath);
|
||||||
|
if (verbosity_is_enabled())
|
||||||
|
printf("%s\"%s\"..\n", msg_hash_to_str(MSG_MANUAL_CONTENT_SCAN_START), db->fullpath);
|
||||||
|
|
||||||
/* If the scan path matches a database path exactly then
|
/* If the scan path matches a database path exactly then
|
||||||
* save time by only processing that database. */
|
* save time by only processing that database. */
|
||||||
if (dbstate->list && (db->flags & DB_HANDLE_FLAG_IS_DIRECTORY))
|
if (dbstate->list && (db->flags & DB_HANDLE_FLAG_IS_DIRECTORY))
|
||||||
@ -1248,6 +1263,9 @@ static void task_database_handler(retro_task_t *task)
|
|||||||
task_set_title(task, strdup(msg));
|
task_set_title(task, strdup(msg));
|
||||||
task_set_progress(task, 100);
|
task_set_progress(task, 100);
|
||||||
ui_companion_driver_notify_refresh();
|
ui_companion_driver_notify_refresh();
|
||||||
|
RARCH_LOG("[Scanner]: %s\n", msg);
|
||||||
|
if (verbosity_is_enabled())
|
||||||
|
printf("%s\n", msg);
|
||||||
#else
|
#else
|
||||||
fprintf(stderr, "msg: %s\n", msg);
|
fprintf(stderr, "msg: %s\n", msg);
|
||||||
#endif
|
#endif
|
||||||
@ -1261,6 +1279,7 @@ static void task_database_handler(retro_task_t *task)
|
|||||||
}
|
}
|
||||||
|
|
||||||
return;
|
return;
|
||||||
|
|
||||||
task_finished:
|
task_finished:
|
||||||
if (task)
|
if (task)
|
||||||
task_set_finished(task, true);
|
task_set_finished(task, true);
|
||||||
|
Loading…
Reference in New Issue
Block a user