From fcd57801bd1b6fcdd8dc0c5317cb4074e8f82e3d Mon Sep 17 00:00:00 2001 From: Gregor Richards Date: Sat, 24 Sep 2016 08:12:08 -0400 Subject: [PATCH] When we replay, resimulate input so that it doesn't judder between remote states --- network/netplay/netplay.c | 16 ++++++++++------ network/netplay/netplay_net.c | 7 ++++++- network/netplay/netplay_private.h | 2 ++ 3 files changed, 18 insertions(+), 7 deletions(-) diff --git a/network/netplay/netplay.c b/network/netplay/netplay.c index db9c03083e..3b0cd659c5 100644 --- a/network/netplay/netplay.c +++ b/network/netplay/netplay.c @@ -554,13 +554,17 @@ static int poll_input(netplay_t *netplay, bool block) return 0; } -/* TODO: Somewhat better prediction. :P */ -static void simulate_input(netplay_t *netplay) +/** + * netplay_simulate_input: + * @netplay : pointer to netplay object + * @sim_ptr : frame index for which to simulate input + * + * "Simulate" input by assuming it hasn't changed since the last read input. + */ +void netplay_simulate_input(netplay_t *netplay, uint32_t sim_ptr) { - size_t ptr = netplay->self_ptr; size_t prev = PREV_PTR(netplay->read_ptr); - - memcpy(netplay->buffer[ptr].simulated_input_state, + memcpy(netplay->buffer[sim_ptr].simulated_input_state, netplay->buffer[prev].real_input_state, sizeof(netplay->buffer[prev].real_input_state)); } @@ -603,7 +607,7 @@ static bool netplay_poll(netplay_t *netplay) /* Simulate the input if we don't have real input */ if (!netplay->buffer[netplay->self_ptr].have_remote) - simulate_input(netplay); + netplay_simulate_input(netplay, netplay->self_ptr); /* Consider stalling */ switch (netplay->stall) { diff --git a/network/netplay/netplay_net.c b/network/netplay/netplay_net.c index e31f52beb0..4138ca80c9 100644 --- a/network/netplay/netplay_net.c +++ b/network/netplay/netplay_net.c @@ -214,9 +214,14 @@ static void netplay_net_post_frame(netplay_t *netplay) serial_info.size = netplay->state_size; serial_info.data_const = NULL; + /* Remember the current state */ core_serialize(&serial_info); + if (netplay->replay_frame_count < netplay->read_frame_count) + netplay_handle_frame_hash(netplay, ptr); - netplay_handle_frame_hash(netplay, ptr); + /* Simulate this frame's input */ + if (netplay->replay_frame_count >= netplay->read_frame_count) + netplay_simulate_input(netplay, netplay->replay_ptr); #if defined(HAVE_THREADS) autosave_lock(); diff --git a/network/netplay/netplay_private.h b/network/netplay/netplay_private.h index 520cf94d55..e792d94788 100644 --- a/network/netplay/netplay_private.h +++ b/network/netplay/netplay_private.h @@ -177,6 +177,8 @@ struct netplay_callbacks* netplay_get_cbs_net(void); struct netplay_callbacks* netplay_get_cbs_spectate(void); +void netplay_simulate_input(netplay_t *netplay, uint32_t sim_ptr); + void netplay_log_connection(const struct sockaddr_storage *their_addr, unsigned slot, const char *nick);