diff --git a/network/netplay/netplay.c b/network/netplay/netplay.c index 142d08e280..078f0192b6 100644 --- a/network/netplay/netplay.c +++ b/network/netplay/netplay.c @@ -997,7 +997,7 @@ netplay_t *netplay_new(const char *server, uint16_t port, return NULL; netplay->fd = -1; - netplay->tcp_port = server ? 0 : port; + netplay->tcp_port = port; netplay->cbs = *cb; netplay->port = server ? 0 : 1; netplay->spectate.enabled = spectate; @@ -1277,6 +1277,42 @@ void netplay_load_savestate(netplay_t *netplay, retro_ctx_serialize_info_t *seri } } +/** + * netplay_reconnect + * @netplay : pointer to netplay object + * + * Reconnect netplay. Only does anything as a client, and only if netplay isn't + * currently connected. + * + * Returns: true (1) if successful, false (0) if unsuccessful, false (0) if not + * client or already connected. + **/ +bool netplay_reconnect(netplay_t *netplay) +{ + /* FIXME: This function has some things remembered in netplay, some things + * brought back from global */ + global_t *global = global_get_ptr(); + + if (!netplay || netplay->has_connection || netplay->is_server) + { + return false; + } + + if (!init_socket(netplay, global->netplay.server, netplay->tcp_port)) + { + RARCH_WARN("Failed to reconnect Netplay.\n"); + runloop_msg_queue_push("Failed to reconnect Netplay.", 0, 480, false); + } + + /* FIXME: Connection info is weirdly conflated into info_cb */ + if (!netplay_info_cb(netplay, netplay->stall_frames)) + { + return false; + } + + return true; +} + void deinit_netplay(void) { netplay_t *netplay = (netplay_t*)netplay_data; @@ -1386,6 +1422,8 @@ bool netplay_driver_ctl(enum rarch_netplay_ctl_state state, void *data) case RARCH_NETPLAY_CTL_LOAD_SAVESTATE: netplay_load_savestate((netplay_t*)netplay_data, (retro_ctx_serialize_info_t*)data, true); break; + case RARCH_NETPLAY_CTL_RECONNECT: + return netplay_reconnect((netplay_t*)netplay_data); default: case RARCH_NETPLAY_CTL_NONE: break; diff --git a/network/netplay/netplay.h b/network/netplay/netplay.h index a2bb44efba..19b0f05342 100644 --- a/network/netplay/netplay.h +++ b/network/netplay/netplay.h @@ -38,7 +38,8 @@ enum rarch_netplay_ctl_state RARCH_NETPLAY_CTL_IS_DATA_INITED, RARCH_NETPLAY_CTL_PAUSE, RARCH_NETPLAY_CTL_UNPAUSE, - RARCH_NETPLAY_CTL_LOAD_SAVESTATE + RARCH_NETPLAY_CTL_LOAD_SAVESTATE, + RARCH_NETPLAY_CTL_RECONNECT }; enum netplay_cmd @@ -194,6 +195,18 @@ void netplay_frontend_paused(netplay_t *netplay, bool paused); **/ void netplay_load_savestate(netplay_t *netplay, retro_ctx_serialize_info_t *serial_info, bool save); +/** + * netplay_reconnect + * @netplay : pointer to netplay object + * + * Reconnect netplay. Only does anything as a client, and only if netplay isn't + * currently connected. + * + * Returns: true (1) if successful, false (0) if unsuccessful, false (0) if not + * client or already connected. + **/ +bool netplay_reconnect(netplay_t *netplay); + /** * init_netplay: * diff --git a/network/netplay/netplay_common.c b/network/netplay/netplay_common.c index 287bf88912..c55174a398 100644 --- a/network/netplay/netplay_common.c +++ b/network/netplay/netplay_common.c @@ -133,6 +133,7 @@ bool netplay_send_info(netplay_t *netplay) uint32_t *content_crc_ptr = NULL; void *sram = NULL; uint32_t header[3] = {0}; + size_t i; mem_info.id = RETRO_MEMORY_SAVE_RAM; @@ -197,6 +198,22 @@ bool netplay_send_info(netplay_t *netplay) return false; } + /* Reset our frame count so it's consistent with the server */ + netplay->self_frame_count = netplay->read_frame_count = netplay->other_frame_count = 0; + for (i = 0; i < netplay->buffer_size; i++) + { + netplay->buffer[i].used = false; + if (i == netplay->self_ptr) + { + netplay_delta_frame_ready(netplay, &netplay->buffer[i], 0); + netplay->read_ptr = netplay->other_ptr = i; + } + else + { + netplay->buffer[i].used = false; + } + } + snprintf(msg, sizeof(msg), "%s: \"%s\"", msg_hash_to_str(MSG_CONNECTED_TO), netplay->other_nick); @@ -215,6 +232,9 @@ bool netplay_get_info(netplay_t *netplay) const void *sram = NULL; size_t i; + /* FIXME: There's a huge amount of duplication between send_info and + * get_info */ + mem_info.id = RETRO_MEMORY_SAVE_RAM; core_get_memory(&mem_info); @@ -286,6 +306,7 @@ bool netplay_get_info(netplay_t *netplay) if (i == netplay->self_ptr) { netplay_delta_frame_ready(netplay, &netplay->buffer[i], 0); + netplay->read_ptr = netplay->other_ptr = i; } else {