mirror of
https://github.com/libretro/RetroArch
synced 2025-01-31 06:32:48 +00:00
Merge pull request #4266 from GregorR/netplay-better-simulation
Better netplay input simulation
This commit is contained in:
commit
d604441cea
@ -822,15 +822,47 @@ static int poll_input(netplay_t *netplay, bool block)
|
||||
* netplay_simulate_input:
|
||||
* @netplay : pointer to netplay object
|
||||
* @sim_ptr : frame index for which to simulate input
|
||||
* @resim : are we resimulating, or simulating this frame for the
|
||||
* first time?
|
||||
*
|
||||
* "Simulate" input by assuming it hasn't changed since the last read input.
|
||||
*/
|
||||
void netplay_simulate_input(netplay_t *netplay, uint32_t sim_ptr)
|
||||
void netplay_simulate_input(netplay_t *netplay, uint32_t sim_ptr, bool resim)
|
||||
{
|
||||
size_t prev = PREV_PTR(netplay->read_ptr);
|
||||
memcpy(netplay->buffer[sim_ptr].simulated_input_state,
|
||||
netplay->buffer[prev].real_input_state,
|
||||
sizeof(netplay->buffer[prev].real_input_state));
|
||||
struct delta_frame *pframe = &netplay->buffer[prev],
|
||||
*simframe = &netplay->buffer[sim_ptr];
|
||||
if (resim)
|
||||
{
|
||||
/* In resimulation mode, we only copy the buttons. The reason for this
|
||||
* is nonobvious:
|
||||
*
|
||||
* If we resimulated nothing, then the /duration/ with which any input
|
||||
* was pressed would be approximately correct, since the original
|
||||
* simulation came in as the input came in, but the /number of times/
|
||||
* the input was pressed would be wrong, as there would be an
|
||||
* advancing wavefront of real data overtaking the simulated data
|
||||
* (which is really just real data offset by some frames).
|
||||
*
|
||||
* That's acceptable for arrows in most situations, since the amount
|
||||
* you move is tied to the duration, but unacceptable for buttons,
|
||||
* which will seem to jerkily be pressed numerous times with those
|
||||
* wavefronts.
|
||||
*/
|
||||
const uint32_t keep = (1U<<RETRO_DEVICE_ID_JOYPAD_UP) |
|
||||
(1U<<RETRO_DEVICE_ID_JOYPAD_DOWN) |
|
||||
(1U<<RETRO_DEVICE_ID_JOYPAD_LEFT) |
|
||||
(1U<<RETRO_DEVICE_ID_JOYPAD_RIGHT);
|
||||
uint32_t sim_state = simframe->simulated_input_state[0] & keep;
|
||||
sim_state |= pframe->real_input_state[0] & ~keep;
|
||||
simframe->simulated_input_state[0] = sim_state;
|
||||
}
|
||||
else
|
||||
{
|
||||
memcpy(simframe->simulated_input_state,
|
||||
pframe->real_input_state,
|
||||
sizeof(pframe->real_input_state));
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@ -874,7 +906,7 @@ static bool netplay_poll(void)
|
||||
|
||||
/* Simulate the input if we don't have real input */
|
||||
if (!netplay_data->buffer[netplay_data->self_ptr].have_remote)
|
||||
netplay_simulate_input(netplay_data, netplay_data->self_ptr);
|
||||
netplay_simulate_input(netplay_data, netplay_data->self_ptr, false);
|
||||
|
||||
/* Consider stalling */
|
||||
switch (netplay_data->stall)
|
||||
|
@ -280,7 +280,7 @@ static void netplay_net_post_frame(netplay_t *netplay)
|
||||
|
||||
/* Simulate this frame's input */
|
||||
if (netplay->replay_frame_count >= netplay->read_frame_count)
|
||||
netplay_simulate_input(netplay, netplay->replay_ptr);
|
||||
netplay_simulate_input(netplay, netplay->replay_ptr, true);
|
||||
|
||||
autosave_lock();
|
||||
core_run();
|
||||
|
@ -234,7 +234,7 @@ bool netplay_init_serialization(netplay_t *netplay);
|
||||
/* Force serialization to be ready by fast-forwarding the core */
|
||||
bool netplay_wait_and_init_serialization(netplay_t *netplay);
|
||||
|
||||
void netplay_simulate_input(netplay_t *netplay, uint32_t sim_ptr);
|
||||
void netplay_simulate_input(netplay_t *netplay, uint32_t sim_ptr, bool resim);
|
||||
|
||||
void netplay_log_connection(const struct sockaddr_storage *their_addr,
|
||||
unsigned slot, const char *nick);
|
||||
|
Loading…
x
Reference in New Issue
Block a user