From abf045ef0e51d129aa1485987e5cdff1e08c98a2 Mon Sep 17 00:00:00 2001 From: Gregor Richards Date: Sun, 10 Sep 2017 21:46:18 -0400 Subject: [PATCH] Made device requests (badly) configurable. --- configuration.c | 7 ++ configuration.h | 3 + intl/msg_hash_lbl.h | 2 + intl/msg_hash_us.h | 4 + menu/menu_displaylist.c | 7 ++ menu/menu_setting.c | 29 +++++++- msg_hash.h | 3 + network/netplay/netplay.h | 22 ++++++ network/netplay/netplay_frontend.c | 2 +- network/netplay/netplay_io.c | 113 ++++++++++++++++++++--------- network/netplay/netplay_private.h | 22 ------ network/netplay/netplay_sync.c | 18 ++--- 12 files changed, 164 insertions(+), 68 deletions(-) diff --git a/configuration.c b/configuration.c index 9e7eacc246..865674ad3c 100644 --- a/configuration.c +++ b/configuration.c @@ -1146,7 +1146,9 @@ static struct config_bool_setting *populate_settings_bool(settings_t *settings, { struct config_bool_setting *tmp = (struct config_bool_setting*)malloc((*size + 1) * sizeof(struct config_bool_setting)); unsigned count = 0; + unsigned user; global_t *global = global_get_ptr(); + char cfg[64] = {0}; SETTING_BOOL("automatically_add_content_to_playlist", &settings->bools.automatically_add_content_to_playlist, true, automatically_add_content_to_playlist, false); SETTING_BOOL("ui_companion_start_on_boot", &settings->bools.ui_companion_start_on_boot, true, ui_companion_start_on_boot, false); @@ -1163,6 +1165,11 @@ static struct config_bool_setting *populate_settings_bool(settings_t *settings, SETTING_BOOL("netplay_stateless_mode", &settings->bools.netplay_stateless_mode, true, netplay_stateless_mode, false); SETTING_BOOL("netplay_client_swap_input", &settings->bools.netplay_swap_input, true, netplay_client_swap_input, false); SETTING_BOOL("netplay_use_mitm_server", &settings->bools.netplay_use_mitm_server, true, netplay_use_mitm_server, false); + for (user = 0; user < MAX_USERS; user++) + { + snprintf(cfg, sizeof(cfg)-1, "netplay_request_device_p%u", user + 1); + SETTING_BOOL(strdup(cfg), &settings->bools.netplay_request_devices[user], true, false, false); + } #endif SETTING_BOOL("input_descriptor_label_show", &settings->bools.input_descriptor_label_show, true, input_descriptor_label_show, false); SETTING_BOOL("input_descriptor_hide_unbound", &settings->bools.input_descriptor_hide_unbound, true, input_descriptor_hide_unbound, false); diff --git a/configuration.h b/configuration.h index c7697167cd..26bd4333f4 100644 --- a/configuration.h +++ b/configuration.h @@ -177,6 +177,7 @@ typedef struct settings bool netplay_swap_input; bool netplay_nat_traversal; bool netplay_use_mitm_server; + bool netplay_request_devices[MAX_USERS]; /* Network */ bool network_buildbot_auto_extract_archive; @@ -315,6 +316,8 @@ typedef struct settings unsigned netplay_port; unsigned netplay_input_latency_frames_min; unsigned netplay_input_latency_frames_range; + unsigned netplay_share_digital; + unsigned netplay_share_analog; unsigned bundle_assets_extract_version_current; unsigned bundle_assets_extract_last_version; unsigned content_history_size; diff --git a/intl/msg_hash_lbl.h b/intl/msg_hash_lbl.h index 27124e3489..292d16a9a1 100644 --- a/intl/msg_hash_lbl.h +++ b/intl/msg_hash_lbl.h @@ -627,6 +627,8 @@ MSG_HASH(MENU_ENUM_LABEL_NETPLAY_CHECK_FRAMES, "netplay_check_frames") MSG_HASH(MENU_ENUM_LABEL_NETPLAY_CLIENT_SWAP_INPUT, "netplay_client_swap_input") +MSG_HASH(MENU_ENUM_LABEL_NETPLAY_REQUEST_DEVICE_I, + "netplay_request_device_%u") MSG_HASH(MENU_ENUM_LABEL_NETPLAY_INPUT_LATENCY_FRAMES_MIN, "netplay_input_latency_frames_min") MSG_HASH(MENU_ENUM_LABEL_NETPLAY_INPUT_LATENCY_FRAMES_RANGE, diff --git a/intl/msg_hash_us.h b/intl/msg_hash_us.h index fe4d25dcf7..783811f9fa 100644 --- a/intl/msg_hash_us.h +++ b/intl/msg_hash_us.h @@ -1071,6 +1071,8 @@ MSG_HASH(MENU_ENUM_LABEL_VALUE_NETPLAY_PASSWORD, "Server Password") MSG_HASH(MENU_ENUM_LABEL_VALUE_NETPLAY_PUBLIC_ANNOUNCE, "Publicly Announce Netplay") +MSG_HASH(MENU_ENUM_LABEL_VALUE_NETPLAY_REQUEST_DEVICE_I, + "Request Device %u") MSG_HASH(MENU_ENUM_LABEL_VALUE_NETPLAY_REQUIRE_SLAVES, "Disallow Non-Slave-Mode Clients") MSG_HASH(MENU_ENUM_LABEL_VALUE_NETPLAY_SETTINGS, @@ -2877,6 +2879,8 @@ MSG_HASH(MENU_ENUM_SUBLABEL_SORT_SAVESTATES_ENABLE, ) MSG_HASH(MENU_ENUM_SUBLABEL_NETPLAY_CLIENT_SWAP_INPUT, "When being client over netplay, use keybinds for Player 1.") +MSG_HASH(MENU_ENUM_SUBLABEL_NETPLAY_REQUEST_DEVICE_I, + "Request to play with the given input device.") MSG_HASH(MENU_ENUM_SUBLABEL_CORE_UPDATER_BUILDBOT_URL, "URL to core updater directory on the Libretro buildbot.") MSG_HASH(MENU_ENUM_SUBLABEL_BUILDBOT_ASSETS_URL, diff --git a/menu/menu_displaylist.c b/menu/menu_displaylist.c index f60c74ae68..4d325f2ea7 100644 --- a/menu/menu_displaylist.c +++ b/menu/menu_displaylist.c @@ -5537,6 +5537,13 @@ bool menu_displaylist_ctl(enum menu_displaylist_ctl_state type, void *data) MENU_ENUM_LABEL_NETPLAY_CLIENT_SWAP_INPUT, PARSE_ONLY_BOOL, false) != -1) count++; + for (user = 0; user < MAX_USERS; user++) + { + if (menu_displaylist_parse_settings_enum(menu, info, + MENU_ENUM_LABEL_NETPLAY_REQUEST_DEVICE_1 + user, + PARSE_ONLY_BOOL, false) != -1) + count++; + } if (menu_displaylist_parse_settings_enum(menu, info, MENU_ENUM_LABEL_NETWORK_CMD_ENABLE, PARSE_ONLY_BOOL, false) != -1) diff --git a/menu/menu_setting.c b/menu/menu_setting.c index 7b26307956..7897d79834 100644 --- a/menu/menu_setting.c +++ b/menu/menu_setting.c @@ -6694,9 +6694,10 @@ static bool setting_append_list( { #if defined(HAVE_NETWORKING) -#if defined(HAVE_NETWORK_CMD) unsigned user; -#endif + char dev_req_label[64]; + char dev_req_value[64]; + CONFIG_BOOL( list, list_info, &settings->bools.netplay_public_announce, @@ -6920,6 +6921,30 @@ static bool setting_append_list( SD_FLAG_NONE); settings_data_list_current_add_flags(list, list_info, SD_FLAG_ADVANCED); + for (user = 0; user < MAX_USERS; user++) + { + snprintf(dev_req_label, sizeof(dev_req_label), + msg_hash_to_str(MENU_ENUM_LABEL_NETPLAY_REQUEST_DEVICE_I), user + 1); + snprintf(dev_req_value, sizeof(dev_req_value), + msg_hash_to_str(MENU_ENUM_LABEL_VALUE_NETPLAY_REQUEST_DEVICE_I), user + 1); + CONFIG_BOOL_ALT( + list, list_info, + &settings->bools.netplay_request_devices[user], + strdup(dev_req_label), + strdup(dev_req_value), + false, + MENU_ENUM_LABEL_VALUE_NO, + MENU_ENUM_LABEL_VALUE_YES, + &group_info, + &subgroup_info, + parent_group, + general_write_handler, + general_read_handler, + SD_FLAG_ADVANCED); + settings_data_list_current_add_free_flags(list, list_info, SD_FREE_FLAG_NAME | SD_FREE_FLAG_SHORT); + menu_settings_list_current_add_enum_idx(list, list_info, (enum msg_hash_enums)(MENU_ENUM_LABEL_NETPLAY_REQUEST_DEVICE_1 + user)); + } + END_SUB_GROUP(list, list_info, parent_group); START_SUB_GROUP( diff --git a/msg_hash.h b/msg_hash.h index 72a5abf080..7fcbf6e0e2 100644 --- a/msg_hash.h +++ b/msg_hash.h @@ -1169,6 +1169,9 @@ enum msg_hash_enums MENU_LABEL(NETPLAY_SPECTATOR_MODE_ENABLE), MENU_LABEL(NETPLAY_TCP_UDP_PORT), MENU_LABEL(NETPLAY_NAT_TRAVERSAL), + MENU_LABEL(NETPLAY_REQUEST_DEVICE_I), + MENU_ENUM_LABEL_NETPLAY_REQUEST_DEVICE_1, + MENU_ENUM_LABEL_NETPLAY_REQUEST_DEVICE_LAST = MENU_ENUM_LABEL_NETPLAY_REQUEST_DEVICE_1 + MAX_USERS, MENU_LABEL(SORT_SAVEFILES_ENABLE), MENU_LABEL(SORT_SAVESTATES_ENABLE), MENU_LABEL(SAVEFILES_IN_CONTENT_DIR_ENABLE), diff --git a/network/netplay/netplay.h b/network/netplay/netplay.h index b680298584..2f45ca872a 100644 --- a/network/netplay/netplay.h +++ b/network/netplay/netplay.h @@ -53,6 +53,28 @@ enum rarch_netplay_ctl_state RARCH_NETPLAY_CTL_DESYNC_POP }; +/* Preferences for sharing devices */ +enum rarch_netplay_share_preference +{ + /* Prefer not to share, shouldn't be set as a sharing mode for an shared device */ + RARCH_NETPLAY_SHARE_NO_SHARING = 0x0, + + /* No preference. Only for requests. Set if sharing is requested but either + * digital or analog doesn't have a preference. */ + RARCH_NETPLAY_SHARE_NO_PREFERENCE = 0x1, + + /* For digital devices */ + RARCH_NETPLAY_SHARE_DIGITAL_BITS = 0x1C, + RARCH_NETPLAY_SHARE_DIGITAL_OR = 0x4, + RARCH_NETPLAY_SHARE_DIGITAL_XOR = 0x8, + RARCH_NETPLAY_SHARE_DIGITAL_VOTE = 0xC, + + /* For analog devices */ + RARCH_NETPLAY_SHARE_ANALOG_BITS = 0xE0, + RARCH_NETPLAY_SHARE_ANALOG_MAX = 0x20, + RARCH_NETPLAY_SHARE_ANALOG_AVERAGE = 0x40 +}; + int16_t input_state_net(unsigned port, unsigned device, unsigned idx, unsigned id); diff --git a/network/netplay/netplay_frontend.c b/network/netplay/netplay_frontend.c index e72ac80a89..6fc2619fd6 100644 --- a/network/netplay/netplay_frontend.c +++ b/network/netplay/netplay_frontend.c @@ -1158,7 +1158,7 @@ static void netplay_toggle_play_spectate(netplay_t *netplay) else if (netplay->self_mode == NETPLAY_CONNECTION_SPECTATING) { uint32_t device; - uint8_t share_mode = NETPLAY_SHARE_DIGITAL_OR|NETPLAY_SHARE_ANALOG_MAX; + uint8_t share_mode = RARCH_NETPLAY_SHARE_DIGITAL_OR|RARCH_NETPLAY_SHARE_ANALOG_MAX; /* Take an input device */ for (device = 0; device < MAX_INPUT_DEVICES; device++) diff --git a/network/netplay/netplay_io.c b/network/netplay/netplay_io.c index a1ad814c44..504c4c775a 100644 --- a/network/netplay/netplay_io.c +++ b/network/netplay/netplay_io.c @@ -468,8 +468,9 @@ bool netplay_cmd_mode(netplay_t *netplay, struct netplay_connection *connection, enum rarch_netplay_connection_mode mode) { - uint32_t cmd; + uint32_t cmd, device; uint32_t payloadBuf = 0, *payload = NULL; + settings_t *settings = config_get_ptr(); switch (mode) { case NETPLAY_CONNECTION_SPECTATING: @@ -482,7 +483,15 @@ bool netplay_cmd_mode(netplay_t *netplay, case NETPLAY_CONNECTION_PLAYING: payload = &payloadBuf; - payloadBuf |= NETPLAY_SHARE_NO_PREFERENCE<<16; + payloadBuf |= RARCH_NETPLAY_SHARE_NO_PREFERENCE<<16; + + /* Request devices */ + for (device = 0; device < MAX_INPUT_DEVICES; device++) + { + if (settings->bools.netplay_request_devices[device]) + payloadBuf |= 1<device_clients[device]) - break; - } - if (device >= MAX_INPUT_DEVICES && share_mode) - { - /* No device was totally free, maybe one is shareable? */ + /* Make sure the devices are available and/or shareable */ for (device = 0; device < MAX_INPUT_DEVICES; device++) { - if (netplay->device_clients[device] && netplay->device_share_modes[device]) + if (!(devices & (1<device_clients[device]) continue; + if (netplay->device_share_modes[device] && share_mode) continue; + + /* Device already taken and unshareable */ + payload[0] = htonl(NETPLAY_CMD_MODE_REFUSED_REASON_NOT_AVAILABLE); + netplay_send_raw_cmd(netplay, connection, NETPLAY_CMD_MODE_REFUSED, payload, sizeof(uint32_t)); + devices = 0; + break; + } + if (devices == 0) + break; + + /* Set the share mode on any new devices */ + for (device = 0; device < MAX_INPUT_DEVICES; device++) + { + if (!(devices & (1<device_clients[device]) + netplay->device_share_modes[device] = share_mode; + } + + } + else + { + /* Find an available device */ + for (device = 0; device < MAX_INPUT_DEVICES; device++) + { + if (input_config_get_device(device) == RETRO_DEVICE_NONE) { - share_mode = netplay->device_share_modes[device]; + device = MAX_INPUT_DEVICES; break; } + if (!netplay->device_clients[device]) + break; } + if (device >= MAX_INPUT_DEVICES && share_mode) + { + /* No device was totally free, maybe one is shareable? */ + for (device = 0; device < MAX_INPUT_DEVICES; device++) + { + if (netplay->device_clients[device] && netplay->device_share_modes[device]) + { + share_mode = netplay->device_share_modes[device]; + break; + } + } + } + if (device >= MAX_INPUT_DEVICES) + { + /* No slots free! */ + payload[0] = htonl(NETPLAY_CMD_MODE_REFUSED_REASON_NO_SLOTS); + netplay_send_raw_cmd(netplay, connection, NETPLAY_CMD_MODE_REFUSED, payload, sizeof(uint32_t)); + break; + } + devices = 1<device_share_modes[device] = share_mode; + } - if (device >= MAX_INPUT_DEVICES) - { - /* No slots free! */ - payload[0] = htonl(NETPLAY_CMD_MODE_REFUSED_REASON_NO_SLOTS); - netplay_send_raw_cmd(netplay, connection, NETPLAY_CMD_MODE_REFUSED, payload, sizeof(uint32_t)); - break; - } - payload[2] = htonl(1<connected_players |= 1 << client_num; if (slave) netplay->connected_slaves |= 1 << client_num; - netplay->client_devices[client_num] |= 1 << device; - netplay->device_clients[device] |= 1 << client_num; - netplay->device_share_modes[device] = share_mode; + netplay->client_devices[client_num] = devices; + for (device = 0; device < MAX_INPUT_DEVICES; device++) + { + if (!(devices & (1<device_clients[device] |= 1 << client_num; + } /* Tell everyone */ payload[1] = htonl( diff --git a/network/netplay/netplay_private.h b/network/netplay/netplay_private.h index 0d1ffc4647..7b68520e93 100644 --- a/network/netplay/netplay_private.h +++ b/network/netplay/netplay_private.h @@ -207,28 +207,6 @@ enum netplay_cmd_mode_reasons NETPLAY_CMD_MODE_REFUSED_REASON_NOT_AVAILABLE }; -/* Preferences for sharing devices */ -enum rarch_netplay_share_preference -{ - /* Prefer not to share, shouldn't be set as a sharing mode for an shared device */ - NETPLAY_SHARE_NO_SHARING = 0x0, - - /* No preference. Only for requests. Set if sharing is requested but either - * digital or analog doesn't have a preference. */ - NETPLAY_SHARE_NO_PREFERENCE = 0x1, - - /* For digital devices */ - NETPLAY_SHARE_DIGITAL_BITS = 0x1C, - NETPLAY_SHARE_DIGITAL_OR = 0x4, - NETPLAY_SHARE_DIGITAL_XOR = 0x8, - NETPLAY_SHARE_DIGITAL_VOTE = 0xC, - - /* For analog devices */ - NETPLAY_SHARE_ANALOG_BITS = 0xE0, - NETPLAY_SHARE_ANALOG_MAX = 0x20, - NETPLAY_SHARE_ANALOG_AVERAGE = 0x40 -}; - /* The current status of a connection */ enum rarch_netplay_connection_mode { diff --git a/network/netplay/netplay_sync.c b/network/netplay/netplay_sync.c index df0e45316d..d95f445d17 100644 --- a/network/netplay/netplay_sync.c +++ b/network/netplay/netplay_sync.c @@ -124,8 +124,8 @@ static void netplay_merge_digital(netplay_t *netplay, { netplay_input_state_t simstate; uint32_t word, bit, client; - uint8_t share_mode = netplay->device_share_modes[device] & NETPLAY_SHARE_DIGITAL_BITS; - if (share_mode == NETPLAY_SHARE_DIGITAL_VOTE) + uint8_t share_mode = netplay->device_share_modes[device] & RARCH_NETPLAY_SHARE_DIGITAL_BITS; + if (share_mode == RARCH_NETPLAY_SHARE_DIGITAL_VOTE) { /* Vote mode requires counting all the bits */ uint32_t client_count = 0; @@ -178,8 +178,8 @@ static void netplay_merge_digital(netplay_t *netplay, /* Combine the whole word */ switch (share_mode) { - case NETPLAY_SHARE_DIGITAL_XOR: resstate->data[word] ^= part; break; - default: resstate->data[word] |= part; + case RARCH_NETPLAY_SHARE_DIGITAL_XOR: resstate->data[word] ^= part; break; + default: resstate->data[word] |= part; } } @@ -190,8 +190,8 @@ static void netplay_merge_digital(netplay_t *netplay, if (!(digital[word] & (1<data[word] ^= part & (1<data[word] |= part & (1<data[word] ^= part & (1<data[word] |= part & (1<device_share_modes[device] & NETPLAY_SHARE_ANALOG_BITS; + uint8_t share_mode = netplay->device_share_modes[device] & RARCH_NETPLAY_SHARE_ANALOG_BITS; int32_t value = 0, new_value; for (client = 0; client < MAX_CLIENTS; client++) @@ -229,7 +229,7 @@ static void merge_analog_part(netplay_t *netplay, new_value = (int16_t) ((simstate->data[word]>>bit) & 0xFFFF); switch (share_mode) { - case NETPLAY_SHARE_ANALOG_AVERAGE: + case RARCH_NETPLAY_SHARE_ANALOG_AVERAGE: value += (int32_t) new_value; break; default: @@ -239,7 +239,7 @@ static void merge_analog_part(netplay_t *netplay, } } - if (share_mode == NETPLAY_SHARE_ANALOG_AVERAGE) + if (share_mode == RARCH_NETPLAY_SHARE_ANALOG_AVERAGE) value /= client_count; resstate->data[word] |= ((uint32_t) (uint16_t) value) << bit;