Make Netplay flipping deterministic

The receiving side of a player-flip request now does a forced rewind to
assure that any already-computed frames are computed with the players on
the right side.
This commit is contained in:
Gregor Richards 2016-09-15 18:51:56 -04:00
parent 827009d2d3
commit 4076b14568
2 changed files with 12 additions and 6 deletions

View File

@ -293,7 +293,7 @@ static bool netplay_get_cmd(netplay_t *netplay)
flip_frame = ntohl(flip_frame); flip_frame = ntohl(flip_frame);
if (flip_frame < netplay->flip_frame) if (flip_frame < netplay->read_frame_count)
{ {
RARCH_ERR("Host asked us to flip users in the past. Not possible ...\n"); RARCH_ERR("Host asked us to flip users in the past. Not possible ...\n");
return netplay_cmd_nak(netplay); return netplay_cmd_nak(netplay);
@ -302,6 +302,12 @@ static bool netplay_get_cmd(netplay_t *netplay)
netplay->flip ^= true; netplay->flip ^= true;
netplay->flip_frame = flip_frame; netplay->flip_frame = flip_frame;
/* Force a rewind to assure the flip happens: This just prevents us
* from skipping other past the flip because our prediction was
* correct */
if (flip_frame < netplay->self_frame_count)
netplay->force_rewind = true;
RARCH_LOG("Netplay users are flipped.\n"); RARCH_LOG("Netplay users are flipped.\n");
runloop_msg_queue_push("Netplay users are flipped.", 1, 180, false); runloop_msg_queue_push("Netplay users are flipped.", 1, 180, false);
@ -1008,7 +1014,8 @@ error:
**/ **/
static void netplay_flip_users(netplay_t *netplay) static void netplay_flip_users(netplay_t *netplay)
{ {
uint32_t flip_frame = netplay->self_frame_count + 32; /* FIXME: This value is now arbitrary */ /* Must be in the future because we may have already sent this frame's data */
uint32_t flip_frame = netplay->self_frame_count + 1;
uint32_t flip_frame_net = htonl(flip_frame); uint32_t flip_frame_net = htonl(flip_frame);
bool command = netplay_command( bool command = netplay_command(
netplay, NETPLAY_CMD_FLIP_PLAYERS, netplay, NETPLAY_CMD_FLIP_PLAYERS,

View File

@ -143,11 +143,10 @@ struct netplay
size_t input_sz; size_t input_sz;
} spectate; } spectate;
bool is_server; bool is_server;
/* User flipping /* User flipping
* Flipping state. If ptr >= flip_frame, we apply the flip. * Flipping state. If frame >= flip_frame, we apply the flip.
* If not, we apply the opposite, effectively creating a trigger point. * If not, we apply the opposite, effectively creating a trigger point. */
* To avoid collition we need to make sure our client/host is synced up
* well after flip_frame before allowing another flip. */
bool flip; bool flip;
uint32_t flip_frame; uint32_t flip_frame;