From 816d7786ac84588eb00312427e00b5b42f607235 Mon Sep 17 00:00:00 2001 From: Gregor Richards Date: Thu, 16 Feb 2017 19:17:06 -0500 Subject: [PATCH] Re-adding the option to start in spectator mode This used to be a configuration option because spectator mode and "net" mode were incompatible. When the ability to switch between player and spectator was added, the configuration option was removed, since it was no longer a mode toggle. This re-adds it, mainly so that I can use it to implement regression tests. --- config.def.h | 3 +++ configuration.c | 1 + configuration.h | 1 + intl/msg_hash_lbl.h | 2 ++ intl/msg_hash_us.c | 8 ++++++++ intl/msg_hash_us.h | 6 ++++++ menu/cbs/menu_cbs_sublabel.c | 4 ++++ menu/menu_displaylist.c | 4 ++++ menu/menu_setting.c | 15 +++++++++++++++ msg_hash.h | 1 + network/netplay/README | 2 +- network/netplay/netplay_frontend.c | 4 ++++ network/netplay/netplay_handshake.c | 8 ++++++-- network/netplay/netplay_init.c | 2 +- 14 files changed, 57 insertions(+), 4 deletions(-) diff --git a/config.def.h b/config.def.h index 6b01bc9e59..82a99c79b5 100644 --- a/config.def.h +++ b/config.def.h @@ -818,6 +818,9 @@ static const unsigned autosave_interval = 0; /* Publicly announce netplay */ static const bool netplay_public_announce = true; +/* Start netplay in spectator mode */ +static const bool netplay_start_as_spectator = false; + /* Netplay without savestates/rewind */ static const bool netplay_stateless_mode = false; diff --git a/configuration.c b/configuration.c index b40de26d25..1812c2bef1 100644 --- a/configuration.c +++ b/configuration.c @@ -729,6 +729,7 @@ static struct config_bool_setting *populate_settings_bool(settings_t *settings, SETTING_BOOL("menu_swap_ok_cancel_buttons", &settings->input.menu_swap_ok_cancel_buttons, true, menu_swap_ok_cancel_buttons, false); #ifdef HAVE_NETWORKING SETTING_BOOL("netplay_public_announce", &settings->netplay.public_announce, true, netplay_public_announce, false); + SETTING_BOOL("netplay_start_as_spectator", &settings->netplay.start_as_spectator, false, netplay_start_as_spectator, false); SETTING_BOOL("netplay_stateless_mode", &settings->netplay.stateless_mode, false, netplay_stateless_mode, false); SETTING_BOOL("netplay_client_swap_input", &settings->netplay.swap_input, true, netplay_client_swap_input, false); #endif diff --git a/configuration.h b/configuration.h index a8f1e20e64..3b6c51306f 100644 --- a/configuration.h +++ b/configuration.h @@ -406,6 +406,7 @@ typedef struct settings bool public_announce; char server[255]; unsigned port; + bool start_as_spectator; bool stateless_mode; int check_frames; unsigned input_latency_frames_min; diff --git a/intl/msg_hash_lbl.h b/intl/msg_hash_lbl.h index 277d837046..8772de1888 100644 --- a/intl/msg_hash_lbl.h +++ b/intl/msg_hash_lbl.h @@ -617,6 +617,8 @@ MSG_HASH(MENU_ENUM_LABEL_NETPLAY_SPECTATE_PASSWORD, "netplay_spectate_password") MSG_HASH(MENU_ENUM_LABEL_NETPLAY_SPECTATOR_MODE_ENABLE, "netplay_spectator_mode_enable") +MSG_HASH(MENU_ENUM_LABEL_NETPLAY_START_AS_SPECTATOR, + "netplay_start_as_spectator") MSG_HASH(MENU_ENUM_LABEL_NETPLAY_STATELESS_MODE, "netplay_stateless_mode") MSG_HASH(MENU_ENUM_LABEL_NETPLAY_TCP_UDP_PORT, diff --git a/intl/msg_hash_us.c b/intl/msg_hash_us.c index dfd157ff38..6a7cdc4be1 100644 --- a/intl/msg_hash_us.c +++ b/intl/msg_hash_us.c @@ -1542,6 +1542,14 @@ int menu_hash_get_help_us_enum(enum msg_hash_enums msg, char *s, size_t len) { "If set to false, clients must manually connect \n" "rather than using the public lobby."); break; + case MENU_ENUM_LABEL_NETPLAY_START_AS_SPECTATOR: + snprintf(s, len, + "Whether to start netplay in spectator mode. \n" + " \n" + "If set to true, netplay will be in spectator mode \n" + "on start. It's always possible to change mode \n" + "later."); + break; case MENU_ENUM_LABEL_NETPLAY_STATELESS_MODE: snprintf(s, len, "Whether to run netplay in a mode not requiring\n" diff --git a/intl/msg_hash_us.h b/intl/msg_hash_us.h index d370efde10..7ca3391f13 100644 --- a/intl/msg_hash_us.h +++ b/intl/msg_hash_us.h @@ -993,6 +993,8 @@ MSG_HASH(MENU_ENUM_LABEL_VALUE_NETPLAY_PUBLIC_ANNOUNCE, "Publicly Announce Netplay") MSG_HASH(MENU_ENUM_LABEL_VALUE_NETPLAY_SETTINGS, "Netplay settings") +MSG_HASH(MENU_ENUM_LABEL_VALUE_NETPLAY_START_AS_SPECTATOR, + "Netplay Spectator Mode") MSG_HASH(MENU_ENUM_LABEL_VALUE_NETPLAY_STATELESS_MODE, "Netplay Stateless Mode") MSG_HASH(MENU_ENUM_LABEL_VALUE_NETPLAY_SPECTATE_PASSWORD, @@ -2632,6 +2634,10 @@ MSG_HASH( MENU_ENUM_SUBLABEL_NETPLAY_SPECTATE_PASSWORD, "The password for connecting to the netplay host with only spectator privileges. Used only in host mode." ) +MSG_HASH( + MENU_ENUM_SUBLABEL_NETPLAY_START_AS_SPECTATOR, + "Whether to start netplay in spectator mode." + ) MSG_HASH( MENU_ENUM_SUBLABEL_NETPLAY_STATELESS_MODE, "Whether to run netplay in a mode not requiring save states. If set to true, a very fast network is required, but no rewinding is performed, so there will be no netplay jitter." diff --git a/menu/cbs/menu_cbs_sublabel.c b/menu/cbs/menu_cbs_sublabel.c index e57e66043e..161ff63e57 100644 --- a/menu/cbs/menu_cbs_sublabel.c +++ b/menu/cbs/menu_cbs_sublabel.c @@ -189,6 +189,7 @@ default_sublabel_macro(action_bind_sublabel_netplay_ip_address, MENU_ default_sublabel_macro(action_bind_sublabel_netplay_tcp_udp_port, MENU_ENUM_SUBLABEL_NETPLAY_TCP_UDP_PORT) default_sublabel_macro(action_bind_sublabel_netplay_password, MENU_ENUM_SUBLABEL_NETPLAY_PASSWORD) default_sublabel_macro(action_bind_sublabel_netplay_spectate_password, MENU_ENUM_SUBLABEL_NETPLAY_SPECTATE_PASSWORD) +default_sublabel_macro(action_bind_sublabel_netplay_start_as_spectator, MENU_ENUM_SUBLABEL_NETPLAY_START_AS_SPECTATOR) default_sublabel_macro(action_bind_sublabel_netplay_stateless_mode, MENU_ENUM_SUBLABEL_NETPLAY_STATELESS_MODE) default_sublabel_macro(action_bind_sublabel_netplay_check_frames, MENU_ENUM_SUBLABEL_NETPLAY_CHECK_FRAMES) default_sublabel_macro(action_bind_sublabel_netplay_nat_traversal, MENU_ENUM_SUBLABEL_NETPLAY_NAT_TRAVERSAL) @@ -746,6 +747,9 @@ int menu_cbs_init_bind_sublabel(menu_file_list_cbs_t *cbs, case MENU_ENUM_LABEL_NETPLAY_CHECK_FRAMES: BIND_ACTION_SUBLABEL(cbs, action_bind_sublabel_netplay_check_frames); break; + case MENU_ENUM_LABEL_NETPLAY_START_AS_SPECTATOR: + BIND_ACTION_SUBLABEL(cbs, action_bind_sublabel_netplay_start_as_spectator); + break; case MENU_ENUM_LABEL_NETPLAY_STATELESS_MODE: BIND_ACTION_SUBLABEL(cbs, action_bind_sublabel_netplay_stateless_mode); break; diff --git a/menu/menu_displaylist.c b/menu/menu_displaylist.c index a1a2b319fb..641c8847d5 100644 --- a/menu/menu_displaylist.c +++ b/menu/menu_displaylist.c @@ -4813,6 +4813,10 @@ bool menu_displaylist_ctl(enum menu_displaylist_ctl_state type, void *data) MENU_ENUM_LABEL_NETPLAY_SPECTATE_PASSWORD, PARSE_ONLY_STRING, false) != -1) count++; + if (menu_displaylist_parse_settings_enum(menu, info, + MENU_ENUM_LABEL_NETPLAY_START_AS_SPECTATOR, + PARSE_ONLY_BOOL, false) != -1) + count++; if (menu_displaylist_parse_settings_enum(menu, info, MENU_ENUM_LABEL_NETPLAY_STATELESS_MODE, PARSE_ONLY_BOOL, false) != -1) diff --git a/menu/menu_setting.c b/menu/menu_setting.c index 6cba6258f5..ae82515b83 100644 --- a/menu/menu_setting.c +++ b/menu/menu_setting.c @@ -5661,6 +5661,21 @@ static bool setting_append_list( general_read_handler); settings_data_list_current_add_flags(list, list_info, SD_FLAG_ALLOW_INPUT); + CONFIG_BOOL( + list, list_info, + &settings->netplay.start_as_spectator, + MENU_ENUM_LABEL_NETPLAY_START_AS_SPECTATOR, + MENU_ENUM_LABEL_VALUE_NETPLAY_START_AS_SPECTATOR, + false, + MENU_ENUM_LABEL_VALUE_OFF, + MENU_ENUM_LABEL_VALUE_ON, + &group_info, + &subgroup_info, + parent_group, + general_write_handler, + general_read_handler, + SD_FLAG_NONE); + CONFIG_BOOL( list, list_info, &settings->netplay.stateless_mode, diff --git a/msg_hash.h b/msg_hash.h index fba5261515..52b421b503 100644 --- a/msg_hash.h +++ b/msg_hash.h @@ -1019,6 +1019,7 @@ enum msg_hash_enums MENU_LABEL(NETPLAY_CLIENT_SWAP_INPUT), MENU_LABEL(NETPLAY_DELAY_FRAMES), MENU_LABEL(NETPLAY_PUBLIC_ANNOUNCE), + MENU_LABEL(NETPLAY_START_AS_SPECTATOR), MENU_LABEL(NETPLAY_STATELESS_MODE), MENU_LABEL(NETPLAY_CHECK_FRAMES), MENU_LABEL(NETPLAY_INPUT_LATENCY_FRAMES_MIN), diff --git a/network/netplay/README b/network/netplay/README index 460dbc91cc..2f32dfd98f 100644 --- a/network/netplay/README +++ b/network/netplay/README @@ -319,7 +319,7 @@ Description: Command: RESET Payload: { - frame: uint32 + frame number: uint32 } Description: Indicate that the core was reset at the beginning of the given frame. diff --git a/network/netplay/netplay_frontend.c b/network/netplay/netplay_frontend.c index 0afbbcb353..e02332fed0 100644 --- a/network/netplay/netplay_frontend.c +++ b/network/netplay/netplay_frontend.c @@ -1095,7 +1095,11 @@ bool init_netplay(void *direct_host, const char *server, unsigned port) quirks); if (netplay_data) + { + if (netplay_data->is_server && !settings->netplay.start_as_spectator) + netplay_data->self_mode = NETPLAY_CONNECTION_PLAYING; return true; + } RARCH_WARN("%s\n", msg_hash_to_str(MSG_NETPLAY_FAILED)); diff --git a/network/netplay/netplay_handshake.c b/network/netplay/netplay_handshake.c index 4df482e0e9..6350770520 100644 --- a/network/netplay/netplay_handshake.c +++ b/network/netplay/netplay_handshake.c @@ -878,6 +878,7 @@ bool netplay_handshake_pre_sync(netplay_t *netplay, retro_ctx_controller_info_t pad; char new_nick[NETPLAY_NICK_LEN]; retro_ctx_memory_info_t mem_info; + settings_t *settings = config_get_ptr(); RECV(cmd, sizeof(cmd)) { @@ -1021,8 +1022,11 @@ bool netplay_handshake_pre_sync(netplay_t *netplay, netplay_handshake_ready(netplay, connection); netplay_recv_flush(&connection->recv_packet_buffer); - /* Ask to go to player mode */ - return netplay_cmd_mode(netplay, connection, NETPLAY_CONNECTION_PLAYING); + /* Ask to switch to playing mode if we should */ + if (!settings->netplay.start_as_spectator) + return netplay_cmd_mode(netplay, connection, NETPLAY_CONNECTION_PLAYING); + else + return true; } /** diff --git a/network/netplay/netplay_init.c b/network/netplay/netplay_init.c index e96d72178b..cf02a2d001 100644 --- a/network/netplay/netplay_init.c +++ b/network/netplay/netplay_init.c @@ -430,7 +430,7 @@ netplay_t *netplay_new(void *direct_host, const char *server, uint16_t port, netplay->crcs_valid = true; netplay->quirks = quirks; netplay->self_mode = netplay->is_server ? - NETPLAY_CONNECTION_PLAYING : + NETPLAY_CONNECTION_SPECTATING : NETPLAY_CONNECTION_NONE; if (netplay->is_server)