diff --git a/core.h b/core.h index 2ae06e6d4f..0b80d39737 100644 --- a/core.h +++ b/core.h @@ -155,6 +155,8 @@ bool core_set_default_callbacks(void *data); bool core_set_rewind_callbacks(void); +bool core_set_netplay_callbacks(void); + bool core_set_poll_type(unsigned *type); /* Runs the core for one frame. */ diff --git a/core_impl.c b/core_impl.c index 0dd8f537b0..9279ec6817 100644 --- a/core_impl.c +++ b/core_impl.c @@ -103,13 +103,7 @@ static bool core_init_libretro_cbs(void *data) if (!netplay_driver_ctl(RARCH_NETPLAY_CTL_IS_DATA_INITED, NULL)) return true; - /* Force normal poll type for netplay. */ - core_poll_type = POLL_TYPE_NORMAL; - - core.retro_set_video_refresh(video_frame_net); - core.retro_set_audio_sample(audio_sample_net); - core.retro_set_audio_sample_batch(audio_sample_batch_net); - core.retro_set_input_state(input_state_net); + core_set_netplay_callbacks(); #endif return true; @@ -182,6 +176,26 @@ bool core_set_rewind_callbacks(void) return true; } +/** + * core_set_netplay_callbacks: + * + * Set the I/O callbacks to use netplay's interceding callback system. Should + * only be called once. + **/ +bool core_set_netplay_callbacks(void) +{ + /* Force normal poll type for netplay. */ + core_poll_type = POLL_TYPE_NORMAL; + + /* And use netplay's interceding callbacks */ + core.retro_set_video_refresh(video_frame_net); + core.retro_set_audio_sample(audio_sample_net); + core.retro_set_audio_sample_batch(audio_sample_batch_net); + core.retro_set_input_state(input_state_net); + + return true; +} + bool core_set_cheat(retro_ctx_cheat_info_t *info) { core.retro_cheat_set(info->index, info->enabled, info->code); diff --git a/intl/msg_hash_us.c b/intl/msg_hash_us.c index 40d6e47677..9ebcf5d185 100644 --- a/intl/msg_hash_us.c +++ b/intl/msg_hash_us.c @@ -2858,6 +2858,8 @@ static const char *menu_hash_to_str_us_label_enum(enum msg_hash_enums msg) return "network_information"; case MENU_ENUM_LABEL_ONLINE_UPDATER: return "online_updater"; + case MENU_ENUM_LABEL_NETPLAY: + return "netplay"; case MENU_ENUM_LABEL_CORE_INFORMATION: return "core_information"; case MENU_ENUM_LABEL_CORE_LIST: @@ -4129,6 +4131,8 @@ const char *msg_hash_to_str_us(enum msg_hash_enums msg) return "Achievement List"; case MENU_ENUM_LABEL_VALUE_ONLINE_UPDATER: return "Online Updater"; + case MENU_ENUM_LABEL_VALUE_NETPLAY: + return "Netplay"; case MENU_ENUM_LABEL_VALUE_CORE_INFORMATION: return "Core Information"; case MENU_ENUM_LABEL_VALUE_DIRECTORY_NOT_FOUND: diff --git a/menu/cbs/menu_cbs_deferred_push.c b/menu/cbs/menu_cbs_deferred_push.c index b36552c20f..b99f3a7d95 100644 --- a/menu/cbs/menu_cbs_deferred_push.c +++ b/menu/cbs/menu_cbs_deferred_push.c @@ -287,6 +287,11 @@ static int deferred_push_options(menu_displaylist_info_t *info) return deferred_push_dlist(info, DISPLAYLIST_OPTIONS); } +static int deferred_push_netplay(menu_displaylist_info_t *info) +{ + return deferred_push_dlist(info, DISPLAYLIST_NETPLAY); +} + static int deferred_push_content_settings(menu_displaylist_info_t *info) { return deferred_push_dlist(info, DISPLAYLIST_CONTENT_SETTINGS); @@ -905,6 +910,9 @@ static int menu_cbs_init_bind_deferred_push_compare_label( case MENU_ENUM_LABEL_ONLINE_UPDATER: BIND_ACTION_DEFERRED_PUSH(cbs, deferred_push_options); break; + case MENU_ENUM_LABEL_NETPLAY: + BIND_ACTION_DEFERRED_PUSH(cbs, deferred_push_netplay); + break; case MENU_ENUM_LABEL_CONTENT_SETTINGS: BIND_ACTION_DEFERRED_PUSH(cbs, deferred_push_content_settings); break; @@ -1156,6 +1164,9 @@ static int menu_cbs_init_bind_deferred_push_compare_label( case MENU_LABEL_ONLINE_UPDATER: BIND_ACTION_DEFERRED_PUSH(cbs, deferred_push_options); break; + case MENU_LABEL_NETPLAY: + BIND_ACTION_DEFERRED_PUSH(cbs, deferred_push_netplay); + break; case MENU_LABEL_CONTENT_SETTINGS: BIND_ACTION_DEFERRED_PUSH(cbs, deferred_push_content_settings); break; diff --git a/menu/cbs/menu_cbs_ok.c b/menu/cbs/menu_cbs_ok.c index 1213973998..5e3ff279df 100644 --- a/menu/cbs/menu_cbs_ok.c +++ b/menu/cbs/menu_cbs_ok.c @@ -50,6 +50,10 @@ #include "../../lakka.h" #include "../../wifi/wifi_driver.h" +#ifdef HAVE_NETPLAY +#include "../../network/netplay/netplay.h" +#endif + typedef struct { enum msg_hash_enums enum_idx; @@ -3266,6 +3270,56 @@ static int action_ok_video_resolution(const char *path, return 0; } +static int action_ok_netplay_enable_host(const char *path, + const char *label, unsigned type, size_t idx, size_t entry_idx) +{ + bool netplay_was_on = false; + global_t *global = global_get_ptr(); + + global->netplay.enable = true; + + if (netplay_driver_ctl(RARCH_NETPLAY_CTL_IS_DATA_INITED, NULL)) + { + netplay_was_on = true; + + /* Netplay is already on. Are we in the wrong mode? */ + if (global->netplay.is_client) + { + /* Kill it! */ + command_event(CMD_EVENT_NETPLAY_DEINIT, NULL); + } + } + + global->netplay.is_client = false; + global->netplay.server[0] = '\0'; + + /* If we haven't yet started, this will load on its own */ + if (!content_is_inited()) + return 0; + + /* Enable Netplay itself */ + if (!command_event(CMD_EVENT_NETPLAY_INIT, NULL)) + return -1; + + /* Then make sure we use Netplay's callbacks */ + if (!netplay_was_on && !core_set_netplay_callbacks()) + return -1; + + return 0; +} + +static int action_ok_netplay_enable_client(const char *path, + const char *label, unsigned type, size_t idx, size_t entry_idx) +{ + return 0; +} + +static int action_ok_netplay_disconnect(const char *path, + const char *label, unsigned type, size_t idx, size_t entry_idx) +{ + return 0; +} + static int is_rdb_entry(enum msg_hash_enums enum_idx) { switch (enum_idx) @@ -3501,6 +3555,7 @@ static int menu_cbs_init_bind_ok_compare_label(menu_file_list_cbs_t *cbs, case MENU_ENUM_LABEL_CORE_COUNTERS: case MENU_ENUM_LABEL_MANAGEMENT: case MENU_ENUM_LABEL_ONLINE_UPDATER: + case MENU_ENUM_LABEL_NETPLAY: case MENU_ENUM_LABEL_LOAD_CONTENT_LIST: case MENU_ENUM_LABEL_ADD_CONTENT_LIST: case MENU_ENUM_LABEL_HELP_LIST: @@ -3641,6 +3696,15 @@ static int menu_cbs_init_bind_ok_compare_label(menu_file_list_cbs_t *cbs, case MENU_ENUM_LABEL_UPDATE_AUTOCONFIG_PROFILES: BIND_ACTION_OK(cbs, action_ok_update_autoconfig_profiles); break; + case MENU_ENUM_LABEL_NETPLAY_ENABLE_HOST: + BIND_ACTION_OK(cbs, action_ok_netplay_enable_host); + break; + case MENU_ENUM_LABEL_NETPLAY_ENABLE_CLIENT: + BIND_ACTION_OK(cbs, action_ok_netplay_enable_client); + break; + case MENU_ENUM_LABEL_NETPLAY_DISCONNECT: + BIND_ACTION_OK(cbs, action_ok_netplay_disconnect); + break; default: return -1; } diff --git a/menu/cbs/menu_cbs_title.c b/menu/cbs/menu_cbs_title.c index f73f6e0d58..2463ff80f5 100644 --- a/menu/cbs/menu_cbs_title.c +++ b/menu/cbs/menu_cbs_title.c @@ -86,6 +86,13 @@ static int action_get_online_updater_list(const char *path, const char *label, return 0; } +static int action_get_netplay_list(const char *path, const char *label, + unsigned menu_type, char *s, size_t len) +{ + sanitize_to_string(s, msg_hash_to_str(MENU_ENUM_LABEL_VALUE_NETPLAY), len); + return 0; +} + static int action_get_online_thumbnails_updater_list(const char *path, const char *label, unsigned menu_type, char *s, size_t len) { @@ -1171,6 +1178,9 @@ static int menu_cbs_init_bind_title_compare_label(menu_file_list_cbs_t *cbs, case MENU_ENUM_LABEL_ONLINE_UPDATER: BIND_ACTION_GET_TITLE(cbs, action_get_online_updater_list); break; + case MENU_ENUM_LABEL_NETPLAY: + BIND_ACTION_GET_TITLE(cbs, action_get_netplay_list); + break; case MENU_ENUM_LABEL_DEFERRED_THUMBNAILS_UPDATER_LIST: BIND_ACTION_GET_TITLE(cbs, action_get_online_thumbnails_updater_list); break; @@ -1473,6 +1483,9 @@ static int menu_cbs_init_bind_title_compare_label(menu_file_list_cbs_t *cbs, case MENU_LABEL_ONLINE_UPDATER: BIND_ACTION_GET_TITLE(cbs, action_get_online_updater_list); break; + case MENU_LABEL_NETPLAY: + BIND_ACTION_GET_TITLE(cbs, action_get_netplay_list); + break; case MENU_LABEL_DEFERRED_THUMBNAILS_UPDATER_LIST: BIND_ACTION_GET_TITLE(cbs, action_get_online_thumbnails_updater_list); break; diff --git a/menu/drivers/materialui.c b/menu/drivers/materialui.c index d1cae46ae0..a92aa26a72 100644 --- a/menu/drivers/materialui.c +++ b/menu/drivers/materialui.c @@ -1651,6 +1651,10 @@ static int mui_list_push(void *data, void *userdata, #endif entry.enum_idx = MENU_ENUM_LABEL_ONLINE_UPDATER; menu_displaylist_ctl(DISPLAYLIST_SETTING_ENUM, &entry); +#endif +#if defined(HAVE_NETPLAY) + entry.enum_idx = MENU_ENUM_LABEL_NETPLAY; + menu_displaylist_ctl(DISPLAYLIST_SETTING_ENUM, &entry); #endif entry.enum_idx = MENU_ENUM_LABEL_INFORMATION_LIST; menu_displaylist_ctl(DISPLAYLIST_SETTING_ENUM, &entry); diff --git a/menu/drivers/xmb.c b/menu/drivers/xmb.c index aba1b2e8e3..2d486b5c58 100644 --- a/menu/drivers/xmb.c +++ b/menu/drivers/xmb.c @@ -3358,6 +3358,10 @@ static int xmb_list_push(void *data, void *userdata, #if defined(HAVE_NETWORKING) entry.enum_idx = MENU_ENUM_LABEL_ONLINE_UPDATER; menu_displaylist_ctl(DISPLAYLIST_SETTING_ENUM, &entry); +#endif +#if defined(HAVE_NETPLAY) + entry.enum_idx = MENU_ENUM_LABEL_NETPLAY; + menu_displaylist_ctl(DISPLAYLIST_SETTING_ENUM, &entry); #endif entry.enum_idx = MENU_ENUM_LABEL_INFORMATION_LIST; menu_displaylist_ctl(DISPLAYLIST_SETTING_ENUM, &entry); diff --git a/menu/menu_displaylist.c b/menu/menu_displaylist.c index a7b682188a..8605a2f9c1 100644 --- a/menu/menu_displaylist.c +++ b/menu/menu_displaylist.c @@ -1500,6 +1500,39 @@ static int menu_displaylist_parse_shader_options(menu_displaylist_info_t *info) return 0; } +static int menu_displaylist_parse_netplay( + menu_displaylist_info_t *info) +{ +#ifdef HAVE_NETPLAY + menu_entries_append_enum(info->list, + "Start hosting" /* FIXME */, + "enable_netplay_host" /* FIXME */, + MENU_ENUM_LABEL_NETPLAY_ENABLE_HOST, + MENU_SETTING_ACTION, 0, 0); + + menu_entries_append_enum(info->list, + "Connect to Netplay host" /* FIXME */, + "enable_netplay_client" /* FIXME */, + MENU_ENUM_LABEL_NETPLAY_ENABLE_CLIENT, + MENU_SETTING_ACTION, 0, 0); + + menu_entries_append_enum(info->list, + "Disconnect" /* FIXME */, + "disconnect_netplay" /* FIXME */, + MENU_ENUM_LABEL_NETPLAY_DISCONNECT, + MENU_SETTING_ACTION, 0, 0); + +#else + menu_entries_append_enum(info->list, + msg_hash_to_str(MENU_ENUM_LABEL_VALUE_NO_ITEMS), + msg_hash_to_str(MENU_ENUM_LABEL_NO_ITEMS), + MENU_ENUM_LABEL_NO_ITEMS, + MENU_SETTING_NO_ITEM, 0, 0); +#endif + + return 0; +} + #ifdef HAVE_LIBRETRODB static int create_string_list_rdb_entry_string( enum msg_hash_enums enum_idx, @@ -3971,6 +4004,7 @@ bool menu_displaylist_ctl(enum menu_displaylist_ctl_state type, void *data) case DISPLAYLIST_DATABASE_ENTRY: case DISPLAYLIST_DATABASE_QUERY: case DISPLAYLIST_OPTIONS_SHADERS: + case DISPLAYLIST_NETPLAY: case DISPLAYLIST_CORE_CONTENT: case DISPLAYLIST_CORE_CONTENT_DIRS: case DISPLAYLIST_PLAYLIST_COLLECTION: @@ -4245,6 +4279,11 @@ bool menu_displaylist_ctl(enum menu_displaylist_ctl_state type, void *data) menu_displaylist_parse_settings_enum(menu, info, MENU_ENUM_LABEL_ONLINE_UPDATER, PARSE_ACTION, false); +#endif +#if defined(HAVE_NETPLAY) + menu_displaylist_parse_settings_enum(menu, info, + MENU_ENUM_LABEL_NETPLAY, + PARSE_ACTION, false); #endif menu_displaylist_parse_settings_enum(menu, info, MENU_ENUM_LABEL_SETTINGS, PARSE_ACTION, false); @@ -5344,6 +5383,11 @@ bool menu_displaylist_ctl(enum menu_displaylist_ctl_state type, void *data) case DISPLAYLIST_OPTIONS_SHADERS: ret = menu_displaylist_parse_shader_options(info); + info->need_push = true; + break; + case DISPLAYLIST_NETPLAY: + ret = menu_displaylist_parse_netplay(info); + info->need_push = true; break; case DISPLAYLIST_CORE_CONTENT: diff --git a/menu/menu_displaylist.h b/menu/menu_displaylist.h index 2821797927..5ce6666ab2 100644 --- a/menu/menu_displaylist.h +++ b/menu/menu_displaylist.h @@ -141,6 +141,7 @@ enum menu_displaylist_ctl_state DISPLAYLIST_OPTIONS_MANAGEMENT, DISPLAYLIST_OPTIONS_DISK, DISPLAYLIST_OPTIONS_SHADERS, + DISPLAYLIST_NETPLAY, DISPLAYLIST_ADD_CONTENT_LIST, DISPLAYLIST_SCAN_DIRECTORY_LIST, DISPLAYLIST_ARCHIVE_ACTION, diff --git a/menu/menu_setting.c b/menu/menu_setting.c index e0bfa9bba3..81dac077d5 100644 --- a/menu/menu_setting.c +++ b/menu/menu_setting.c @@ -2198,6 +2198,17 @@ static bool setting_append_list( menu_settings_list_current_add_enum_idx(list, list_info, MENU_ENUM_LABEL_ONLINE_UPDATER); #endif +#if defined(HAVE_NETPLAY) + CONFIG_ACTION( + list, list_info, + msg_hash_to_str(MENU_ENUM_LABEL_NETPLAY), + msg_hash_to_str(MENU_ENUM_LABEL_VALUE_NETPLAY), + &group_info, + &subgroup_info, + parent_group); + menu_settings_list_current_add_enum_idx(list, list_info, MENU_ENUM_LABEL_NETPLAY); +#endif + CONFIG_ACTION( list, list_info, msg_hash_to_str(MENU_ENUM_LABEL_SETTINGS), diff --git a/msg_hash.h b/msg_hash.h index c0535a8fac..0b8a49722f 100644 --- a/msg_hash.h +++ b/msg_hash.h @@ -959,6 +959,12 @@ enum msg_hash_enums + /* Netplay */ + MENU_ENUM_LABEL_NETPLAY_ENABLE_HOST, + MENU_ENUM_LABEL_NETPLAY_ENABLE_CLIENT, + MENU_ENUM_LABEL_NETPLAY_DISCONNECT, + + MENU_ENUM_LABEL_COLLAPSE_SUBGROUPS_ENABLE, MENU_ENUM_LABEL_VALUE_COLLAPSE_SUBGROUPS_ENABLE, @@ -1428,6 +1434,8 @@ enum msg_hash_enums MENU_ENUM_LABEL_VALUE_MANAGEMENT, MENU_ENUM_LABEL_ONLINE_UPDATER, MENU_ENUM_LABEL_VALUE_ONLINE_UPDATER, + MENU_ENUM_LABEL_NETPLAY, + MENU_ENUM_LABEL_VALUE_NETPLAY, MENU_ENUM_LABEL_SETTINGS, MENU_ENUM_LABEL_FRONTEND_COUNTERS, MENU_ENUM_LABEL_VALUE_FRONTEND_COUNTERS, @@ -2075,6 +2083,7 @@ enum msg_hash_enums #define MENU_LABEL_LOAD_CONTENT_HISTORY 0xfe1d79e5U #define MENU_LABEL_ADD_CONTENT_LIST 0x046f4668U #define MENU_LABEL_ONLINE_UPDATER 0xcac0025eU +#define MENU_LABEL_NETPLAY 0x0b511d22U #define MENU_LABEL_SETTINGS 0x1304dc16U #define MENU_LABEL_HELP 0x7c97d2eeU #define MENU_VALUE_HORIZONTAL_MENU 0x35761704U