mirror of
https://github.com/libretro/RetroArch
synced 2025-04-01 04:20:27 +00:00
Rather than stalling by blocking and becoming unresponsive, stall by
replaying the same frame. TODO: Maybe mute the audio?
This commit is contained in:
parent
5edfbeafb0
commit
4f16a19f5e
@ -149,6 +149,13 @@ static bool get_self_input_state(netplay_t *netplay)
|
|||||||
if (!netplay_delta_frame_ready(netplay, ptr, netplay->self_frame_count))
|
if (!netplay_delta_frame_ready(netplay, ptr, netplay->self_frame_count))
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
|
if (ptr->have_local)
|
||||||
|
{
|
||||||
|
/* We've already read this frame! */
|
||||||
|
netplay->self_ptr = NEXT_PTR(netplay->self_ptr);
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
if (!input_driver_is_libretro_input_blocked() && netplay->self_frame_count > 0)
|
if (!input_driver_is_libretro_input_blocked() && netplay->self_frame_count > 0)
|
||||||
{
|
{
|
||||||
unsigned i;
|
unsigned i;
|
||||||
@ -206,6 +213,7 @@ static bool get_self_input_state(netplay_t *netplay)
|
|||||||
}
|
}
|
||||||
|
|
||||||
memcpy(ptr->self_state, state, sizeof(state));
|
memcpy(ptr->self_state, state, sizeof(state));
|
||||||
|
ptr->have_local = true;
|
||||||
netplay->self_ptr = NEXT_PTR(netplay->self_ptr);
|
netplay->self_ptr = NEXT_PTR(netplay->self_ptr);
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
@ -296,14 +304,8 @@ static bool netplay_get_cmd(netplay_t *netplay)
|
|||||||
|
|
||||||
if (buffer[0] != netplay->read_frame_count)
|
if (buffer[0] != netplay->read_frame_count)
|
||||||
{
|
{
|
||||||
/* FIXME: JUST drop it? */
|
/* FIXME: Except on the first (null) frame, this should be
|
||||||
return netplay_cmd_nak(netplay);
|
* impossible, so maybe just disconnect? */
|
||||||
}
|
|
||||||
|
|
||||||
if (!netplay_delta_frame_ready(netplay, &netplay->buffer[netplay->read_ptr], netplay->read_frame_count))
|
|
||||||
{
|
|
||||||
/* FIXME: If we're here, we're desyncing. */
|
|
||||||
netplay->must_fast_forward = true;
|
|
||||||
return netplay_cmd_nak(netplay);
|
return netplay_cmd_nak(netplay);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -313,7 +315,7 @@ static bool netplay_get_cmd(netplay_t *netplay)
|
|||||||
netplay->read_ptr = NEXT_PTR(netplay->read_ptr);
|
netplay->read_ptr = NEXT_PTR(netplay->read_ptr);
|
||||||
netplay->read_frame_count++;
|
netplay->read_frame_count++;
|
||||||
netplay->timeout_cnt = 0;
|
netplay->timeout_cnt = 0;
|
||||||
return netplay_cmd_ack(netplay);
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
case NETPLAY_CMD_FLIP_PLAYERS:
|
case NETPLAY_CMD_FLIP_PLAYERS:
|
||||||
@ -431,7 +433,7 @@ static int poll_input(netplay_t *netplay, bool block)
|
|||||||
|
|
||||||
RARCH_LOG("Network is stalling, resending packet... Count %u of %d ...\n",
|
RARCH_LOG("Network is stalling, resending packet... Count %u of %d ...\n",
|
||||||
netplay->timeout_cnt, MAX_RETRIES);
|
netplay->timeout_cnt, MAX_RETRIES);
|
||||||
} while (had_input || (block && netplay->read_frame_count < netplay->self_frame_count));
|
} while (had_input);
|
||||||
|
|
||||||
/*if (block)
|
/*if (block)
|
||||||
return -1;*/
|
return -1;*/
|
||||||
@ -537,9 +539,8 @@ static bool netplay_poll(netplay_t *netplay)
|
|||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* We might have reached the end of the buffer, where we
|
/* Read Netplay input */
|
||||||
* simply have to block. */
|
res = poll_input(netplay, 0); /* FIXME: configure stalling intervals */
|
||||||
res = poll_input(netplay, netplay->read_frame_count < netplay->self_frame_count - 10); /* FIXME: configure stalling intervals */
|
|
||||||
if (res == -1)
|
if (res == -1)
|
||||||
{
|
{
|
||||||
netplay->has_connection = false;
|
netplay->has_connection = false;
|
||||||
@ -582,6 +583,18 @@ static bool netplay_poll(netplay_t *netplay)
|
|||||||
else
|
else
|
||||||
netplay->buffer[PREV_PTR(netplay->self_ptr)].used_real = true;
|
netplay->buffer[PREV_PTR(netplay->self_ptr)].used_real = true;
|
||||||
|
|
||||||
|
/* Consider stalling */
|
||||||
|
switch (netplay->stall) {
|
||||||
|
case RARCH_NETPLAY_STALL_RUNNING_FAST:
|
||||||
|
if (netplay->read_frame_count >= netplay->self_frame_count)
|
||||||
|
netplay->stall = RARCH_NETPLAY_STALL_NONE;
|
||||||
|
break;
|
||||||
|
|
||||||
|
default: /* not stalling */
|
||||||
|
if (netplay->read_frame_count < netplay->self_frame_count - 10)
|
||||||
|
netplay->stall = RARCH_NETPLAY_STALL_RUNNING_FAST;
|
||||||
|
}
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -166,6 +166,20 @@ static void netplay_net_post_frame(netplay_t *netplay)
|
|||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
/* If we're supposed to stall, rewind */
|
||||||
|
if (netplay->stall)
|
||||||
|
{
|
||||||
|
retro_ctx_serialize_info_t serial_info;
|
||||||
|
|
||||||
|
netplay->self_ptr = PREV_PTR(netplay->self_ptr);
|
||||||
|
netplay->self_frame_count--;
|
||||||
|
|
||||||
|
serial_info.data = NULL;
|
||||||
|
serial_info.data_const = netplay->buffer[netplay->self_ptr].state;
|
||||||
|
serial_info.size = netplay->state_size;
|
||||||
|
|
||||||
|
core_unserialize(&serial_info);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
static bool netplay_net_init_buffers(netplay_t *netplay)
|
static bool netplay_net_init_buffers(netplay_t *netplay)
|
||||||
{
|
{
|
||||||
|
@ -49,8 +49,13 @@ struct delta_frame
|
|||||||
uint32_t simulated_input_state[WORDS_PER_FRAME - 1];
|
uint32_t simulated_input_state[WORDS_PER_FRAME - 1];
|
||||||
uint32_t self_state[WORDS_PER_FRAME - 1];
|
uint32_t self_state[WORDS_PER_FRAME - 1];
|
||||||
|
|
||||||
|
/* Have we read local input? */
|
||||||
bool have_local;
|
bool have_local;
|
||||||
|
|
||||||
|
/* Badly named: This is !have_real(_remote) */
|
||||||
bool is_simulated;
|
bool is_simulated;
|
||||||
|
|
||||||
|
/* Is the current state as of self_frame_count using the real data? */
|
||||||
bool used_real;
|
bool used_real;
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -60,6 +65,12 @@ struct netplay_callbacks {
|
|||||||
bool (*info_cb) (netplay_t *netplay, unsigned frames);
|
bool (*info_cb) (netplay_t *netplay, unsigned frames);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
enum rarch_netplay_stall_reasons
|
||||||
|
{
|
||||||
|
RARCH_NETPLAY_STALL_NONE = 0,
|
||||||
|
RARCH_NETPLAY_STALL_RUNNING_FAST
|
||||||
|
};
|
||||||
|
|
||||||
struct netplay
|
struct netplay
|
||||||
{
|
{
|
||||||
char nick[32];
|
char nick[32];
|
||||||
@ -131,6 +142,9 @@ struct netplay
|
|||||||
bool pause;
|
bool pause;
|
||||||
uint32_t pause_frame;
|
uint32_t pause_frame;
|
||||||
|
|
||||||
|
/* And stalling */
|
||||||
|
int stall;
|
||||||
|
|
||||||
struct netplay_callbacks* net_cbs;
|
struct netplay_callbacks* net_cbs;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
Loading…
x
Reference in New Issue
Block a user