mirror of
https://github.com/libretro/RetroArch
synced 2025-02-06 00:39:53 +00:00
(Netplay) Force a core update when starting netplay (#14157)
This commit is contained in:
parent
a6516512b6
commit
ef022ffe90
66
retroarch.c
66
retroarch.c
@ -2883,61 +2883,45 @@ bool command_event(enum event_command cmd, void *data)
|
||||
break;
|
||||
case CMD_EVENT_NETPLAY_ENABLE_HOST:
|
||||
{
|
||||
#ifdef HAVE_MENU
|
||||
bool contentless = false;
|
||||
bool is_inited = false;
|
||||
|
||||
content_get_status(&contentless, &is_inited);
|
||||
|
||||
if (netplay_driver_ctl(RARCH_NETPLAY_CTL_IS_DATA_INITED, NULL))
|
||||
command_event(CMD_EVENT_NETPLAY_DEINIT, NULL);
|
||||
netplay_driver_ctl(RARCH_NETPLAY_CTL_ENABLE_SERVER, NULL);
|
||||
|
||||
/* If we haven't yet started, this will load on its own */
|
||||
if (!is_inited)
|
||||
if (!task_push_netplay_content_reload(NULL))
|
||||
{
|
||||
command_event(CMD_EVENT_NETPLAY_DEINIT, NULL);
|
||||
netplay_driver_ctl(RARCH_NETPLAY_CTL_ENABLE_SERVER, NULL);
|
||||
|
||||
runloop_msg_queue_push(
|
||||
msg_hash_to_str(MENU_ENUM_LABEL_VALUE_NETPLAY_START_WHEN_LOADED),
|
||||
1, 480, true,
|
||||
NULL, MESSAGE_QUEUE_ICON_DEFAULT, MESSAGE_QUEUE_CATEGORY_INFO);
|
||||
msg_hash_to_str(MENU_ENUM_LABEL_VALUE_NETPLAY_START_WHEN_LOADED),
|
||||
1, 480, true, NULL,
|
||||
MESSAGE_QUEUE_ICON_DEFAULT, MESSAGE_QUEUE_CATEGORY_INFO);
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
/* Enable Netplay itself */
|
||||
if (!command_event(CMD_EVENT_NETPLAY_INIT, NULL))
|
||||
return false;
|
||||
#endif
|
||||
break;
|
||||
}
|
||||
break;
|
||||
case CMD_EVENT_NETPLAY_DISCONNECT:
|
||||
{
|
||||
bool rewind_enable = settings->bools.rewind_enable;
|
||||
unsigned autosave_interval = settings->uints.autosave_interval;
|
||||
|
||||
netplay_driver_ctl(RARCH_NETPLAY_CTL_DISCONNECT, NULL);
|
||||
netplay_driver_ctl(RARCH_NETPLAY_CTL_DISABLE, NULL);
|
||||
|
||||
{
|
||||
bool rewind_enable = settings->bools.rewind_enable;
|
||||
unsigned autosave_interval = settings->uints.autosave_interval;
|
||||
|
||||
#ifdef HAVE_REWIND
|
||||
/* Re-enable rewind if it was enabled
|
||||
* TODO/FIXME: Add a setting for these tweaks */
|
||||
if (rewind_enable)
|
||||
command_event(CMD_EVENT_REWIND_INIT, NULL);
|
||||
/* Re-enable rewind if it was enabled
|
||||
* TODO/FIXME: Add a setting for these tweaks */
|
||||
if (rewind_enable)
|
||||
command_event(CMD_EVENT_REWIND_INIT, NULL);
|
||||
#endif
|
||||
if (autosave_interval != 0)
|
||||
command_event(CMD_EVENT_AUTOSAVE_INIT, NULL);
|
||||
}
|
||||
|
||||
break;
|
||||
if (autosave_interval != 0)
|
||||
command_event(CMD_EVENT_AUTOSAVE_INIT, NULL);
|
||||
}
|
||||
break;
|
||||
case CMD_EVENT_NETPLAY_HOST_TOGGLE:
|
||||
if (netplay_driver_ctl(RARCH_NETPLAY_CTL_IS_ENABLED, NULL) &&
|
||||
netplay_driver_ctl(RARCH_NETPLAY_CTL_IS_SERVER, NULL))
|
||||
command_event(CMD_EVENT_NETPLAY_DISCONNECT, NULL);
|
||||
else if (netplay_driver_ctl(RARCH_NETPLAY_CTL_IS_ENABLED, NULL) &&
|
||||
!netplay_driver_ctl(RARCH_NETPLAY_CTL_IS_SERVER, NULL) &&
|
||||
netplay_driver_ctl(RARCH_NETPLAY_CTL_IS_CONNECTED, NULL))
|
||||
command_event(CMD_EVENT_NETPLAY_DISCONNECT, NULL);
|
||||
if (netplay_driver_ctl(RARCH_NETPLAY_CTL_IS_ENABLED, NULL))
|
||||
{
|
||||
if (netplay_driver_ctl(RARCH_NETPLAY_CTL_IS_SERVER, NULL) ||
|
||||
netplay_driver_ctl(RARCH_NETPLAY_CTL_IS_CONNECTED, NULL))
|
||||
command_event(CMD_EVENT_NETPLAY_DISCONNECT, NULL);
|
||||
}
|
||||
else
|
||||
command_event(CMD_EVENT_NETPLAY_ENABLE_HOST, NULL);
|
||||
|
||||
|
20
runloop.c
20
runloop.c
@ -5448,6 +5448,26 @@ bool runloop_event_init_core(
|
||||
float fastforward_ratio = 0.0f;
|
||||
rarch_system_info_t *sys_info = &runloop_st->system;
|
||||
|
||||
#if defined(HAVE_NETWORKING) && defined(HAVE_UPDATE_CORES)
|
||||
/* If netplay is enabled, update the core before initializing. */
|
||||
if (netplay_driver_ctl(RARCH_NETPLAY_CTL_IS_ENABLED, NULL))
|
||||
{
|
||||
const char *path_core = path_get(RARCH_PATH_CORE);
|
||||
|
||||
if (!string_is_empty(path_core) &&
|
||||
!string_is_equal(path_core, "builtin"))
|
||||
{
|
||||
task_push_update_single_core(path_core,
|
||||
settings->bools.core_updater_auto_backup,
|
||||
settings->uints.core_updater_auto_backup_history_size,
|
||||
settings->paths.directory_libretro,
|
||||
settings->paths.directory_core_assets);
|
||||
/* We must wait for the update to finish before starting the core. */
|
||||
task_update_installed_cores_wait();
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
if (!init_libretro_symbols(runloop_st,
|
||||
type, &runloop_st->current_core))
|
||||
return false;
|
||||
|
@ -3,6 +3,7 @@
|
||||
* Copyright (C) 2014-2017 - Jean-André Santoni
|
||||
* Copyright (C) 2016-2019 - Brad Parker
|
||||
* Copyright (C) 2019 - James Leaver
|
||||
* Copyright (C) 2022 - Roberto V. Rampim
|
||||
*
|
||||
* 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-
|
||||
@ -133,6 +134,26 @@ typedef struct update_installed_cores_handle
|
||||
bool auto_backup;
|
||||
} update_installed_cores_handle_t;
|
||||
|
||||
enum update_single_core_status
|
||||
{
|
||||
UPDATE_SINGLE_CORE_BEGIN = 0,
|
||||
UPDATE_SINGLE_CORE_WAIT_LIST,
|
||||
UPDATE_SINGLE_CORE_UPDATE_CORE,
|
||||
UPDATE_SINGLE_CORE_WAIT_DOWNLOAD,
|
||||
UPDATE_SINGLE_CORE_END
|
||||
};
|
||||
|
||||
typedef struct update_single_core_handle
|
||||
{
|
||||
core_updater_list_t *core_list;
|
||||
size_t auto_backup_history_size;
|
||||
enum update_single_core_status status;
|
||||
char path_core[PATH_MAX_LENGTH];
|
||||
char path_dir_libretro[PATH_MAX_LENGTH];
|
||||
char path_dir_core_assets[PATH_MAX_LENGTH];
|
||||
bool auto_backup;
|
||||
} update_single_core_handle_t;
|
||||
|
||||
#if defined(ANDROID)
|
||||
/* Play feature delivery core install */
|
||||
enum play_feature_delivery_install_task_status
|
||||
@ -1454,17 +1475,128 @@ task_finished:
|
||||
free_update_installed_cores_handle(update_installed_handle);
|
||||
}
|
||||
|
||||
static void task_update_single_core_handler(retro_task_t *task)
|
||||
{
|
||||
update_single_core_handle_t *handle =
|
||||
(update_single_core_handle_t*)task->state;
|
||||
|
||||
switch (handle->status)
|
||||
{
|
||||
case UPDATE_SINGLE_CORE_BEGIN:
|
||||
{
|
||||
if (task_push_get_core_updater_list(handle->core_list,
|
||||
true, false))
|
||||
handle->status = UPDATE_SINGLE_CORE_WAIT_LIST;
|
||||
else
|
||||
handle->status = UPDATE_SINGLE_CORE_END;
|
||||
}
|
||||
break;
|
||||
case UPDATE_SINGLE_CORE_WAIT_LIST:
|
||||
{
|
||||
task_finder_data_t find_data;
|
||||
|
||||
find_data.func = task_core_updater_get_list_finder;
|
||||
find_data.userdata = handle->core_list;
|
||||
if (!task_queue_find(&find_data))
|
||||
handle->status = UPDATE_SINGLE_CORE_UPDATE_CORE;
|
||||
}
|
||||
break;
|
||||
case UPDATE_SINGLE_CORE_UPDATE_CORE:
|
||||
{
|
||||
uint32_t crc;
|
||||
const core_updater_list_entry_t *entry = NULL;
|
||||
|
||||
if (!core_updater_list_get_core(handle->core_list,
|
||||
handle->path_core, &entry))
|
||||
{
|
||||
handle->status = UPDATE_SINGLE_CORE_END;
|
||||
break;
|
||||
}
|
||||
|
||||
if (core_info_get_core_lock(entry->local_core_path, false))
|
||||
{
|
||||
handle->status = UPDATE_SINGLE_CORE_END;
|
||||
break;
|
||||
}
|
||||
|
||||
crc = task_core_updater_get_core_crc(entry->local_core_path);
|
||||
if (!crc || crc == entry->crc)
|
||||
{
|
||||
handle->status = UPDATE_SINGLE_CORE_END;
|
||||
break;
|
||||
}
|
||||
|
||||
if (task_push_core_updater_download(handle->core_list,
|
||||
entry->remote_filename, crc, true,
|
||||
handle->auto_backup, handle->auto_backup_history_size,
|
||||
handle->path_dir_libretro, handle->path_dir_core_assets))
|
||||
handle->status = UPDATE_SINGLE_CORE_WAIT_DOWNLOAD;
|
||||
else
|
||||
handle->status = UPDATE_SINGLE_CORE_END;
|
||||
}
|
||||
break;
|
||||
case UPDATE_SINGLE_CORE_WAIT_DOWNLOAD:
|
||||
{
|
||||
task_finder_data_t find_data;
|
||||
const core_updater_list_entry_t *entry = NULL;
|
||||
|
||||
if (!core_updater_list_get_core(handle->core_list,
|
||||
handle->path_core, &entry))
|
||||
{
|
||||
handle->status = UPDATE_SINGLE_CORE_END;
|
||||
break;
|
||||
}
|
||||
|
||||
find_data.func = task_core_updater_download_finder;
|
||||
find_data.userdata = entry->remote_filename;
|
||||
if (!task_queue_find(&find_data))
|
||||
handle->status = UPDATE_SINGLE_CORE_END;
|
||||
}
|
||||
break;
|
||||
case UPDATE_SINGLE_CORE_END:
|
||||
default:
|
||||
task_set_progress(task, 100);
|
||||
task_set_finished(task, true);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
static void task_update_single_core_cleanup(retro_task_t *task)
|
||||
{
|
||||
update_single_core_handle_t *handle =
|
||||
(update_single_core_handle_t*)task->state;
|
||||
|
||||
core_updater_list_free(handle->core_list);
|
||||
free(handle);
|
||||
}
|
||||
|
||||
static bool task_update_installed_cores_finder(retro_task_t *task, void *user_data)
|
||||
{
|
||||
if (!task)
|
||||
return false;
|
||||
|
||||
if (task->handler == task_update_installed_cores_handler)
|
||||
if (task->handler == task_update_installed_cores_handler ||
|
||||
task->handler == task_update_single_core_handler)
|
||||
return true;
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
static bool task_update_installed_cores_waiter(void *data)
|
||||
{
|
||||
task_finder_data_t find_data;
|
||||
|
||||
find_data.func = task_update_installed_cores_finder;
|
||||
find_data.userdata = NULL;
|
||||
|
||||
return task_queue_find(&find_data);
|
||||
}
|
||||
|
||||
void task_update_installed_cores_wait(void)
|
||||
{
|
||||
task_queue_wait(task_update_installed_cores_waiter, NULL);
|
||||
}
|
||||
|
||||
void task_push_update_installed_cores(
|
||||
bool auto_backup, size_t auto_backup_history_size,
|
||||
const char *path_dir_libretro,
|
||||
@ -1545,6 +1677,65 @@ error:
|
||||
free_update_installed_cores_handle(update_installed_handle);
|
||||
}
|
||||
|
||||
void task_push_update_single_core(
|
||||
const char *path_core, bool auto_backup, size_t auto_backup_history_size,
|
||||
const char *path_dir_libretro, const char *path_dir_core_assets)
|
||||
{
|
||||
task_finder_data_t find_data;
|
||||
core_updater_list_t *core_list;
|
||||
update_single_core_handle_t *handle;
|
||||
retro_task_t *task;
|
||||
|
||||
if (string_is_empty(path_core) || string_is_empty(path_dir_libretro))
|
||||
return;
|
||||
|
||||
#ifdef ANDROID
|
||||
/* Regular core updater is disabled in Play Store builds. */
|
||||
if (play_feature_delivery_enabled())
|
||||
return;
|
||||
#endif
|
||||
|
||||
/* Only one instance of this task may run at a time. */
|
||||
find_data.func = task_update_installed_cores_finder;
|
||||
find_data.userdata = NULL;
|
||||
if (task_queue_find(&find_data))
|
||||
return;
|
||||
|
||||
core_list = core_updater_list_init();
|
||||
handle = (update_single_core_handle_t*)malloc(sizeof(*handle));
|
||||
task = task_init();
|
||||
if (!core_list || !handle || !task)
|
||||
{
|
||||
core_updater_list_free(core_list);
|
||||
free(handle);
|
||||
free(task);
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
/* Configure handle */
|
||||
handle->status = UPDATE_SINGLE_CORE_BEGIN;
|
||||
handle->core_list = core_list;
|
||||
handle->auto_backup = auto_backup;
|
||||
handle->auto_backup_history_size = auto_backup_history_size;
|
||||
strlcpy(handle->path_core, path_core, sizeof(handle->path_core));
|
||||
strlcpy(handle->path_dir_libretro, path_dir_libretro,
|
||||
sizeof(handle->path_dir_libretro));
|
||||
if (!string_is_empty(path_dir_core_assets))
|
||||
strlcpy(handle->path_dir_core_assets, path_dir_core_assets,
|
||||
sizeof(handle->path_dir_core_assets));
|
||||
else
|
||||
handle->path_dir_core_assets[0] = '\0';
|
||||
|
||||
/* Configure task */
|
||||
task->handler = task_update_single_core_handler;
|
||||
task->cleanup = task_update_single_core_cleanup;
|
||||
task->state = handle;
|
||||
|
||||
/* Push task */
|
||||
task_queue_push(task);
|
||||
}
|
||||
|
||||
#if defined(ANDROID)
|
||||
/**************************************/
|
||||
/* Play feature delivery core install */
|
||||
|
@ -468,9 +468,17 @@ static void task_netplay_crc_scan_callback(retro_task_t *task,
|
||||
data->core, content_path);
|
||||
|
||||
command_event(CMD_EVENT_NETPLAY_DEINIT, NULL);
|
||||
netplay_driver_ctl(RARCH_NETPLAY_CTL_ENABLE_CLIENT, NULL);
|
||||
command_event(CMD_EVENT_NETPLAY_INIT_DIRECT_DEFERRED,
|
||||
data->hostname);
|
||||
|
||||
if (string_is_empty(data->hostname))
|
||||
{
|
||||
netplay_driver_ctl(RARCH_NETPLAY_CTL_ENABLE_SERVER, NULL);
|
||||
}
|
||||
else
|
||||
{
|
||||
netplay_driver_ctl(RARCH_NETPLAY_CTL_ENABLE_CLIENT, NULL);
|
||||
command_event(CMD_EVENT_NETPLAY_INIT_DIRECT_DEFERRED,
|
||||
data->hostname);
|
||||
}
|
||||
|
||||
task_push_load_new_core(data->core,
|
||||
NULL, NULL, CORE_TYPE_PLAIN, NULL, NULL);
|
||||
@ -502,7 +510,11 @@ static void task_netplay_crc_scan_callback(retro_task_t *task,
|
||||
data->core, subsystem);
|
||||
|
||||
command_event(CMD_EVENT_NETPLAY_DEINIT, NULL);
|
||||
netplay_driver_ctl(RARCH_NETPLAY_CTL_ENABLE_CLIENT, NULL);
|
||||
|
||||
if (string_is_empty(data->hostname))
|
||||
netplay_driver_ctl(RARCH_NETPLAY_CTL_ENABLE_SERVER, NULL);
|
||||
else
|
||||
netplay_driver_ctl(RARCH_NETPLAY_CTL_ENABLE_CLIENT, NULL);
|
||||
|
||||
task_push_load_new_core(data->core,
|
||||
NULL, NULL, CORE_TYPE_PLAIN, NULL, NULL);
|
||||
@ -517,8 +529,9 @@ static void task_netplay_crc_scan_callback(retro_task_t *task,
|
||||
for (i = 0; i < subsystem_content->size; i++)
|
||||
content_add_subsystem(subsystem_content->elems[i].data);
|
||||
|
||||
command_event(CMD_EVENT_NETPLAY_INIT_DIRECT_DEFERRED,
|
||||
data->hostname);
|
||||
if (!string_is_empty(data->hostname))
|
||||
command_event(CMD_EVENT_NETPLAY_INIT_DIRECT_DEFERRED,
|
||||
data->hostname);
|
||||
|
||||
task_push_load_subsystem_with_core(NULL,
|
||||
&content_info, CORE_TYPE_PLAIN, NULL, NULL);
|
||||
@ -545,9 +558,17 @@ static void task_netplay_crc_scan_callback(retro_task_t *task,
|
||||
RARCH_LOG("[Lobby] Loading contentless core '%s'.\n", data->core);
|
||||
|
||||
command_event(CMD_EVENT_NETPLAY_DEINIT, NULL);
|
||||
netplay_driver_ctl(RARCH_NETPLAY_CTL_ENABLE_CLIENT, NULL);
|
||||
command_event(CMD_EVENT_NETPLAY_INIT_DIRECT_DEFERRED,
|
||||
data->hostname);
|
||||
|
||||
if (string_is_empty(data->hostname))
|
||||
{
|
||||
netplay_driver_ctl(RARCH_NETPLAY_CTL_ENABLE_SERVER, NULL);
|
||||
}
|
||||
else
|
||||
{
|
||||
netplay_driver_ctl(RARCH_NETPLAY_CTL_ENABLE_CLIENT, NULL);
|
||||
command_event(CMD_EVENT_NETPLAY_INIT_DIRECT_DEFERRED,
|
||||
data->hostname);
|
||||
}
|
||||
|
||||
task_push_load_new_core(data->core,
|
||||
NULL, NULL, CORE_TYPE_PLAIN, NULL, NULL);
|
||||
@ -562,9 +583,17 @@ static void task_netplay_crc_scan_callback(retro_task_t *task,
|
||||
command_event(CMD_EVENT_UNLOAD_CORE, NULL);
|
||||
|
||||
command_event(CMD_EVENT_NETPLAY_DEINIT, NULL);
|
||||
netplay_driver_ctl(RARCH_NETPLAY_CTL_ENABLE_CLIENT, NULL);
|
||||
command_event(CMD_EVENT_NETPLAY_INIT_DIRECT_DEFERRED,
|
||||
data->hostname);
|
||||
|
||||
if (string_is_empty(data->hostname))
|
||||
{
|
||||
netplay_driver_ctl(RARCH_NETPLAY_CTL_ENABLE_SERVER, NULL);
|
||||
}
|
||||
else
|
||||
{
|
||||
netplay_driver_ctl(RARCH_NETPLAY_CTL_ENABLE_CLIENT, NULL);
|
||||
command_event(CMD_EVENT_NETPLAY_INIT_DIRECT_DEFERRED,
|
||||
data->hostname);
|
||||
}
|
||||
|
||||
task_push_load_new_core(data->core,
|
||||
NULL, NULL, CORE_TYPE_PLAIN, NULL, NULL);
|
||||
@ -754,7 +783,10 @@ bool task_push_netplay_content_reload(const char *hostname)
|
||||
scan_state.state = STATE_RELOAD;
|
||||
|
||||
strlcpy(data->core, pcore, sizeof(data->core));
|
||||
strlcpy(data->hostname, hostname, sizeof(data->hostname));
|
||||
|
||||
/* Hostname being NULL indicates this is a host. */
|
||||
if (hostname)
|
||||
strlcpy(data->hostname, hostname, sizeof(data->hostname));
|
||||
|
||||
content_get_status(&contentless, &is_inited);
|
||||
if (contentless)
|
||||
|
@ -112,6 +112,10 @@ void task_push_update_installed_cores(
|
||||
bool auto_backup, size_t auto_backup_history_size,
|
||||
const char *path_dir_libretro,
|
||||
const char *path_dir_core_assets);
|
||||
void task_push_update_single_core(
|
||||
const char *path_core, bool auto_backup, size_t auto_backup_history_size,
|
||||
const char *path_dir_libretro, const char *path_dir_core_assets);
|
||||
void task_update_installed_cores_wait(void);
|
||||
#if defined(ANDROID)
|
||||
void *task_push_play_feature_delivery_core_install(
|
||||
core_updater_list_t* core_list,
|
||||
|
Loading…
x
Reference in New Issue
Block a user