mirror of
https://github.com/libretro/RetroArch
synced 2025-02-28 22:13:51 +00:00
(Netplay) Show client slowdown information (#14272)
This commit is contained in:
parent
e6f3a387b2
commit
8105688a99
@ -11731,6 +11731,10 @@ MSG_HASH(
|
|||||||
MSG_NETPLAY_CHAT_SUPPORTED,
|
MSG_NETPLAY_CHAT_SUPPORTED,
|
||||||
"Chat Supported"
|
"Chat Supported"
|
||||||
)
|
)
|
||||||
|
MSG_HASH(
|
||||||
|
MSG_NETPLAY_SLOWDOWNS_CAUSED,
|
||||||
|
"Slowdowns Caused"
|
||||||
|
)
|
||||||
|
|
||||||
MSG_HASH(
|
MSG_HASH(
|
||||||
MSG_AUDIO_VOLUME,
|
MSG_AUDIO_VOLUME,
|
||||||
|
@ -1620,12 +1620,17 @@ static int action_bind_sublabel_netplay_kick_client(file_list_t *list,
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
snprintf(buf, sizeof(buf), "%s: %s",
|
snprintf(buf, sizeof(buf), "%s: %s\n",
|
||||||
msg_hash_to_str(MSG_NETPLAY_CHAT_SUPPORTED),
|
msg_hash_to_str(MSG_NETPLAY_CHAT_SUPPORTED),
|
||||||
msg_hash_to_str((client->protocol >= 6) ?
|
msg_hash_to_str((client->protocol >= 6) ?
|
||||||
MENU_ENUM_LABEL_VALUE_YES : MENU_ENUM_LABEL_VALUE_NO));
|
MENU_ENUM_LABEL_VALUE_YES : MENU_ENUM_LABEL_VALUE_NO));
|
||||||
strlcat(s, buf, len);
|
strlcat(s, buf, len);
|
||||||
|
|
||||||
|
snprintf(buf, sizeof(buf), "%s: %lu",
|
||||||
|
msg_hash_to_str(MSG_NETPLAY_SLOWDOWNS_CAUSED),
|
||||||
|
(unsigned long)client->slowdowns);
|
||||||
|
strlcat(s, buf, len);
|
||||||
|
|
||||||
if (client->ping >= 0)
|
if (client->ping >= 0)
|
||||||
{
|
{
|
||||||
snprintf(buf, sizeof(buf), "\nPing: %u ms", (unsigned)client->ping);
|
snprintf(buf, sizeof(buf), "\nPing: %u ms", (unsigned)client->ping);
|
||||||
|
@ -226,6 +226,7 @@ enum msg_hash_enums
|
|||||||
MSG_NETPLAY_STATUS_SPECTATING,
|
MSG_NETPLAY_STATUS_SPECTATING,
|
||||||
MSG_NETPLAY_CLIENT_DEVICES,
|
MSG_NETPLAY_CLIENT_DEVICES,
|
||||||
MSG_NETPLAY_CHAT_SUPPORTED,
|
MSG_NETPLAY_CHAT_SUPPORTED,
|
||||||
|
MSG_NETPLAY_SLOWDOWNS_CAUSED,
|
||||||
MSG_RESAMPLER_QUALITY_LOWEST,
|
MSG_RESAMPLER_QUALITY_LOWEST,
|
||||||
MSG_RESAMPLER_QUALITY_LOWER,
|
MSG_RESAMPLER_QUALITY_LOWER,
|
||||||
MSG_RESAMPLER_QUALITY_NORMAL,
|
MSG_RESAMPLER_QUALITY_NORMAL,
|
||||||
|
@ -154,6 +154,7 @@ typedef struct netplay_client_info
|
|||||||
{
|
{
|
||||||
uint32_t protocol;
|
uint32_t protocol;
|
||||||
uint32_t devices;
|
uint32_t devices;
|
||||||
|
uint32_t slowdowns;
|
||||||
int32_t ping;
|
int32_t ping;
|
||||||
int id;
|
int id;
|
||||||
enum rarch_netplay_connection_mode mode;
|
enum rarch_netplay_connection_mode mode;
|
||||||
|
@ -7793,225 +7793,238 @@ static bool get_self_input_state(
|
|||||||
static bool netplay_poll(netplay_t *netplay, bool block_libretro_input)
|
static bool netplay_poll(netplay_t *netplay, bool block_libretro_input)
|
||||||
{
|
{
|
||||||
size_t i;
|
size_t i;
|
||||||
int res;
|
|
||||||
uint32_t client;
|
|
||||||
|
|
||||||
if (!get_self_input_state(block_libretro_input, netplay))
|
if (!get_self_input_state(block_libretro_input, netplay))
|
||||||
goto catastrophe;
|
goto catastrophe;
|
||||||
|
|
||||||
/* If we're not connected, we're done */
|
/* If we're not connected, we're done. */
|
||||||
if (netplay->self_mode == NETPLAY_CONNECTION_NONE)
|
if (netplay->self_mode == NETPLAY_CONNECTION_NONE)
|
||||||
return true;
|
return true;
|
||||||
|
|
||||||
/* Read Netplay input, block if we're configured to stall for input every
|
|
||||||
* frame */
|
|
||||||
netplay_update_unread_ptr(netplay);
|
netplay_update_unread_ptr(netplay);
|
||||||
if (netplay->stateless_mode &&
|
|
||||||
(netplay->connected_players>1) &&
|
|
||||||
netplay->unread_frame_count <= netplay->run_frame_count)
|
|
||||||
res = netplay_poll_net_input(netplay, true);
|
|
||||||
else
|
|
||||||
res = netplay_poll_net_input(netplay, false);
|
|
||||||
if (res == -1)
|
|
||||||
goto catastrophe;
|
|
||||||
|
|
||||||
/* Resolve and/or simulate the input if we don't have real input */
|
/* Read netplay input,
|
||||||
|
block if we're configured to stall for input every frame. */
|
||||||
|
{
|
||||||
|
bool block = netplay->stateless_mode && netplay->connected_players > 1 &&
|
||||||
|
netplay->unread_frame_count <= netplay->run_frame_count;
|
||||||
|
|
||||||
|
if (netplay_poll_net_input(netplay, block) == -1)
|
||||||
|
goto catastrophe;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Resolve and/or simulate the input if we don't have real input. */
|
||||||
netplay_resolve_input(netplay, netplay->run_ptr, false);
|
netplay_resolve_input(netplay, netplay->run_ptr, false);
|
||||||
|
|
||||||
/* Handle any slaves */
|
/* Handle slaves. */
|
||||||
if (netplay->is_server && netplay->connected_slaves)
|
if (netplay->is_server && netplay->connected_slaves)
|
||||||
netplay_handle_slaves(netplay);
|
netplay_handle_slaves(netplay);
|
||||||
|
|
||||||
netplay_update_unread_ptr(netplay);
|
netplay_update_unread_ptr(netplay);
|
||||||
|
|
||||||
/* Figure out how many frames of input latency we should be using to hide
|
/* Figure out how many frames of input latency we should be using to
|
||||||
* network latency */
|
hide network latency. */
|
||||||
if (netplay->frame_run_time_avg || netplay->stateless_mode)
|
if (netplay->stateless_mode)
|
||||||
|
{
|
||||||
|
int input_latency_frames_min = (int)netplay->input_latency_frames_min;
|
||||||
|
int input_latency_frames_max = (int)netplay->input_latency_frames_max;
|
||||||
|
|
||||||
|
/* In stateless mode, we adjust up if we're "close"
|
||||||
|
and down if we have a lot of slack. */
|
||||||
|
if (netplay->input_latency_frames < input_latency_frames_min ||
|
||||||
|
(netplay->unread_frame_count == (netplay->run_frame_count + 1) &&
|
||||||
|
netplay->input_latency_frames < input_latency_frames_max))
|
||||||
|
netplay->input_latency_frames++;
|
||||||
|
else if (netplay->input_latency_frames > input_latency_frames_max ||
|
||||||
|
(netplay->unread_frame_count > (netplay->run_frame_count + 2) &&
|
||||||
|
netplay->input_latency_frames > input_latency_frames_min))
|
||||||
|
netplay->input_latency_frames--;
|
||||||
|
}
|
||||||
|
else if (netplay->frame_run_time_avg)
|
||||||
{
|
{
|
||||||
/* FIXME: Using fixed 60fps for this calculation */
|
/* FIXME: Using fixed 60fps for this calculation */
|
||||||
unsigned frames_per_frame = netplay->frame_run_time_avg ?
|
unsigned frames_per_frame = netplay->frame_run_time_avg ?
|
||||||
(16666 / netplay->frame_run_time_avg) :
|
(unsigned)(16666 / netplay->frame_run_time_avg) : 0;
|
||||||
0;
|
unsigned frames_ahead =
|
||||||
unsigned frames_ahead = (netplay->run_frame_count > netplay->unread_frame_count) ?
|
(netplay->run_frame_count > netplay->unread_frame_count) ?
|
||||||
(netplay->run_frame_count - netplay->unread_frame_count) :
|
(unsigned)(netplay->run_frame_count - netplay->unread_frame_count)
|
||||||
0;
|
: 0;
|
||||||
int input_latency_frames_min = netplay->input_latency_frames_min;
|
int input_latency_frames_min = (int)netplay->input_latency_frames_min;
|
||||||
int input_latency_frames_max = netplay->input_latency_frames_max;
|
int input_latency_frames_max = (int)netplay->input_latency_frames_max;
|
||||||
|
|
||||||
/* Assume we need a couple frames worth of time to actually run the
|
/* Assume we need a couple frames worth of time
|
||||||
* current frame */
|
to actually run the current frame. */
|
||||||
if (frames_per_frame > 2)
|
if (frames_per_frame > 2)
|
||||||
frames_per_frame -= 2;
|
frames_per_frame -= 2;
|
||||||
else
|
else
|
||||||
frames_per_frame = 0;
|
frames_per_frame = 0;
|
||||||
|
|
||||||
/* Shall we adjust our latency? */
|
/* We can't hide this much network latency with replay,
|
||||||
if (netplay->stateless_mode)
|
so hide some with input latency. */
|
||||||
{
|
if (netplay->input_latency_frames < input_latency_frames_min ||
|
||||||
/* In stateless mode, we adjust up if we're "close" and down if we
|
(frames_per_frame < frames_ahead &&
|
||||||
* have a lot of slack */
|
netplay->input_latency_frames < input_latency_frames_max))
|
||||||
if (netplay->input_latency_frames < input_latency_frames_min ||
|
|
||||||
(netplay->unread_frame_count == netplay->run_frame_count + 1 &&
|
|
||||||
netplay->input_latency_frames < input_latency_frames_max))
|
|
||||||
netplay->input_latency_frames++;
|
|
||||||
else if (netplay->input_latency_frames > input_latency_frames_max ||
|
|
||||||
(netplay->unread_frame_count > netplay->run_frame_count + 2 &&
|
|
||||||
netplay->input_latency_frames > input_latency_frames_min))
|
|
||||||
netplay->input_latency_frames--;
|
|
||||||
}
|
|
||||||
else if (netplay->input_latency_frames < input_latency_frames_min ||
|
|
||||||
(frames_per_frame < frames_ahead &&
|
|
||||||
netplay->input_latency_frames < input_latency_frames_max))
|
|
||||||
{
|
|
||||||
/* We can't hide this much network latency with replay, so hide some
|
|
||||||
* with input latency */
|
|
||||||
netplay->input_latency_frames++;
|
netplay->input_latency_frames++;
|
||||||
}
|
/* We don't need this much latency (any more). */
|
||||||
else if (netplay->input_latency_frames > input_latency_frames_max ||
|
else if (netplay->input_latency_frames > input_latency_frames_max ||
|
||||||
(frames_per_frame > frames_ahead + 2 &&
|
(frames_per_frame > (frames_ahead + 2) &&
|
||||||
netplay->input_latency_frames > input_latency_frames_min))
|
netplay->input_latency_frames > input_latency_frames_min))
|
||||||
{
|
|
||||||
/* We don't need this much latency (any more) */
|
|
||||||
netplay->input_latency_frames--;
|
netplay->input_latency_frames--;
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/* If we're stalled, consider unstalling */
|
/* If we're stalled, consider unstalling. */
|
||||||
switch (netplay->stall)
|
switch (netplay->stall)
|
||||||
{
|
{
|
||||||
case NETPLAY_STALL_RUNNING_FAST:
|
case NETPLAY_STALL_RUNNING_FAST:
|
||||||
if (netplay->unread_frame_count + NETPLAY_MAX_STALL_FRAMES - 2
|
if ((netplay->unread_frame_count + NETPLAY_MAX_STALL_FRAMES - 2) >
|
||||||
> netplay->self_frame_count)
|
netplay->self_frame_count)
|
||||||
{
|
{
|
||||||
netplay->stall = NETPLAY_STALL_NONE;
|
struct netplay_connection *connection;
|
||||||
|
|
||||||
for (i = 0; i < netplay->connections_size; i++)
|
for (i = 0; i < netplay->connections_size; i++)
|
||||||
{
|
{
|
||||||
struct netplay_connection *connection = &netplay->connections[i];
|
connection = &netplay->connections[i];
|
||||||
if (connection->active && connection->stall)
|
if (connection->active)
|
||||||
connection->stall = NETPLAY_STALL_NONE;
|
connection->stall = NETPLAY_STALL_NONE;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
netplay->stall = NETPLAY_STALL_NONE;
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case NETPLAY_STALL_SPECTATOR_WAIT:
|
case NETPLAY_STALL_SPECTATOR_WAIT:
|
||||||
if (netplay->self_mode == NETPLAY_CONNECTION_PLAYING || netplay->unread_frame_count > netplay->self_frame_count)
|
if (netplay->self_mode == NETPLAY_CONNECTION_PLAYING ||
|
||||||
|
netplay->unread_frame_count > netplay->self_frame_count)
|
||||||
netplay->stall = NETPLAY_STALL_NONE;
|
netplay->stall = NETPLAY_STALL_NONE;
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case NETPLAY_STALL_INPUT_LATENCY:
|
case NETPLAY_STALL_INPUT_LATENCY:
|
||||||
/* Just let it recalculate momentarily */
|
/* Just let it recalculate momentarily. */
|
||||||
netplay->stall = NETPLAY_STALL_NONE;
|
netplay->stall = NETPLAY_STALL_NONE;
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case NETPLAY_STALL_SERVER_REQUESTED:
|
case NETPLAY_STALL_SERVER_REQUESTED:
|
||||||
/* See if the stall is done */
|
|
||||||
if (netplay->connections[0].stall_frame == 0)
|
|
||||||
{
|
{
|
||||||
/* Stop stalling! */
|
struct netplay_connection *connection = &netplay->connections[0];
|
||||||
netplay->connections[0].stall = NETPLAY_STALL_NONE;
|
|
||||||
netplay->stall = NETPLAY_STALL_NONE;
|
/* See if the stall is done. */
|
||||||
|
if (!connection->stall_frame)
|
||||||
|
{
|
||||||
|
/* Stop stalling! */
|
||||||
|
connection->stall = NETPLAY_STALL_NONE;
|
||||||
|
netplay->stall = NETPLAY_STALL_NONE;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
connection->stall_frame--;
|
||||||
}
|
}
|
||||||
else
|
|
||||||
netplay->connections[0].stall_frame--;
|
|
||||||
break;
|
break;
|
||||||
case NETPLAY_STALL_NO_CONNECTION:
|
case NETPLAY_STALL_NO_CONNECTION:
|
||||||
/* We certainly haven't fixed this */
|
/* We certainly haven't fixed this. */
|
||||||
break;
|
break;
|
||||||
default: /* not stalling */
|
default:
|
||||||
|
/* Not stalling. */
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* If we're not stalled, consider stalling */
|
/* If we're not stalled, consider stalling. */
|
||||||
if (!netplay->stall)
|
if (netplay->stall == NETPLAY_STALL_NONE)
|
||||||
{
|
{
|
||||||
/* Have we not read enough latency frames? */
|
switch (netplay->self_mode)
|
||||||
if (netplay->self_mode == NETPLAY_CONNECTION_PLAYING &&
|
|
||||||
netplay->connected_players &&
|
|
||||||
netplay->run_frame_count + netplay->input_latency_frames > netplay->self_frame_count)
|
|
||||||
{
|
{
|
||||||
netplay->stall = NETPLAY_STALL_INPUT_LATENCY;
|
case NETPLAY_CONNECTION_SPECTATING:
|
||||||
netplay->stall_time = 0;
|
case NETPLAY_CONNECTION_SLAVE:
|
||||||
|
/* If we're a spectator, are we ahead at all? */
|
||||||
|
if (!netplay->is_server &&
|
||||||
|
netplay->unread_frame_count <= netplay->self_frame_count)
|
||||||
|
{
|
||||||
|
netplay->stall = NETPLAY_STALL_SPECTATOR_WAIT;
|
||||||
|
netplay->stall_time = cpu_features_get_time_usec();
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case NETPLAY_CONNECTION_PLAYING:
|
||||||
|
/* Have we not read enough latency frames? */
|
||||||
|
if (netplay->connected_players &&
|
||||||
|
(netplay->run_frame_count + netplay->input_latency_frames) >
|
||||||
|
netplay->self_frame_count)
|
||||||
|
{
|
||||||
|
netplay->stall = NETPLAY_STALL_INPUT_LATENCY;
|
||||||
|
netplay->stall_time = 0;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Are we too far ahead? */
|
/* Are we too far ahead? */
|
||||||
if (netplay->unread_frame_count + NETPLAY_MAX_STALL_FRAMES
|
if (netplay->stall == NETPLAY_STALL_NONE &&
|
||||||
<= netplay->self_frame_count)
|
netplay->self_frame_count > NETPLAY_MAX_STALL_FRAMES)
|
||||||
{
|
{
|
||||||
netplay->stall = NETPLAY_STALL_RUNNING_FAST;
|
uint32_t min_frame_count = netplay->self_frame_count -
|
||||||
netplay->stall_time = cpu_features_get_time_usec();
|
NETPLAY_MAX_STALL_FRAMES;
|
||||||
|
|
||||||
/* Figure out who to blame */
|
if (netplay->unread_frame_count <= min_frame_count)
|
||||||
if (netplay->is_server)
|
|
||||||
{
|
{
|
||||||
for (client = 1; client < MAX_CLIENTS; client++)
|
netplay->stall = NETPLAY_STALL_RUNNING_FAST;
|
||||||
|
netplay->stall_time = cpu_features_get_time_usec();
|
||||||
|
|
||||||
|
/* Figure out who to blame. */
|
||||||
|
if (netplay->is_server)
|
||||||
{
|
{
|
||||||
struct netplay_connection *connection;
|
struct netplay_connection *connection;
|
||||||
if (!(netplay->connected_players & (1 << client)))
|
|
||||||
continue;
|
for (i = 0; i < netplay->connections_size; i++)
|
||||||
if (netplay->read_frame_count[client] > netplay->unread_frame_count)
|
|
||||||
continue;
|
|
||||||
connection = &netplay->connections[client-1];
|
|
||||||
if (connection->active &&
|
|
||||||
connection->mode == NETPLAY_CONNECTION_PLAYING)
|
|
||||||
{
|
{
|
||||||
connection->stall = NETPLAY_STALL_RUNNING_FAST;
|
connection = &netplay->connections[i];
|
||||||
connection->stall_time = netplay->stall_time;
|
if (!connection->active ||
|
||||||
|
connection->mode != NETPLAY_CONNECTION_PLAYING)
|
||||||
|
continue;
|
||||||
|
if (netplay->read_frame_count[i + 1] < min_frame_count)
|
||||||
|
{
|
||||||
|
connection->stall = NETPLAY_STALL_RUNNING_FAST;
|
||||||
|
connection->stall_slow++;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
/* If we're a spectator, are we ahead at all? */
|
|
||||||
if (!netplay->is_server &&
|
|
||||||
(netplay->self_mode == NETPLAY_CONNECTION_SPECTATING ||
|
|
||||||
netplay->self_mode == NETPLAY_CONNECTION_SLAVE) &&
|
|
||||||
netplay->unread_frame_count <= netplay->self_frame_count)
|
|
||||||
{
|
|
||||||
netplay->stall = NETPLAY_STALL_SPECTATOR_WAIT;
|
|
||||||
netplay->stall_time = cpu_features_get_time_usec();
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/* If we're stalling, consider disconnection */
|
/* If we're stalling, consider disconnection. */
|
||||||
if (netplay->stall && netplay->stall_time)
|
if (netplay->stall != NETPLAY_STALL_NONE && netplay->stall_time)
|
||||||
{
|
{
|
||||||
retro_time_t now = cpu_features_get_time_usec();
|
retro_time_t now = cpu_features_get_time_usec();
|
||||||
|
|
||||||
/* Don't stall out while they're paused */
|
if (!netplay->remote_paused)
|
||||||
if (netplay->remote_paused)
|
|
||||||
netplay->stall_time = now;
|
|
||||||
else if (now - netplay->stall_time >=
|
|
||||||
(netplay->is_server ? MAX_SERVER_STALL_TIME_USEC :
|
|
||||||
MAX_CLIENT_STALL_TIME_USEC))
|
|
||||||
{
|
{
|
||||||
/* Stalled out! */
|
retro_time_t delta = now - netplay->stall_time;
|
||||||
|
|
||||||
if (netplay->is_server)
|
if (netplay->is_server)
|
||||||
{
|
{
|
||||||
bool fixed = false;
|
if (delta >= MAX_SERVER_STALL_TIME_USEC)
|
||||||
for (i = 0; i < netplay->connections_size; i++)
|
|
||||||
{
|
{
|
||||||
struct netplay_connection *connection = &netplay->connections[i];
|
/* Stalled out! */
|
||||||
if (connection->active &&
|
struct netplay_connection *connection;
|
||||||
connection->mode == NETPLAY_CONNECTION_PLAYING &&
|
|
||||||
connection->stall)
|
for (i = 0; i < netplay->connections_size; i++)
|
||||||
{
|
{
|
||||||
netplay_hangup(netplay, connection);
|
connection = &netplay->connections[i];
|
||||||
fixed = true;
|
if (!connection->active ||
|
||||||
}
|
connection->mode != NETPLAY_CONNECTION_PLAYING)
|
||||||
}
|
continue;
|
||||||
|
if (connection->stall != NETPLAY_STALL_NONE)
|
||||||
|
netplay_hangup(netplay, connection);
|
||||||
|
}
|
||||||
|
|
||||||
if (fixed)
|
|
||||||
{
|
|
||||||
/* Not stalled now :) */
|
|
||||||
netplay->stall = NETPLAY_STALL_NONE;
|
netplay->stall = NETPLAY_STALL_NONE;
|
||||||
return true;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
goto catastrophe;
|
{
|
||||||
return false;
|
if (delta >= MAX_CLIENT_STALL_TIME_USEC)
|
||||||
|
/* Stalled out! */
|
||||||
|
goto catastrophe;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
else
|
||||||
|
/* Don't stall out while they're paused. */
|
||||||
|
netplay->stall_time = now;
|
||||||
}
|
}
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
@ -8019,6 +8032,7 @@ static bool netplay_poll(netplay_t *netplay, bool block_libretro_input)
|
|||||||
catastrophe:
|
catastrophe:
|
||||||
for (i = 0; i < netplay->connections_size; i++)
|
for (i = 0; i < netplay->connections_size; i++)
|
||||||
netplay_hangup(netplay, &netplay->connections[i]);
|
netplay_hangup(netplay, &netplay->connections[i]);
|
||||||
|
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -8818,11 +8832,12 @@ static size_t retrieve_client_info(netplay_t *netplay, netplay_client_info_t *bu
|
|||||||
{
|
{
|
||||||
netplay_client_info_t *info = &buf[j++];
|
netplay_client_info_t *info = &buf[j++];
|
||||||
|
|
||||||
info->id = (int)i;
|
info->id = (int)i;
|
||||||
info->protocol = connection->netplay_protocol;
|
info->protocol = connection->netplay_protocol;
|
||||||
info->mode = connection->mode;
|
info->mode = connection->mode;
|
||||||
info->ping = connection->ping;
|
info->ping = connection->ping;
|
||||||
info->devices = netplay->client_devices[i + 1];
|
info->slowdowns = connection->stall_slow;
|
||||||
|
info->devices = netplay->client_devices[i + 1];
|
||||||
strlcpy(info->name, connection->nick, sizeof(info->name));
|
strlcpy(info->name, connection->nick, sizeof(info->name));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -365,9 +365,6 @@ typedef struct netplay_address
|
|||||||
/* Each connection gets a connection struct */
|
/* Each connection gets a connection struct */
|
||||||
struct netplay_connection
|
struct netplay_connection
|
||||||
{
|
{
|
||||||
/* Is this connection stalling? */
|
|
||||||
retro_time_t stall_time;
|
|
||||||
|
|
||||||
/* Timer used to estimate a connection's latency */
|
/* Timer used to estimate a connection's latency */
|
||||||
retro_time_t ping_timer;
|
retro_time_t ping_timer;
|
||||||
|
|
||||||
@ -399,6 +396,10 @@ struct netplay_connection
|
|||||||
* For the client: How many frames of stall do we have left? */
|
* For the client: How many frames of stall do we have left? */
|
||||||
uint32_t stall_frame;
|
uint32_t stall_frame;
|
||||||
|
|
||||||
|
/* How many times has this connection caused a stall because it's running
|
||||||
|
too slow? */
|
||||||
|
uint32_t stall_slow;
|
||||||
|
|
||||||
/* What latency is this connection running on?
|
/* What latency is this connection running on?
|
||||||
* Network latency has limited precision as we estimate it
|
* Network latency has limited precision as we estimate it
|
||||||
* once every pre-frame. */
|
* once every pre-frame. */
|
||||||
|
Loading…
x
Reference in New Issue
Block a user