Spectator and slave mode are rewind-free

This commit makes spectator mode and slave mode in netplay always stay
ahead of the input, thereby avoiding rewinds, which is sort of the
point. This also changes catch-up detection to be a bit less eager, so
that they hopefully don't flap between stalling for server input and
catching up with that input.
This commit is contained in:
Gregor Richards 2017-02-23 19:05:43 -05:00
parent e495671563
commit 3ff9a43b7d
3 changed files with 47 additions and 9 deletions

View File

@ -247,7 +247,7 @@ bool netplay_send_cur_input(netplay_t *netplay,
{
if (!send_input_frame(netplay, connection, NULL,
netplay->self_frame_count,
(netplay->is_server ? NETPLAY_CMD_INPUT_BIT_SERVER : 0) | netplay->self_player,
(netplay->is_server ? NETPLAY_CMD_INPUT_BIT_SERVER : 0) | netplay->self_player,
dframe->self_state))
return false;
}

View File

@ -42,6 +42,7 @@
#define MAX_SERVER_STALL_TIME_USEC (5*1000*1000)
#define MAX_CLIENT_STALL_TIME_USEC (10*1000*1000)
#define CATCH_UP_CHECK_TIME_USEC (500*1000)
#define MAX_RETRIES 16
#define RETRY_MS 500
@ -479,6 +480,12 @@ struct netplay
/* Opposite of stalling, should we be catching up? */
bool catch_up;
/* When did we start falling behind? */
retro_time_t catch_up_time;
/* How far behind did we fall? */
uint32_t catch_up_behind;
/* Frequency with which to check CRCs */
int check_frames;

View File

@ -555,7 +555,7 @@ void netplay_sync_post_frame(netplay_t *netplay, bool stalled)
if (netplay->catch_up)
{
/* Are we caught up? */
if (netplay->self_frame_count >= lo_frame_count)
if (netplay->self_frame_count + 1 >= lo_frame_count)
{
netplay->catch_up = false;
input_driver_unset_nonblock_state();
@ -565,17 +565,44 @@ void netplay_sync_post_frame(netplay_t *netplay, bool stalled)
}
else if (!stalled)
{
if (netplay->self_frame_count + 2 < lo_frame_count)
if (netplay->self_frame_count + 3 < lo_frame_count)
{
/* Are we falling behind? */
netplay->catch_up = true;
input_driver_set_nonblock_state();
driver_set_nonblock_state();
retro_time_t cur_time = cpu_features_get_time_usec();
uint32_t cur_behind = lo_frame_count - netplay->self_frame_count;
/* We're behind, but we'll only try to catch up if we're actually
* falling behind, i.e. if we're more behind after some time */
if (netplay->catch_up_time == 0)
{
/* Record our current time to check for catch-up later */
netplay->catch_up_time = cur_time;
netplay->catch_up_behind = cur_behind;
}
else if (cur_time - netplay->catch_up_time > CATCH_UP_CHECK_TIME_USEC)
{
/* Time to check how far behind we are */
if (netplay->catch_up_behind <= cur_behind)
{
/* We're definitely falling behind! */
netplay->catch_up = true;
netplay->catch_up_time = 0;
input_driver_set_nonblock_state();
driver_set_nonblock_state();
}
else
{
/* Check again in another period */
netplay->catch_up_time = cur_time;
netplay->catch_up_behind = cur_behind;
}
}
}
else if (netplay->self_frame_count + 2 < hi_frame_count)
else if (netplay->self_frame_count + 3 < hi_frame_count)
{
size_t i;
netplay->catch_up_time = 0;
/* We're falling behind some clients but not others, so request that
* clients ahead of us stall */
@ -589,7 +616,7 @@ void netplay_sync_post_frame(netplay_t *netplay, bool stalled)
player = connection->player;
/* Are they ahead? */
if (netplay->self_frame_count + 2 < netplay->read_frame_count[player])
if (netplay->self_frame_count + 3 < netplay->read_frame_count[player])
{
/* Tell them to stall */
if (connection->stall_frame + NETPLAY_MAX_REQ_STALL_FREQUENCY <
@ -603,5 +630,9 @@ void netplay_sync_post_frame(netplay_t *netplay, bool stalled)
}
}
}
else
netplay->catch_up_time = 0;
}
else
netplay->catch_up_time = 0;
}