From 4f16a19f5e7c380c896718fbdcfb92b3c2fdb004 Mon Sep 17 00:00:00 2001 From: Gregor Richards Date: Mon, 12 Sep 2016 09:13:26 -0400 Subject: [PATCH] Rather than stalling by blocking and becoming unresponsive, stall by replaying the same frame. TODO: Maybe mute the audio? --- network/netplay/netplay.c | 39 ++++++++++++++++++++----------- network/netplay/netplay_net.c | 14 +++++++++++ network/netplay/netplay_private.h | 14 +++++++++++ 3 files changed, 54 insertions(+), 13 deletions(-) diff --git a/network/netplay/netplay.c b/network/netplay/netplay.c index 3425c8c712..bbf680b467 100644 --- a/network/netplay/netplay.c +++ b/network/netplay/netplay.c @@ -149,6 +149,13 @@ static bool get_self_input_state(netplay_t *netplay) if (!netplay_delta_frame_ready(netplay, ptr, netplay->self_frame_count)) return false; + if (ptr->have_local) + { + /* We've already read this frame! */ + netplay->self_ptr = NEXT_PTR(netplay->self_ptr); + return true; + } + if (!input_driver_is_libretro_input_blocked() && netplay->self_frame_count > 0) { unsigned i; @@ -206,6 +213,7 @@ static bool get_self_input_state(netplay_t *netplay) } memcpy(ptr->self_state, state, sizeof(state)); + ptr->have_local = true; netplay->self_ptr = NEXT_PTR(netplay->self_ptr); return true; } @@ -296,14 +304,8 @@ static bool netplay_get_cmd(netplay_t *netplay) if (buffer[0] != netplay->read_frame_count) { - /* FIXME: JUST drop it? */ - return netplay_cmd_nak(netplay); - } - - if (!netplay_delta_frame_ready(netplay, &netplay->buffer[netplay->read_ptr], netplay->read_frame_count)) - { - /* FIXME: If we're here, we're desyncing. */ - netplay->must_fast_forward = true; + /* FIXME: Except on the first (null) frame, this should be + * impossible, so maybe just disconnect? */ return netplay_cmd_nak(netplay); } @@ -313,7 +315,7 @@ static bool netplay_get_cmd(netplay_t *netplay) netplay->read_ptr = NEXT_PTR(netplay->read_ptr); netplay->read_frame_count++; netplay->timeout_cnt = 0; - return netplay_cmd_ack(netplay); + return true; } case NETPLAY_CMD_FLIP_PLAYERS: @@ -431,7 +433,7 @@ static int poll_input(netplay_t *netplay, bool block) RARCH_LOG("Network is stalling, resending packet... Count %u of %d ...\n", netplay->timeout_cnt, MAX_RETRIES); - } while (had_input || (block && netplay->read_frame_count < netplay->self_frame_count)); + } while (had_input); /*if (block) return -1;*/ @@ -537,9 +539,8 @@ static bool netplay_poll(netplay_t *netplay) return true; } - /* We might have reached the end of the buffer, where we - * simply have to block. */ - res = poll_input(netplay, netplay->read_frame_count < netplay->self_frame_count - 10); /* FIXME: configure stalling intervals */ + /* Read Netplay input */ + res = poll_input(netplay, 0); /* FIXME: configure stalling intervals */ if (res == -1) { netplay->has_connection = false; @@ -582,6 +583,18 @@ static bool netplay_poll(netplay_t *netplay) else netplay->buffer[PREV_PTR(netplay->self_ptr)].used_real = true; + /* Consider stalling */ + switch (netplay->stall) { + case RARCH_NETPLAY_STALL_RUNNING_FAST: + if (netplay->read_frame_count >= netplay->self_frame_count) + netplay->stall = RARCH_NETPLAY_STALL_NONE; + break; + + default: /* not stalling */ + if (netplay->read_frame_count < netplay->self_frame_count - 10) + netplay->stall = RARCH_NETPLAY_STALL_RUNNING_FAST; + } + return true; } diff --git a/network/netplay/netplay_net.c b/network/netplay/netplay_net.c index 35bfae9866..b234aa98a3 100644 --- a/network/netplay/netplay_net.c +++ b/network/netplay/netplay_net.c @@ -166,6 +166,20 @@ static void netplay_net_post_frame(netplay_t *netplay) } #endif + /* If we're supposed to stall, rewind */ + if (netplay->stall) + { + retro_ctx_serialize_info_t serial_info; + + netplay->self_ptr = PREV_PTR(netplay->self_ptr); + netplay->self_frame_count--; + + serial_info.data = NULL; + serial_info.data_const = netplay->buffer[netplay->self_ptr].state; + serial_info.size = netplay->state_size; + + core_unserialize(&serial_info); + } } static bool netplay_net_init_buffers(netplay_t *netplay) { diff --git a/network/netplay/netplay_private.h b/network/netplay/netplay_private.h index 2479376c0e..381c934aaf 100644 --- a/network/netplay/netplay_private.h +++ b/network/netplay/netplay_private.h @@ -49,8 +49,13 @@ struct delta_frame uint32_t simulated_input_state[WORDS_PER_FRAME - 1]; uint32_t self_state[WORDS_PER_FRAME - 1]; + /* Have we read local input? */ bool have_local; + + /* Badly named: This is !have_real(_remote) */ bool is_simulated; + + /* Is the current state as of self_frame_count using the real data? */ bool used_real; }; @@ -60,6 +65,12 @@ struct netplay_callbacks { bool (*info_cb) (netplay_t *netplay, unsigned frames); }; +enum rarch_netplay_stall_reasons +{ + RARCH_NETPLAY_STALL_NONE = 0, + RARCH_NETPLAY_STALL_RUNNING_FAST +}; + struct netplay { char nick[32]; @@ -131,6 +142,9 @@ struct netplay bool pause; uint32_t pause_frame; + /* And stalling */ + int stall; + struct netplay_callbacks* net_cbs; };