mirror of
https://github.com/libretro/RetroArch.git
synced 2025-02-22 02:30:56 +00:00
Blind attempt at fixing analog for netplay
This commit is contained in:
parent
5b2a9ef0b3
commit
23b7bdfea6
@ -132,9 +132,9 @@ static bool send_chunk(netplay_t *netplay)
|
||||
**/
|
||||
static bool get_self_input_state(netplay_t *netplay)
|
||||
{
|
||||
uint32_t state = 0;
|
||||
struct delta_frame *ptr = &netplay->buffer[netplay->self_ptr];
|
||||
settings_t *settings = config_get_ptr();
|
||||
uint32_t state[UDP_WORDS_PER_FRAME - 1] = {0};
|
||||
struct delta_frame *ptr = &netplay->buffer[netplay->self_ptr];
|
||||
settings_t *settings = config_get_ptr();
|
||||
|
||||
if (!input_driver_ctl(RARCH_INPUT_CTL_IS_LIBRETRO_INPUT_BLOCKED, NULL) && netplay->frame_count > 0)
|
||||
{
|
||||
@ -148,22 +148,40 @@ static bool get_self_input_state(netplay_t *netplay)
|
||||
int16_t tmp = cb(settings->input.netplay_client_swap_input ?
|
||||
0 : !netplay->port,
|
||||
RETRO_DEVICE_JOYPAD, 0, i);
|
||||
state |= tmp ? 1 << i : 0;
|
||||
state[0] |= tmp ? 1 << i : 0;
|
||||
}
|
||||
|
||||
for (i = RARCH_FIRST_CUSTOM_BIND; i < RARCH_FIRST_META_KEY; i++)
|
||||
for (i = 0; i < 2; i++)
|
||||
{
|
||||
int16_t tmp = cb(settings->input.netplay_client_swap_input ?
|
||||
int16_t tmp_x = cb(settings->input.netplay_client_swap_input ?
|
||||
0 : !netplay->port,
|
||||
RETRO_DEVICE_ANALOG, 0, i);
|
||||
state |= tmp ? 1 << i : 0;
|
||||
RETRO_DEVICE_ANALOG, i, 0);
|
||||
int16_t tmp_y = cb(settings->input.netplay_client_swap_input ?
|
||||
0 : !netplay->port,
|
||||
RETRO_DEVICE_ANALOG, i, 1);
|
||||
state[1 + i] = (uint16_t)tmp_x | (((uint16_t)tmp_y) << 16);
|
||||
}
|
||||
}
|
||||
|
||||
memmove(netplay->packet_buffer, netplay->packet_buffer + 2,
|
||||
sizeof (netplay->packet_buffer) - 2 * sizeof(uint32_t));
|
||||
netplay->packet_buffer[(UDP_FRAME_PACKETS - 1) * 2] = htonl(netplay->frame_count);
|
||||
netplay->packet_buffer[(UDP_FRAME_PACKETS - 1) * 2 + 1] = htonl(state);
|
||||
/* Here we construct the payload format:
|
||||
* frame {
|
||||
* uint32_t frame_number
|
||||
* uint32_t RETRO_DEVICE_JOYPAD state (top 16 bits zero)
|
||||
* uint32_t ANALOG state[0]
|
||||
* uint32_t ANALOG state[1]
|
||||
* }
|
||||
*
|
||||
* payload {
|
||||
* ; To compat packet losses, send input in a sliding window
|
||||
* frame redundancy_frames[UDP_FRAME_PACKETS];
|
||||
* }
|
||||
*/
|
||||
memmove(netplay->packet_buffer, netplay->packet_buffer + UDP_WORDS_PER_FRAME,
|
||||
sizeof (netplay->packet_buffer) - UDP_WORDS_PER_FRAME * sizeof(uint32_t));
|
||||
netplay->packet_buffer[(UDP_FRAME_PACKETS - 1) * UDP_WORDS_PER_FRAME] = htonl(netplay->frame_count);
|
||||
netplay->packet_buffer[(UDP_FRAME_PACKETS - 1) * UDP_WORDS_PER_FRAME + 1] = htonl(state[0]);
|
||||
netplay->packet_buffer[(UDP_FRAME_PACKETS - 1) * UDP_WORDS_PER_FRAME + 2] = htonl(state[1]);
|
||||
netplay->packet_buffer[(UDP_FRAME_PACKETS - 1) * UDP_WORDS_PER_FRAME + 3] = htonl(state[2]);
|
||||
|
||||
if (!send_chunk(netplay))
|
||||
{
|
||||
@ -172,7 +190,7 @@ static bool get_self_input_state(netplay_t *netplay)
|
||||
return false;
|
||||
}
|
||||
|
||||
ptr->self_state = state;
|
||||
memcpy(ptr->self_state, state, sizeof(state));
|
||||
netplay->self_ptr = NEXT_PTR(netplay->self_ptr);
|
||||
return true;
|
||||
}
|
||||
@ -341,19 +359,21 @@ static void parse_packet(netplay_t *netplay, uint32_t *buffer, unsigned size)
|
||||
{
|
||||
unsigned i;
|
||||
|
||||
for (i = 0; i < size * 2; i++)
|
||||
for (i = 0; i < size * UDP_WORDS_PER_FRAME; i++)
|
||||
buffer[i] = ntohl(buffer[i]);
|
||||
|
||||
for (i = 0; i < size && netplay->read_frame_count <= netplay->frame_count; i++)
|
||||
{
|
||||
uint32_t frame = buffer[2 * i + 0];
|
||||
uint32_t state = buffer[2 * i + 1];
|
||||
uint32_t frame = buffer[UDP_WORDS_PER_FRAME * i + 0];
|
||||
const uint32_t *state = &buffer[UDP_WORDS_PER_FRAME * i + 1];
|
||||
|
||||
if (frame != netplay->read_frame_count)
|
||||
continue;
|
||||
|
||||
netplay->buffer[netplay->read_ptr].is_simulated = false;
|
||||
netplay->buffer[netplay->read_ptr].real_input_state = state;
|
||||
memcpy(netplay->buffer[netplay->read_ptr].real_input_state, state,
|
||||
sizeof(netplay->buffer[netplay->read_ptr].real_input_state));
|
||||
|
||||
netplay->read_ptr = NEXT_PTR(netplay->read_ptr);
|
||||
netplay->read_frame_count++;
|
||||
netplay->timeout_cnt = 0;
|
||||
@ -366,8 +386,10 @@ static void simulate_input(netplay_t *netplay)
|
||||
size_t ptr = PREV_PTR(netplay->self_ptr);
|
||||
size_t prev = PREV_PTR(netplay->read_ptr);
|
||||
|
||||
netplay->buffer[ptr].simulated_input_state =
|
||||
netplay->buffer[prev].real_input_state;
|
||||
memcpy(netplay->buffer[ptr].simulated_input_state,
|
||||
netplay->buffer[prev].real_input_state,
|
||||
sizeof(netplay->buffer[prev].real_input_state));
|
||||
|
||||
netplay->buffer[ptr].is_simulated = true;
|
||||
netplay->buffer[ptr].used_real = false;
|
||||
}
|
||||
@ -400,7 +422,7 @@ static bool netplay_poll(netplay_t *netplay)
|
||||
{
|
||||
netplay->buffer[0].used_real = true;
|
||||
netplay->buffer[0].is_simulated = false;
|
||||
netplay->buffer[0].real_input_state = 0;
|
||||
memset(netplay->buffer[0].real_input_state, 0, sizeof(netplay->buffer[0].real_input_state));
|
||||
netplay->read_ptr = NEXT_PTR(netplay->read_ptr);
|
||||
netplay->read_frame_count++;
|
||||
return true;
|
||||
@ -421,7 +443,7 @@ static bool netplay_poll(netplay_t *netplay)
|
||||
uint32_t first_read = netplay->read_frame_count;
|
||||
do
|
||||
{
|
||||
uint32_t buffer[UDP_FRAME_PACKETS * 2];
|
||||
uint32_t buffer[UDP_FRAME_PACKETS * UDP_WORDS_PER_FRAME];
|
||||
if (!receive_data(netplay, buffer, sizeof(buffer)))
|
||||
{
|
||||
warn_hangup();
|
||||
@ -515,7 +537,8 @@ static int16_t netplay_input_state(netplay_t *netplay, bool port, unsigned devic
|
||||
{
|
||||
size_t ptr = netplay->is_replay ?
|
||||
netplay->tmp_ptr : PREV_PTR(netplay->self_ptr);
|
||||
uint16_t curr_input_state = netplay->buffer[ptr].self_state;
|
||||
|
||||
const uint32_t *curr_input_state = netplay->buffer[ptr].self_state;
|
||||
|
||||
if (netplay->port == (netplay_flip_port(netplay, port) ? 1 : 0))
|
||||
{
|
||||
@ -525,7 +548,20 @@ static int16_t netplay_input_state(netplay_t *netplay, bool port, unsigned devic
|
||||
curr_input_state = netplay->buffer[ptr].real_input_state;
|
||||
}
|
||||
|
||||
return ((1 << id) & curr_input_state) ? 1 : 0;
|
||||
switch (device)
|
||||
{
|
||||
case RETRO_DEVICE_JOYPAD:
|
||||
return ((1 << id) & curr_input_state[0]) ? 1 : 0;
|
||||
|
||||
case RETRO_DEVICE_ANALOG:
|
||||
{
|
||||
uint32_t state = curr_input_state[1 + idx];
|
||||
return (int16_t)(uint16_t)(state >> (id * 16));
|
||||
}
|
||||
|
||||
default:
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
int16_t input_state_net(unsigned port, unsigned device,
|
||||
|
@ -34,6 +34,7 @@
|
||||
#endif
|
||||
|
||||
#define UDP_FRAME_PACKETS 16
|
||||
#define UDP_WORDS_PER_FRAME 4 /* Allows us to send 128 bits worth of state per frame. */
|
||||
#define MAX_SPECTATORS 16
|
||||
#define RARCH_DEFAULT_PORT 55435
|
||||
|
||||
@ -44,9 +45,9 @@ struct delta_frame
|
||||
{
|
||||
void *state;
|
||||
|
||||
uint16_t real_input_state;
|
||||
uint16_t simulated_input_state;
|
||||
uint16_t self_state;
|
||||
uint32_t real_input_state[UDP_WORDS_PER_FRAME - 1];
|
||||
uint32_t simulated_input_state[UDP_WORDS_PER_FRAME - 1];
|
||||
uint32_t self_state[UDP_WORDS_PER_FRAME - 1];
|
||||
|
||||
bool is_simulated;
|
||||
bool used_real;
|
||||
@ -95,7 +96,7 @@ struct netplay
|
||||
|
||||
/* To compat UDP packet loss we also send
|
||||
* old data along with the packets. */
|
||||
uint32_t packet_buffer[UDP_FRAME_PACKETS * 2];
|
||||
uint32_t packet_buffer[UDP_FRAME_PACKETS * UDP_WORDS_PER_FRAME];
|
||||
uint32_t frame_count;
|
||||
uint32_t read_frame_count;
|
||||
uint32_t other_frame_count;
|
||||
|
Loading…
x
Reference in New Issue
Block a user