Rather than stalling by blocking and becoming unresponsive, stall by

replaying the same frame. TODO: Maybe mute the audio?
This commit is contained in:
Gregor Richards 2016-09-12 09:13:26 -04:00
parent 5edfbeafb0
commit 4f16a19f5e
3 changed files with 54 additions and 13 deletions

View File

@ -149,6 +149,13 @@ static bool get_self_input_state(netplay_t *netplay)
if (!netplay_delta_frame_ready(netplay, ptr, netplay->self_frame_count)) if (!netplay_delta_frame_ready(netplay, ptr, netplay->self_frame_count))
return false; 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) if (!input_driver_is_libretro_input_blocked() && netplay->self_frame_count > 0)
{ {
unsigned i; unsigned i;
@ -206,6 +213,7 @@ static bool get_self_input_state(netplay_t *netplay)
} }
memcpy(ptr->self_state, state, sizeof(state)); memcpy(ptr->self_state, state, sizeof(state));
ptr->have_local = true;
netplay->self_ptr = NEXT_PTR(netplay->self_ptr); netplay->self_ptr = NEXT_PTR(netplay->self_ptr);
return true; return true;
} }
@ -296,14 +304,8 @@ static bool netplay_get_cmd(netplay_t *netplay)
if (buffer[0] != netplay->read_frame_count) if (buffer[0] != netplay->read_frame_count)
{ {
/* FIXME: JUST drop it? */ /* FIXME: Except on the first (null) frame, this should be
return netplay_cmd_nak(netplay); * impossible, so maybe just disconnect? */
}
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;
return netplay_cmd_nak(netplay); 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_ptr = NEXT_PTR(netplay->read_ptr);
netplay->read_frame_count++; netplay->read_frame_count++;
netplay->timeout_cnt = 0; netplay->timeout_cnt = 0;
return netplay_cmd_ack(netplay); return true;
} }
case NETPLAY_CMD_FLIP_PLAYERS: 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", RARCH_LOG("Network is stalling, resending packet... Count %u of %d ...\n",
netplay->timeout_cnt, MAX_RETRIES); netplay->timeout_cnt, MAX_RETRIES);
} while (had_input || (block && netplay->read_frame_count < netplay->self_frame_count)); } while (had_input);
/*if (block) /*if (block)
return -1;*/ return -1;*/
@ -537,9 +539,8 @@ static bool netplay_poll(netplay_t *netplay)
return true; return true;
} }
/* We might have reached the end of the buffer, where we /* Read Netplay input */
* simply have to block. */ res = poll_input(netplay, 0); /* FIXME: configure stalling intervals */
res = poll_input(netplay, netplay->read_frame_count < netplay->self_frame_count - 10); /* FIXME: configure stalling intervals */
if (res == -1) if (res == -1)
{ {
netplay->has_connection = false; netplay->has_connection = false;
@ -582,6 +583,18 @@ static bool netplay_poll(netplay_t *netplay)
else else
netplay->buffer[PREV_PTR(netplay->self_ptr)].used_real = true; 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; return true;
} }

View File

@ -166,6 +166,20 @@ static void netplay_net_post_frame(netplay_t *netplay)
} }
#endif #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) static bool netplay_net_init_buffers(netplay_t *netplay)
{ {

View File

@ -49,8 +49,13 @@ struct delta_frame
uint32_t simulated_input_state[WORDS_PER_FRAME - 1]; uint32_t simulated_input_state[WORDS_PER_FRAME - 1];
uint32_t self_state[WORDS_PER_FRAME - 1]; uint32_t self_state[WORDS_PER_FRAME - 1];
/* Have we read local input? */
bool have_local; bool have_local;
/* Badly named: This is !have_real(_remote) */
bool is_simulated; bool is_simulated;
/* Is the current state as of self_frame_count using the real data? */
bool used_real; bool used_real;
}; };
@ -60,6 +65,12 @@ struct netplay_callbacks {
bool (*info_cb) (netplay_t *netplay, unsigned frames); 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 struct netplay
{ {
char nick[32]; char nick[32];
@ -131,6 +142,9 @@ struct netplay
bool pause; bool pause;
uint32_t pause_frame; uint32_t pause_frame;
/* And stalling */
int stall;
struct netplay_callbacks* net_cbs; struct netplay_callbacks* net_cbs;
}; };