Netplay keyboard hack for keydown/keyup support

An unfortunate hack for cores that translate the keyboard input device
into keydown/keyup events without saving that in the savestate. We
simply replay the previous frame's input before loading the rewound
frame's state, to assure that both the state and the keyup/down state
are correct.

Ideally, cores would save this as part of the state, but it's a bit
proximal and a fairly significant change for those that use it, so it's
easier to fix in netplay.
This commit is contained in:
Gregor Richards 2017-09-14 19:41:44 -04:00
parent a96eb24247
commit 50de28b1a1
4 changed files with 27 additions and 0 deletions

View File

@ -1023,7 +1023,10 @@ bool netplay_handshake_pre_sync(netplay_t *netplay,
pad.device = ntohl(device);
netplay->config_devices[i] = pad.device;
if ((pad.device&RETRO_DEVICE_MASK) == RETRO_DEVICE_KEYBOARD)
{
netplay->have_updown_device = true;
netplay_key_hton_init();
}
core_set_controller_port_device(&pad);
}

View File

@ -476,7 +476,10 @@ netplay_t *netplay_new(void *direct_host, const char *server, uint16_t port,
uint32_t dtype = input_config_get_device(i);
netplay->config_devices[i] = dtype;
if ((dtype&RETRO_DEVICE_MASK) == RETRO_DEVICE_KEYBOARD)
{
netplay->have_updown_device = true;
netplay_key_hton_init();
}
if (dtype != RETRO_DEVICE_NONE && !netplay_expected_input_size(netplay, 1<<i))
RARCH_WARN("Netplay does not support input device %u\n", i+1);
}

View File

@ -439,6 +439,13 @@ struct netplay
* menu changes, as netplay needs fixed devices. */
uint32_t config_devices[MAX_INPUT_DEVICES];
/* Set to true if we have a device that most cores translate to "up/down"
* actions, typically a keyboard. We need to keep track of this because with
* such a device, we need to "fix" the input state to the frame BEFORE a
* state load, then perform the state load, and the up/down states will
* proceed as expected */
bool have_updown_device;
struct retro_callbacks cbs;
/* TCP port (only set if serving) */

View File

@ -787,6 +787,20 @@ void netplay_sync_post_frame(netplay_t *netplay, bool stalled)
/* Replay frames. */
netplay->is_replay = true;
/* If we have a keyboard device, we replay the previous frame's input
* just to assert that the keydown/keyup events work if the core
* translates them in that way */
if (netplay->have_updown_device)
{
netplay->replay_ptr = PREV_PTR(netplay->replay_ptr);
netplay->replay_frame_count--;
autosave_lock();
core_run();
autosave_unlock();
netplay->replay_ptr = NEXT_PTR(netplay->replay_ptr);
netplay->replay_frame_count++;
}
if (netplay->quirks & NETPLAY_QUIRK_INITIALIZATION)
/* Make sure we're initialized before we start loading things */
netplay_wait_and_init_serialization(netplay);