Fix compatibility between netplay and runahead

Unsurprisingly, netplay and runahead are wildly incompatible; both rely
on internal rewinding, without communicating this fact to each other.
Somewhat more surprisingly, netplay already has all the infrastructure
for negative input latency, as it's structurally the same as receiving
delayed input from a peer. This patch makes the two features
"compatible" by disabling runahead per se when netplay is active, and
using runahead's configuration to adjust netplay's own input latency
feature, which is now allowed to be negative. The effect is mostly the
same (modulo the second core support), and it doesn't confuse netplay
peers.
This commit is contained in:
Gregor Richards 2018-05-30 22:01:02 -04:00
parent 0045e1fff2
commit 2c07561fc1
5 changed files with 19 additions and 5 deletions

View File

@ -1770,6 +1770,10 @@ bool rarch_environment_cb(unsigned cmd, void *data)
result |= 4; result |= 4;
if (get_hard_disable_audio()) if (get_hard_disable_audio())
result |= 8; result |= 8;
#endif
#ifdef HAVE_NETWORKING
if (netplay_driver_ctl(RARCH_NETPLAY_CTL_IS_REPLAYING, NULL))
result &= ~(1|2);
#endif #endif
if (data != NULL) if (data != NULL)
{ {

View File

@ -49,6 +49,7 @@ enum rarch_netplay_ctl_state
RARCH_NETPLAY_CTL_ENABLE_CLIENT, RARCH_NETPLAY_CTL_ENABLE_CLIENT,
RARCH_NETPLAY_CTL_DISABLE, RARCH_NETPLAY_CTL_DISABLE,
RARCH_NETPLAY_CTL_IS_ENABLED, RARCH_NETPLAY_CTL_IS_ENABLED,
RARCH_NETPLAY_CTL_IS_REPLAYING,
RARCH_NETPLAY_CTL_IS_SERVER, RARCH_NETPLAY_CTL_IS_SERVER,
RARCH_NETPLAY_CTL_IS_CONNECTED, RARCH_NETPLAY_CTL_IS_CONNECTED,
RARCH_NETPLAY_CTL_IS_DATA_INITED, RARCH_NETPLAY_CTL_IS_DATA_INITED,

View File

@ -322,8 +322,9 @@ static bool netplay_poll(void)
(netplay_data->run_frame_count - netplay_data->unread_frame_count) : (netplay_data->run_frame_count - netplay_data->unread_frame_count) :
0; 0;
settings_t *settings = config_get_ptr(); settings_t *settings = config_get_ptr();
unsigned input_latency_frames_min = settings->uints.netplay_input_latency_frames_min; int input_latency_frames_min = settings->uints.netplay_input_latency_frames_min -
unsigned input_latency_frames_max = input_latency_frames_min + settings->uints.netplay_input_latency_frames_range; (settings->bools.run_ahead_enabled ? settings->uints.run_ahead_frames : 0);
int input_latency_frames_max = input_latency_frames_min + settings->uints.netplay_input_latency_frames_range;
/* Assume we need a couple frames worth of time to actually run the /* Assume we need a couple frames worth of time to actually run the
* current frame */ * current frame */
@ -1424,6 +1425,7 @@ bool netplay_driver_ctl(enum rarch_netplay_ctl_state state, void *data)
ret = netplay_enabled; ret = netplay_enabled;
goto done; goto done;
case RARCH_NETPLAY_CTL_IS_REPLAYING:
case RARCH_NETPLAY_CTL_IS_DATA_INITED: case RARCH_NETPLAY_CTL_IS_DATA_INITED:
ret = false; ret = false;
goto done; goto done;
@ -1451,6 +1453,9 @@ bool netplay_driver_ctl(enum rarch_netplay_ctl_state state, void *data)
goto done; goto done;
case RARCH_NETPLAY_CTL_IS_ENABLED: case RARCH_NETPLAY_CTL_IS_ENABLED:
goto done; goto done;
case RARCH_NETPLAY_CTL_IS_REPLAYING:
ret = netplay_data->is_replay;
goto done;
case RARCH_NETPLAY_CTL_IS_SERVER: case RARCH_NETPLAY_CTL_IS_SERVER:
ret = netplay_enabled && !netplay_is_client; ret = netplay_enabled && !netplay_is_client;
goto done; goto done;

View File

@ -541,8 +541,8 @@ struct netplay
int frame_run_time_ptr; int frame_run_time_ptr;
retro_time_t frame_run_time_sum, frame_run_time_avg; retro_time_t frame_run_time_sum, frame_run_time_avg;
/* Latency frames and limits */ /* Latency frames; positive to hide network latency, negative to hide input latency */
unsigned input_latency_frames; int input_latency_frames;
/* Are we stalled? */ /* Are we stalled? */
enum rarch_netplay_stall_reason stall; enum rarch_netplay_stall_reason stall;

View File

@ -3339,7 +3339,11 @@ int runloop_iterate(unsigned *sleep_ms)
#ifdef HAVE_RUNAHEAD #ifdef HAVE_RUNAHEAD
/* Run Ahead Feature replaces the call to core_run in this loop */ /* Run Ahead Feature replaces the call to core_run in this loop */
if (settings->bools.run_ahead_enabled && settings->uints.run_ahead_frames > 0) if (settings->bools.run_ahead_enabled && settings->uints.run_ahead_frames > 0
#ifdef HAVE_NETWORKING
&& !netplay_driver_ctl(RARCH_NETPLAY_CTL_IS_ENABLED, NULL)
#endif
)
run_ahead(settings->uints.run_ahead_frames, settings->bools.run_ahead_secondary_instance); run_ahead(settings->uints.run_ahead_frames, settings->bools.run_ahead_secondary_instance);
else else
#endif #endif