From 2c07561fc10d6942935769d6a855b994c5bfbb0b Mon Sep 17 00:00:00 2001 From: Gregor Richards Date: Wed, 30 May 2018 22:01:02 -0400 Subject: [PATCH] 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. --- dynamic.c | 4 ++++ network/netplay/netplay.h | 1 + network/netplay/netplay_frontend.c | 9 +++++++-- network/netplay/netplay_private.h | 4 ++-- retroarch.c | 6 +++++- 5 files changed, 19 insertions(+), 5 deletions(-) diff --git a/dynamic.c b/dynamic.c index 91394d9509..0668f846ed 100644 --- a/dynamic.c +++ b/dynamic.c @@ -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) { diff --git a/network/netplay/netplay.h b/network/netplay/netplay.h index 535eb2ebe5..721ab5f01d 100644 --- a/network/netplay/netplay.h +++ b/network/netplay/netplay.h @@ -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, diff --git a/network/netplay/netplay_frontend.c b/network/netplay/netplay_frontend.c index bef3cbbc4b..016f02232c 100644 --- a/network/netplay/netplay_frontend.c +++ b/network/netplay/netplay_frontend.c @@ -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 */ @@ -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; @@ -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; diff --git a/network/netplay/netplay_private.h b/network/netplay/netplay_private.h index 2445892c49..d607b5e84f 100644 --- a/network/netplay/netplay_private.h +++ b/network/netplay/netplay_private.h @@ -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; diff --git a/retroarch.c b/retroarch.c index d5c5ebdb26..f05c8b270b 100644 --- a/retroarch.c +++ b/retroarch.c @@ -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