From 2a0202ccf5cdfc38fc9067221d8a69251af987ef Mon Sep 17 00:00:00 2001 From: Gregor Richards Date: Wed, 14 Sep 2016 23:54:18 -0400 Subject: [PATCH] Making Netplay check frequency configurable. --- configuration.c | 5 ++++- intl/msg_hash_us.c | 20 ++++++++++++++++++++ menu/menu_displaylist.c | 4 ++++ menu/menu_setting.c | 26 ++++++++++++++++++++++++++ msg_hash.h | 2 ++ network/netplay/netplay.c | 11 ++++++----- network/netplay/netplay.h | 3 ++- network/netplay/netplay_net.c | 7 +++++-- network/netplay/netplay_private.h | 3 +++ retroarch.c | 18 ++++++++++++++++++ retroarch.h | 1 + runloop.h | 1 + 12 files changed, 92 insertions(+), 9 deletions(-) diff --git a/configuration.c b/configuration.c index 99c3504982..b8d976551a 100644 --- a/configuration.c +++ b/configuration.c @@ -911,7 +911,8 @@ static int populate_settings_int(settings_t *settings, struct config_int_setting SETTING_INT("state_slot", (unsigned*)&settings->state_slot, false, 0 /* TODO */, false); #ifdef HAVE_NETPLAY SETTING_INT("netplay_ip_port", &global->netplay.port, false, 0 /* TODO */, false); - SETTING_INT("netplay_delay_frames", &global->netplay.sync_frames, false, 0 /* TODO */, false); + SETTING_INT("netplay_delay_frames", &global->netplay.sync_frames, false, 16, false); + SETTING_INT("netplay_check_frames", &global->netplay.check_frames, false, 60, false); #endif #ifdef HAVE_LANGEXTRA SETTING_INT("user_language", &settings->user_language, true, RETRO_LANGUAGE_ENGLISH, false); @@ -1788,6 +1789,8 @@ static bool config_load_file(const char *path, bool set_defaults, #ifdef HAVE_NETPLAY if (!retroarch_override_setting_is_set(RARCH_OVERRIDE_SETTING_NETPLAY_DELAY_FRAMES)) CONFIG_GET_INT_BASE(conf, global, netplay.sync_frames, "netplay_delay_frames"); + if (!retroarch_override_setting_is_set(RARCH_OVERRIDE_SETTING_NETPLAY_CHECK_FRAMES)) + CONFIG_GET_INT_BASE(conf, global, netplay.sync_frames, "netplay_check_frames"); if (!retroarch_override_setting_is_set(RARCH_OVERRIDE_SETTING_NETPLAY_IP_PORT)) CONFIG_GET_INT_BASE(conf, global, netplay.port, "netplay_ip_port"); #endif diff --git a/intl/msg_hash_us.c b/intl/msg_hash_us.c index 36f0f7d8d4..dfefcb4f0b 100644 --- a/intl/msg_hash_us.c +++ b/intl/msg_hash_us.c @@ -1558,6 +1558,22 @@ int menu_hash_get_help_us_enum(enum msg_hash_enums msg, char *s, size_t len) "Increasing this value will increase \n" "performance, but introduce more latency."); break; + case MENU_ENUM_LABEL_NETPLAY_CHECK_FRAMES: + snprintf(s, len, + "The frequency in frames with which netplay \n" + "will verify that the host and client are in \n" + "sync. \n" + " \n" + "With most cores, this value will have no \n" + "visible effect and can be ignored. With \n" + "nondeterminstic cores, this value determines \n" + "how often the netplay peers will be brought \n" + "into sync. With buggy cores, setting this \n" + "to any non-zero value will cause severe \n" + "performance issues. Set to zero to perform \n" + "no checks. This value is only used on the \n" + "netplay host. \n"); + break; case MENU_ENUM_LABEL_VIDEO_MAX_SWAPCHAIN_IMAGES: snprintf(s, len, "Maximum amount of swapchain images. This \n" @@ -2424,6 +2440,8 @@ static const char *menu_hash_to_str_us_label_enum(enum msg_hash_enums msg) return "bluetooth_enable"; case MENU_ENUM_LABEL_NETPLAY_DELAY_FRAMES: return "netplay_delay_frames"; + case MENU_ENUM_LABEL_NETPLAY_CHECK_FRAMES: + return "netplay_check_frames"; case MENU_ENUM_LABEL_NETPLAY_MODE: return "netplay_mode"; case MENU_ENUM_LABEL_RGUI_SHOW_START_SCREEN: @@ -3747,6 +3765,8 @@ const char *msg_hash_to_str_us(enum msg_hash_enums msg) return "Bluetooth Enable"; case MENU_ENUM_LABEL_VALUE_NETPLAY_DELAY_FRAMES: return "Netplay Delay Frames"; + case MENU_ENUM_LABEL_VALUE_NETPLAY_CHECK_FRAMES: + return "Netplay Check Frames"; case MENU_ENUM_LABEL_VALUE_NETPLAY_MODE: return "Netplay Client Enable"; case MENU_ENUM_LABEL_VALUE_RGUI_SHOW_START_SCREEN: diff --git a/menu/menu_displaylist.c b/menu/menu_displaylist.c index 3c880a3830..e01b84d658 100644 --- a/menu/menu_displaylist.c +++ b/menu/menu_displaylist.c @@ -4684,6 +4684,10 @@ bool menu_displaylist_ctl(enum menu_displaylist_ctl_state type, void *data) MENU_ENUM_LABEL_NETPLAY_DELAY_FRAMES, PARSE_ONLY_UINT, false) != -1) count++; + if (menu_displaylist_parse_settings_enum(menu, info, + MENU_ENUM_LABEL_NETPLAY_CHECK_FRAMES, + PARSE_ONLY_UINT, false) != -1) + count++; if (menu_displaylist_parse_settings_enum(menu, info, MENU_ENUM_LABEL_NETPLAY_TCP_UDP_PORT, PARSE_ONLY_UINT, false) != -1) diff --git a/menu/menu_setting.c b/menu/menu_setting.c index 930e1ec756..4bbc769230 100644 --- a/menu/menu_setting.c +++ b/menu/menu_setting.c @@ -1675,6 +1675,17 @@ void general_write_handler(void *data) } #endif break; + case MENU_ENUM_LABEL_NETPLAY_CHECK_FRAMES: +#ifdef HAVE_NETPLAY + { + bool val = (global->netplay.check_frames > 0); + + if (val) + retroarch_override_setting_set(RARCH_OVERRIDE_SETTING_NETPLAY_CHECK_FRAMES); + else + retroarch_override_setting_unset(RARCH_OVERRIDE_SETTING_NETPLAY_CHECK_FRAMES); + } +#endif default: break; } @@ -5814,6 +5825,21 @@ static bool setting_append_list( settings_data_list_current_add_flags(list, list_info, SD_FLAG_ADVANCED); menu_settings_list_current_add_enum_idx(list, list_info, MENU_ENUM_LABEL_NETPLAY_DELAY_FRAMES); + CONFIG_UINT( + list, list_info, + &global->netplay.check_frames, + msg_hash_to_str(MENU_ENUM_LABEL_NETPLAY_CHECK_FRAMES), + msg_hash_to_str(MENU_ENUM_LABEL_VALUE_NETPLAY_CHECK_FRAMES), + 0, + &group_info, + &subgroup_info, + parent_group, + general_write_handler, + general_read_handler); + menu_settings_list_current_add_range(list, list_info, 0, 10, 1, true, false); + settings_data_list_current_add_flags(list, list_info, SD_FLAG_ADVANCED); + menu_settings_list_current_add_enum_idx(list, list_info, MENU_ENUM_LABEL_NETPLAY_CHECK_FRAMES); + CONFIG_UINT( list, list_info, &global->netplay.port, diff --git a/msg_hash.h b/msg_hash.h index 2fcdbc3425..83b8eea021 100644 --- a/msg_hash.h +++ b/msg_hash.h @@ -1111,6 +1111,8 @@ enum msg_hash_enums MENU_ENUM_LABEL_VALUE_NETPLAY_CLIENT_SWAP_INPUT, MENU_ENUM_LABEL_NETPLAY_DELAY_FRAMES, MENU_ENUM_LABEL_VALUE_NETPLAY_DELAY_FRAMES, + MENU_ENUM_LABEL_NETPLAY_CHECK_FRAMES, + MENU_ENUM_LABEL_VALUE_NETPLAY_CHECK_FRAMES, MENU_ENUM_LABEL_NETPLAY_SPECTATOR_MODE_ENABLE, MENU_ENUM_LABEL_VALUE_NETPLAY_SPECTATOR_MODE_ENABLE, MENU_ENUM_LABEL_NETPLAY_TCP_UDP_PORT, diff --git a/network/netplay/netplay.c b/network/netplay/netplay.c index 0fc9e9ca10..77ca32ae28 100644 --- a/network/netplay/netplay.c +++ b/network/netplay/netplay.c @@ -898,6 +898,7 @@ static bool init_socket(netplay_t *netplay, const char *server, uint16_t port) * @server : IP address of server. * @port : Port of server. * @frames : Amount of lag frames. + * @check_frames : Frequency with which to check CRCs. * @cb : Libretro callbacks. * @spectate : If true, enable spectator mode. * @nick : Nickname of user. @@ -908,9 +909,8 @@ static bool init_socket(netplay_t *netplay, const char *server, uint16_t port) * Returns: new netplay handle. **/ netplay_t *netplay_new(const char *server, uint16_t port, - unsigned frames, const struct retro_callbacks *cb, - bool spectate, - const char *nick) + unsigned frames, unsigned check_frames, const struct retro_callbacks *cb, + bool spectate, const char *nick) { netplay_t *netplay = (netplay_t*)calloc(1, sizeof(*netplay)); if (!netplay) @@ -923,6 +923,7 @@ netplay_t *netplay_new(const char *server, uint16_t port, netplay->is_server = server == NULL; strlcpy(netplay->nick, nick, sizeof(netplay->nick)); netplay->stall_frames = frames; + netplay->check_frames = check_frames; if(spectate) netplay->net_cbs = netplay_get_cbs_spectate(); @@ -1263,8 +1264,8 @@ bool init_netplay(void) netplay_data = (netplay_t*)netplay_new( global->netplay.is_client ? global->netplay.server : NULL, global->netplay.port ? global->netplay.port : RARCH_DEFAULT_PORT, - global->netplay.sync_frames, &cbs, global->netplay.is_spectate, - settings->username); + global->netplay.sync_frames, global->netplay.check_frames, &cbs, + global->netplay.is_spectate, settings->username); if (netplay_data) return true; diff --git a/network/netplay/netplay.h b/network/netplay/netplay.h index eeb3783840..7ed2400841 100644 --- a/network/netplay/netplay.h +++ b/network/netplay/netplay.h @@ -136,6 +136,7 @@ int16_t input_state_spectate_client(unsigned port, unsigned device, * @server : IP address of server. * @port : Port of server. * @frames : Amount of lag frames. + * @check_frames : Frequency with which to check CRCs. * @cb : Libretro callbacks. * @spectate : If true, enable spectator mode. * @nick : Nickname of user. @@ -146,7 +147,7 @@ int16_t input_state_spectate_client(unsigned port, unsigned device, * Returns: new netplay handle. **/ netplay_t *netplay_new(const char *server, - uint16_t port, unsigned frames, + uint16_t port, unsigned frames, unsigned check_frames, const struct retro_callbacks *cb, bool spectate, const char *nick); diff --git a/network/netplay/netplay_net.c b/network/netplay/netplay_net.c index bb7851a08c..225135416a 100644 --- a/network/netplay/netplay_net.c +++ b/network/netplay/netplay_net.c @@ -28,8 +28,11 @@ static void netplay_handle_frame_hash(netplay_t *netplay, struct delta_frame *de { if (netplay_is_server(netplay)) { - delta->crc = netplay_delta_frame_crc(netplay, delta); - netplay_cmd_crc(netplay, delta); + if (netplay->check_frames && delta->frame % netplay->check_frames == 0) + { + delta->crc = netplay_delta_frame_crc(netplay, delta); + netplay_cmd_crc(netplay, delta); + } } else if (delta->crc) { diff --git a/network/netplay/netplay_private.h b/network/netplay/netplay_private.h index 3f9a335ef5..5b4b5e28e7 100644 --- a/network/netplay/netplay_private.h +++ b/network/netplay/netplay_private.h @@ -161,6 +161,9 @@ struct netplay int stall; retro_time_t stall_time; + /* Frequency with which to check CRCs */ + uint32_t check_frames; + struct netplay_callbacks* net_cbs; }; diff --git a/retroarch.c b/retroarch.c index e482ab0b22..ca5559f93e 100644 --- a/retroarch.c +++ b/retroarch.c @@ -90,6 +90,7 @@ enum { RA_OPT_MENU = 256, /* must be outside the range of a char */ + RA_OPT_CHECK_FRAMES, RA_OPT_PORT, RA_OPT_SPECTATE, RA_OPT_NICK, @@ -306,6 +307,8 @@ static void retroarch_print_help(const char *arg0) puts(" -C, --connect=HOST Connect to netplay server as user 2."); puts(" --port=PORT Port used to netplay. Default is 55435."); puts(" -F, --frames=NUMBER Sync frames when using netplay."); + puts(" --check-frames=NUMBER\n" + " Check frames when using netplay."); puts(" --spectate Connect to netplay server as spectator."); #endif puts(" --nick=NICK Picks a username (for use with netplay). " @@ -677,6 +680,7 @@ static void retroarch_parse_input(int argc, char *argv[]) { "host", 0, NULL, 'H' }, { "connect", 1, NULL, 'C' }, { "frames", 1, NULL, 'F' }, + { "check-frames", 1, NULL, RA_OPT_CHECK_FRAMES }, { "port", 1, NULL, RA_OPT_PORT }, { "spectate", 0, NULL, RA_OPT_SPECTATE }, #endif @@ -978,6 +982,11 @@ static void retroarch_parse_input(int argc, char *argv[]) break; #ifdef HAVE_NETPLAY + case RA_OPT_CHECK_FRAMES: + retroarch_override_setting_set(RARCH_OVERRIDE_SETTING_NETPLAY_CHECK_FRAMES); + global->netplay.check_frames = strtoul(optarg, NULL, 0); + break; + case RA_OPT_PORT: retroarch_override_setting_set(RARCH_OVERRIDE_SETTING_NETPLAY_IP_PORT); global->netplay.port = strtoul(optarg, NULL, 0); @@ -1645,6 +1654,7 @@ static bool has_set_netplay_mode = false; static bool has_set_netplay_ip_address = false; static bool has_set_netplay_ip_port = false; static bool has_set_netplay_delay_frames= false; +static bool has_set_netplay_check_frames= false; static bool has_set_ups_pref = false; static bool has_set_bps_pref = false; static bool has_set_ips_pref = false; @@ -1671,6 +1681,8 @@ bool retroarch_override_setting_is_set(enum rarch_override_setting enum_idx) return has_set_netplay_ip_port; case RARCH_OVERRIDE_SETTING_NETPLAY_DELAY_FRAMES: return has_set_netplay_delay_frames; + case RARCH_OVERRIDE_SETTING_NETPLAY_CHECK_FRAMES: + return has_set_netplay_check_frames; case RARCH_OVERRIDE_SETTING_UPS_PREF: return has_set_ups_pref; case RARCH_OVERRIDE_SETTING_BPS_PREF: @@ -1717,6 +1729,9 @@ void retroarch_override_setting_set(enum rarch_override_setting enum_idx) case RARCH_OVERRIDE_SETTING_NETPLAY_DELAY_FRAMES: has_set_netplay_delay_frames = true; break; + case RARCH_OVERRIDE_SETTING_NETPLAY_CHECK_FRAMES: + has_set_netplay_check_frames = true; + break; case RARCH_OVERRIDE_SETTING_UPS_PREF: has_set_ups_pref = true; break; @@ -1763,6 +1778,9 @@ void retroarch_override_setting_unset(enum rarch_override_setting enum_idx) case RARCH_OVERRIDE_SETTING_NETPLAY_DELAY_FRAMES: has_set_netplay_delay_frames = false; break; + case RARCH_OVERRIDE_SETTING_NETPLAY_CHECK_FRAMES: + has_set_netplay_check_frames = false; + break; case RARCH_OVERRIDE_SETTING_UPS_PREF: has_set_ups_pref = false; break; diff --git a/retroarch.h b/retroarch.h index 878d24d756..eab78907c1 100644 --- a/retroarch.h +++ b/retroarch.h @@ -110,6 +110,7 @@ enum rarch_override_setting RARCH_OVERRIDE_SETTING_NETPLAY_IP_ADDRESS, RARCH_OVERRIDE_SETTING_NETPLAY_IP_PORT, RARCH_OVERRIDE_SETTING_NETPLAY_DELAY_FRAMES, + RARCH_OVERRIDE_SETTING_NETPLAY_CHECK_FRAMES, RARCH_OVERRIDE_SETTING_UPS_PREF, RARCH_OVERRIDE_SETTING_BPS_PREF, RARCH_OVERRIDE_SETTING_IPS_PREF, diff --git a/runloop.h b/runloop.h index 6bee74e3a0..b3920a9d85 100644 --- a/runloop.h +++ b/runloop.h @@ -228,6 +228,7 @@ typedef struct global bool is_client; bool is_spectate; unsigned sync_frames; + unsigned check_frames; unsigned port; } netplay; #endif