Skip to content

Commit

Permalink
Fix compatibility between netplay and runahead
Browse files Browse the repository at this point in the history
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.
  • Loading branch information
GregorR committed May 31, 2018
1 parent 0045e1f commit 2c07561
Show file tree
Hide file tree
Showing 5 changed files with 19 additions and 5 deletions.
4 changes: 4 additions & 0 deletions dynamic.c
Original file line number Diff line number Diff line change
Expand Up @@ -1770,6 +1770,10 @@ bool rarch_environment_cb(unsigned cmd, void *data)
result |= 4;
if (get_hard_disable_audio())
result |= 8;
#endif
#ifdef HAVE_NETWORKING
if (netplay_driver_ctl(RARCH_NETPLAY_CTL_IS_REPLAYING, NULL))
result &= ~(1|2);
#endif
if (data != NULL)
{
Expand Down
1 change: 1 addition & 0 deletions network/netplay/netplay.h
Original file line number Diff line number Diff line change
Expand Up @@ -49,6 +49,7 @@ enum rarch_netplay_ctl_state
RARCH_NETPLAY_CTL_ENABLE_CLIENT,
RARCH_NETPLAY_CTL_DISABLE,
RARCH_NETPLAY_CTL_IS_ENABLED,
RARCH_NETPLAY_CTL_IS_REPLAYING,
RARCH_NETPLAY_CTL_IS_SERVER,
RARCH_NETPLAY_CTL_IS_CONNECTED,
RARCH_NETPLAY_CTL_IS_DATA_INITED,
Expand Down
9 changes: 7 additions & 2 deletions network/netplay/netplay_frontend.c
Original file line number Diff line number Diff line change
Expand Up @@ -322,8 +322,9 @@ static bool netplay_poll(void)
(netplay_data->run_frame_count - netplay_data->unread_frame_count) :
0;
settings_t *settings = config_get_ptr();
unsigned 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;
int input_latency_frames_min = settings->uints.netplay_input_latency_frames_min -
(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
* current frame */
Expand Down Expand Up @@ -1424,6 +1425,7 @@ bool netplay_driver_ctl(enum rarch_netplay_ctl_state state, void *data)
ret = netplay_enabled;
goto done;

case RARCH_NETPLAY_CTL_IS_REPLAYING:
case RARCH_NETPLAY_CTL_IS_DATA_INITED:
ret = false;
goto done;
Expand Down Expand Up @@ -1451,6 +1453,9 @@ bool netplay_driver_ctl(enum rarch_netplay_ctl_state state, void *data)
goto done;
case RARCH_NETPLAY_CTL_IS_ENABLED:
goto done;
case RARCH_NETPLAY_CTL_IS_REPLAYING:
ret = netplay_data->is_replay;
goto done;
case RARCH_NETPLAY_CTL_IS_SERVER:
ret = netplay_enabled && !netplay_is_client;
goto done;
Expand Down
4 changes: 2 additions & 2 deletions network/netplay/netplay_private.h
Original file line number Diff line number Diff line change
Expand Up @@ -541,8 +541,8 @@ struct netplay
int frame_run_time_ptr;
retro_time_t frame_run_time_sum, frame_run_time_avg;

/* Latency frames and limits */
unsigned input_latency_frames;
/* Latency frames; positive to hide network latency, negative to hide input latency */
int input_latency_frames;

/* Are we stalled? */
enum rarch_netplay_stall_reason stall;
Expand Down
6 changes: 5 additions & 1 deletion retroarch.c
Original file line number Diff line number Diff line change
Expand Up @@ -3339,7 +3339,11 @@ int runloop_iterate(unsigned *sleep_ms)

#ifdef HAVE_RUNAHEAD
/* 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);
else
#endif
Expand Down

0 comments on commit 2c07561

Please sign in to comment.