From 17e08c7a28f3dcf6468849de7b805cb72fcf4878 Mon Sep 17 00:00:00 2001 From: Gregor Richards Date: Sat, 17 Dec 2016 23:08:59 -0500 Subject: [PATCH] When we disconnect netplay, fully deinit it In particular, we need to disentangle the interceding netplay callbacks. In previous versions, if you disconnected netplay but were using a core that made netplay stall for connections (i.e., one that has no savestates), netplay would continue to stall because it still interceded, even though it was supposed to be off. This fixes that. --- core.h | 4 ++++ core_impl.c | 22 +++++++++++++++++++++- menu/cbs/menu_cbs_ok.c | 31 ------------------------------- network/netplay/netplay.c | 6 +++++- 4 files changed, 30 insertions(+), 33 deletions(-) diff --git a/core.h b/core.h index e1a7705fd5..f044fc7b64 100644 --- a/core.h +++ b/core.h @@ -166,8 +166,12 @@ bool core_set_default_callbacks(void *data); bool core_set_rewind_callbacks(void); +#ifdef HAVE_NETWORKING bool core_set_netplay_callbacks(void); +bool core_unset_netplay_callbacks(void); +#endif + bool core_set_poll_type(unsigned *type); /* Runs the core for one frame. */ diff --git a/core_impl.c b/core_impl.c index aca7c167bc..68a5c9aef5 100644 --- a/core_impl.c +++ b/core_impl.c @@ -184,7 +184,7 @@ bool core_set_rewind_callbacks(void) * core_set_netplay_callbacks: * * Set the I/O callbacks to use netplay's interceding callback system. Should - * only be called once. + * only be called while initializing netplay. **/ bool core_set_netplay_callbacks(void) { @@ -199,6 +199,26 @@ bool core_set_netplay_callbacks(void) return true; } + +/** + * core_unset_netplay_callbacks + * + * Unset the I/O callbacks from having used netplay's interceding callback + * system. Should only be called while uninitializing netplay. + */ +bool core_unset_netplay_callbacks(void) +{ + struct retro_callbacks cbs; + if (!core_set_default_callbacks(&cbs)) + return false; + + core.retro_set_video_refresh(cbs.frame_cb); + core.retro_set_audio_sample(cbs.sample_cb); + core.retro_set_audio_sample_batch(cbs.sample_batch_cb); + core.retro_set_input_state(cbs.state_cb); + + return true; +} #endif bool core_set_cheat(retro_ctx_cheat_info_t *info) diff --git a/menu/cbs/menu_cbs_ok.c b/menu/cbs/menu_cbs_ok.c index 9adb36cfae..4b2e50b29a 100644 --- a/menu/cbs/menu_cbs_ok.c +++ b/menu/cbs/menu_cbs_ok.c @@ -3084,7 +3084,6 @@ static int action_ok_netplay_lan_scan(const char *path, #ifdef HAVE_NETWORKING struct netplay_host_list *hosts; struct netplay_host *host; - bool netplay_was_on = false; /* Figure out what host we're connecting to */ if (!netplay_discovery_driver_ctl(RARCH_NETPLAY_DISCOVERY_CTL_LAN_GET_RESPONSES, &hosts)) @@ -3095,20 +3094,13 @@ static int action_ok_netplay_lan_scan(const char *path, /* Enable Netplay client mode */ if (netplay_driver_ctl(RARCH_NETPLAY_CTL_IS_DATA_INITED, NULL)) - { - netplay_was_on = true; command_event(CMD_EVENT_NETPLAY_DEINIT, NULL); - } netplay_driver_ctl(RARCH_NETPLAY_CTL_ENABLE_CLIENT, NULL); /* Enable Netplay */ if (!command_event(CMD_EVENT_NETPLAY_INIT, (void *) host)) return -1; - /* And make sure we use its callbacks */ - if (!netplay_was_on && !core_set_netplay_callbacks()) - return -1; - return generic_action_ok_command(CMD_EVENT_RESUME); #else @@ -3531,16 +3523,8 @@ static int action_ok_netplay_enable_host(const char *path, const char *label, unsigned type, size_t idx, size_t entry_idx) { #ifdef HAVE_NETWORKING - bool netplay_was_on = false; - if (netplay_driver_ctl(RARCH_NETPLAY_CTL_IS_DATA_INITED, NULL)) - { - netplay_was_on = true; - - /* Netplay is already on. Kill it. */ 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 */ @@ -3556,10 +3540,6 @@ static int action_ok_netplay_enable_host(const char *path, 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 generic_action_ok_command(CMD_EVENT_RESUME); #else @@ -3572,17 +3552,10 @@ static int action_ok_netplay_enable_client(const char *path, const char *label, unsigned type, size_t idx, size_t entry_idx) { #ifdef HAVE_NETWORKING - bool netplay_was_on = false; settings_t *settings = config_get_ptr(); if (netplay_driver_ctl(RARCH_NETPLAY_CTL_IS_DATA_INITED, NULL)) - { - netplay_was_on = true; - - /* Kill it! */ command_event(CMD_EVENT_NETPLAY_DEINIT, NULL); - } - netplay_driver_ctl(RARCH_NETPLAY_CTL_ENABLE_CLIENT, NULL); /* We can't do anything without a host specified */ @@ -3607,10 +3580,6 @@ static int action_ok_netplay_enable_client(const char *path, 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 generic_action_ok_command(CMD_EVENT_RESUME); #else diff --git a/network/netplay/netplay.c b/network/netplay/netplay.c index f820dafea0..d82108f640 100644 --- a/network/netplay/netplay.c +++ b/network/netplay/netplay.c @@ -1654,6 +1654,7 @@ void deinit_netplay(void) if (netplay_data) netplay_free(netplay_data); netplay_data = NULL; + core_unset_netplay_callbacks(); } /** @@ -1684,6 +1685,8 @@ bool init_netplay(bool is_spectate, void *direct_host, const char *server, unsig } core_set_default_callbacks(&cbs); + if (!core_set_netplay_callbacks()) + return false; /* Map the core's quirks to our quirks */ serialization_quirks = core_serialization_quirks(); @@ -1780,7 +1783,8 @@ bool netplay_driver_ctl(enum rarch_netplay_ctl_state state, void *data) case RARCH_NETPLAY_CTL_IS_DATA_INITED: goto done; case RARCH_NETPLAY_CTL_DISABLE: - ret = false; + netplay_enabled = false; + deinit_netplay(); goto done; case RARCH_NETPLAY_CTL_IS_ENABLED: goto done;