mirror of
https://github.com/libretro/RetroArch
synced 2025-01-30 12:32:52 +00:00
Support for keyboards over netplay.
This commit is contained in:
parent
c01a199493
commit
a96eb24247
@ -1508,6 +1508,7 @@ ifeq ($(HAVE_NETWORKING), 1)
|
||||
network/netplay/netplay_handshake.o \
|
||||
network/netplay/netplay_init.o \
|
||||
network/netplay/netplay_io.o \
|
||||
network/netplay/netplay_keyboard.o \
|
||||
network/netplay/netplay_sync.o \
|
||||
network/netplay/netplay_discovery.o \
|
||||
network/netplay/netplay_buf.o \
|
||||
|
@ -1029,6 +1029,7 @@ NETPLAY
|
||||
#include "../network/netplay/netplay_handshake.c"
|
||||
#include "../network/netplay/netplay_init.c"
|
||||
#include "../network/netplay/netplay_io.c"
|
||||
#include "../network/netplay/netplay_keyboard.c"
|
||||
#include "../network/netplay/netplay_sync.c"
|
||||
#include "../network/netplay/netplay_discovery.c"
|
||||
#include "../network/netplay/netplay_buf.c"
|
||||
|
@ -379,6 +379,9 @@ MOUSE
|
||||
X: int16
|
||||
}
|
||||
|
||||
KEYBOARD
|
||||
(5 words, see netplay_keys.h)
|
||||
|
||||
LIGHTGUN
|
||||
{
|
||||
unused, unused, Trigger, Cursor, Turbo, Pause, Start
|
||||
|
@ -179,6 +179,7 @@ uint32_t netplay_expected_input_size(netplay_t *netplay, uint32_t devices)
|
||||
* fixed size, documented in network/netplay/README */
|
||||
case RETRO_DEVICE_JOYPAD: ret += 1; break;
|
||||
case RETRO_DEVICE_MOUSE: ret += 2; break;
|
||||
case RETRO_DEVICE_KEYBOARD: ret += 5; break;
|
||||
case RETRO_DEVICE_LIGHTGUN: ret += 2; break;
|
||||
case RETRO_DEVICE_ANALOG: ret += 3; break;
|
||||
default: break; /* Unsupported */
|
||||
|
@ -201,6 +201,26 @@ static bool get_self_input_state(netplay_t *netplay)
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
case RETRO_DEVICE_KEYBOARD:
|
||||
{
|
||||
unsigned key, word = 0, bit = 1;
|
||||
for (key = 1; key < NETPLAY_KEY_LAST; key++)
|
||||
{
|
||||
state[word] |=
|
||||
cb(local_device, RETRO_DEVICE_KEYBOARD, 0, netplay_key_ntoh(key)) ?
|
||||
(1U << bit) : 0;
|
||||
bit++;
|
||||
if (bit >= 32)
|
||||
{
|
||||
bit = 0;
|
||||
word++;
|
||||
if (word >= istate->size)
|
||||
break;
|
||||
}
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -536,7 +556,8 @@ static int16_t netplay_input_state(netplay_t *netplay,
|
||||
return 0;
|
||||
|
||||
/* If the port doesn't seem to correspond to the device, "correct" it. This
|
||||
* is common with e.g. zappers. */
|
||||
* is common with devices that typically only have one instance, such as
|
||||
* keyboards, mice and lightguns. */
|
||||
if (device != RETRO_DEVICE_JOYPAD &&
|
||||
(netplay->config_devices[port]&RETRO_DEVICE_MASK) != device)
|
||||
{
|
||||
@ -582,6 +603,19 @@ static int16_t netplay_input_state(netplay_t *netplay,
|
||||
return ((1 << id) & curr_input_state[0]) ? 1 : 0;
|
||||
}
|
||||
|
||||
case RETRO_DEVICE_KEYBOARD:
|
||||
{
|
||||
unsigned key, word, bit;
|
||||
key = netplay_key_hton(id);
|
||||
if (key == NETPLAY_KEY_UNKNOWN)
|
||||
return 0;
|
||||
word = key/32;
|
||||
bit = key%32;
|
||||
if (word <= istate->size)
|
||||
return ((1U<<bit) & curr_input_state[word]) ? 1 : 0;
|
||||
return 0;
|
||||
}
|
||||
|
||||
default:
|
||||
return 0;
|
||||
}
|
||||
|
@ -1022,6 +1022,8 @@ bool netplay_handshake_pre_sync(netplay_t *netplay,
|
||||
pad.port = (unsigned)i;
|
||||
pad.device = ntohl(device);
|
||||
netplay->config_devices[i] = pad.device;
|
||||
if ((pad.device&RETRO_DEVICE_MASK) == RETRO_DEVICE_KEYBOARD)
|
||||
netplay_key_hton_init();
|
||||
|
||||
core_set_controller_port_device(&pad);
|
||||
}
|
||||
|
@ -475,6 +475,8 @@ 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_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);
|
||||
}
|
||||
|
53
network/netplay/netplay_keyboard.c
Normal file
53
network/netplay/netplay_keyboard.c
Normal file
@ -0,0 +1,53 @@
|
||||
/* RetroArch - A frontend for libretro.
|
||||
* Copyright (C) 2017 - Gregor Richards
|
||||
*
|
||||
* RetroArch is free software: you can redistribute it and/or modify it under the terms
|
||||
* of the GNU General Public License as published by the Free Software Found-
|
||||
* ation, either version 3 of the License, or (at your option) any later version.
|
||||
*
|
||||
* RetroArch is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY;
|
||||
* without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
|
||||
* PURPOSE. See the GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License along with RetroArch.
|
||||
* If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#include <stdio.h>
|
||||
|
||||
#include "netplay_private.h"
|
||||
|
||||
/* The mapping of keys from netplay (network) to libretro (host) */
|
||||
const uint16_t netplay_key_ntoh_mapping[] = {
|
||||
(uint16_t) RETROK_UNKNOWN,
|
||||
#define K(k) (uint16_t) RETROK_ ## k,
|
||||
#define KL(k,l) (uint16_t) l,
|
||||
#include "netplay_keys.h"
|
||||
#undef KL
|
||||
#undef K
|
||||
0
|
||||
};
|
||||
|
||||
static bool mapping_defined = false;
|
||||
static uint16_t mapping[RETROK_LAST];
|
||||
|
||||
/* The mapping of keys from libretro (host) to netplay (network) */
|
||||
uint32_t netplay_key_hton(unsigned key)
|
||||
{
|
||||
if (key >= RETROK_LAST)
|
||||
return NETPLAY_KEY_UNKNOWN;
|
||||
return mapping[key];
|
||||
}
|
||||
|
||||
/* Because the hton keymapping has to be generated, call this before using
|
||||
* netplay_key_hton */
|
||||
void netplay_key_hton_init(void)
|
||||
{
|
||||
if (!mapping_defined)
|
||||
{
|
||||
uint16_t i;
|
||||
for (i = 0; i < NETPLAY_KEY_LAST; i++)
|
||||
mapping[netplay_key_ntoh(i)] = i;
|
||||
mapping_defined = true;
|
||||
}
|
||||
}
|
169
network/netplay/netplay_keys.h
Normal file
169
network/netplay/netplay_keys.h
Normal file
@ -0,0 +1,169 @@
|
||||
/* RetroArch - A frontend for libretro.
|
||||
* Copyright (C) 2016-2017 - Gregor Richards
|
||||
*
|
||||
* RetroArch is free software: you can redistribute it and/or modify it under the terms
|
||||
* of the GNU General Public License as published by the Free Software Found-
|
||||
* ation, either version 3 of the License, or (at your option) any later version.
|
||||
*
|
||||
* RetroArch is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY;
|
||||
* without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
|
||||
* PURPOSE. See the GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License along with RetroArch.
|
||||
* If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
/* This is an X-include file which defines the mapping of keycodes used by
|
||||
* libretro to keycodes used by RetroArch Netplay. The keycodes are different
|
||||
* because the keycodes supported by libretro are in discontiguous blocks,
|
||||
* which would create gaps in the input data, requiring more space and more
|
||||
* network bandwidth to represent them.
|
||||
*
|
||||
* If you want to add a new keycode, make sure you add it to the END. The order
|
||||
* that the keys appear in this file defines their indices in the netplay
|
||||
* protocol, so adding a key in the middle will break backwards compatibility.
|
||||
* If you want to clean up the order and thereby break backwards compatibility,
|
||||
* make sure you bump the protocol version in netplay_private.h.
|
||||
*/
|
||||
|
||||
K(BACKSPACE)
|
||||
K(TAB)
|
||||
KL(LINEFEED, 10)
|
||||
K(CLEAR)
|
||||
K(RETURN)
|
||||
K(PAUSE)
|
||||
K(ESCAPE)
|
||||
K(SPACE)
|
||||
K(EXCLAIM)
|
||||
K(QUOTEDBL)
|
||||
K(HASH)
|
||||
K(DOLLAR)
|
||||
K(AMPERSAND)
|
||||
K(QUOTE)
|
||||
K(LEFTPAREN)
|
||||
K(RIGHTPAREN)
|
||||
K(ASTERISK)
|
||||
K(PLUS)
|
||||
K(COMMA)
|
||||
K(MINUS)
|
||||
K(PERIOD)
|
||||
K(SLASH)
|
||||
K(0)
|
||||
K(1)
|
||||
K(2)
|
||||
K(3)
|
||||
K(4)
|
||||
K(5)
|
||||
K(6)
|
||||
K(7)
|
||||
K(8)
|
||||
K(9)
|
||||
K(COLON)
|
||||
K(SEMICOLON)
|
||||
K(LESS)
|
||||
K(EQUALS)
|
||||
K(GREATER)
|
||||
K(QUESTION)
|
||||
K(AT)
|
||||
K(LEFTBRACKET)
|
||||
K(BACKSLASH)
|
||||
K(RIGHTBRACKET)
|
||||
K(CARET)
|
||||
K(UNDERSCORE)
|
||||
K(BACKQUOTE)
|
||||
K(a)
|
||||
K(b)
|
||||
K(c)
|
||||
K(d)
|
||||
K(e)
|
||||
K(f)
|
||||
K(g)
|
||||
K(h)
|
||||
K(i)
|
||||
K(j)
|
||||
K(k)
|
||||
K(l)
|
||||
K(m)
|
||||
K(n)
|
||||
K(o)
|
||||
K(p)
|
||||
K(q)
|
||||
K(r)
|
||||
K(s)
|
||||
K(t)
|
||||
K(u)
|
||||
K(v)
|
||||
K(w)
|
||||
K(x)
|
||||
K(y)
|
||||
K(z)
|
||||
K(DELETE)
|
||||
|
||||
K(KP0)
|
||||
K(KP1)
|
||||
K(KP2)
|
||||
K(KP3)
|
||||
K(KP4)
|
||||
K(KP5)
|
||||
K(KP6)
|
||||
K(KP7)
|
||||
K(KP8)
|
||||
K(KP9)
|
||||
K(KP_PERIOD)
|
||||
K(KP_DIVIDE)
|
||||
K(KP_MULTIPLY)
|
||||
K(KP_MINUS)
|
||||
K(KP_PLUS)
|
||||
K(KP_ENTER)
|
||||
K(KP_EQUALS)
|
||||
|
||||
K(UP)
|
||||
K(DOWN)
|
||||
K(RIGHT)
|
||||
K(LEFT)
|
||||
K(INSERT)
|
||||
K(HOME)
|
||||
K(END)
|
||||
K(PAGEUP)
|
||||
K(PAGEDOWN)
|
||||
|
||||
K(F1)
|
||||
K(F2)
|
||||
K(F3)
|
||||
K(F4)
|
||||
K(F5)
|
||||
K(F6)
|
||||
K(F7)
|
||||
K(F8)
|
||||
K(F9)
|
||||
K(F10)
|
||||
K(F11)
|
||||
K(F12)
|
||||
K(F13)
|
||||
K(F14)
|
||||
K(F15)
|
||||
|
||||
K(NUMLOCK)
|
||||
K(CAPSLOCK)
|
||||
K(SCROLLOCK)
|
||||
K(RSHIFT)
|
||||
K(LSHIFT)
|
||||
K(RCTRL)
|
||||
K(LCTRL)
|
||||
K(RALT)
|
||||
K(LALT)
|
||||
K(RMETA)
|
||||
K(LMETA)
|
||||
K(LSUPER)
|
||||
K(RSUPER)
|
||||
K(MODE)
|
||||
K(COMPOSE)
|
||||
|
||||
K(HELP)
|
||||
K(PRINT)
|
||||
K(SYSREQ)
|
||||
K(BREAK)
|
||||
K(MENU)
|
||||
K(POWER)
|
||||
K(EURO)
|
||||
K(UNDO)
|
@ -48,10 +48,9 @@
|
||||
#define MAX_CLIENTS 32
|
||||
typedef uint32_t client_bitmap_t;
|
||||
|
||||
/* For now we only support the normal or analog gamepad */
|
||||
#define NETPLAY_SUPPORTED_DEVICES ( \
|
||||
(1<<RETRO_DEVICE_JOYPAD) | \
|
||||
(1<<RETRO_DEVICE_ANALOG))
|
||||
/* Because the callback keyboard reverses some assumptions, when the keyboard
|
||||
* callbacks are in use, we assign a pseudodevice for it */
|
||||
#define RETRO_DEVICE_NETPLAY_KEYBOARD RETRO_DEVICE_SUBCLASS(RETRO_DEVICE_KEYBOARD, 65535)
|
||||
|
||||
#define NETPLAY_MAX_STALL_FRAMES 60
|
||||
#define NETPLAY_FRAME_RUN_TIME_WINDOW 120
|
||||
@ -916,6 +915,33 @@ void netplay_announce_nat_traversal(netplay_t *netplay);
|
||||
void netplay_init_nat_traversal(netplay_t *netplay);
|
||||
|
||||
|
||||
/***************************************************************
|
||||
* NETPLAY-KEYBOARD.C
|
||||
**************************************************************/
|
||||
|
||||
/* The keys supported by netplay */
|
||||
enum netplay_keys {
|
||||
NETPLAY_KEY_UNKNOWN = 0,
|
||||
#define K(k) NETPLAY_KEY_ ## k,
|
||||
#define KL(k,l) K(k)
|
||||
#include "netplay_keys.h"
|
||||
#undef KL
|
||||
#undef K
|
||||
NETPLAY_KEY_LAST
|
||||
};
|
||||
|
||||
/* The mapping of keys from netplay (network) to libretro (host) */
|
||||
extern const uint16_t netplay_key_ntoh_mapping[];
|
||||
#define netplay_key_ntoh(k) (netplay_key_ntoh_mapping[k])
|
||||
|
||||
/* The mapping of keys from libretro (host) to netplay (network) */
|
||||
uint32_t netplay_key_hton(unsigned key);
|
||||
|
||||
/* Because the hton keymapping has to be generated, call this before using
|
||||
* netplay_key_hton */
|
||||
void netplay_key_hton_init(void);
|
||||
|
||||
|
||||
/***************************************************************
|
||||
* NETPLAY-SYNC.C
|
||||
**************************************************************/
|
||||
|
@ -277,12 +277,15 @@ static void netplay_merge_analog(netplay_t *netplay,
|
||||
netplay_input_state_t resstate, struct delta_frame *simframe,
|
||||
uint32_t device, uint32_t clients, unsigned dtype)
|
||||
{
|
||||
if (dtype == RETRO_DEVICE_JOYPAD)
|
||||
/* Devices with no analog parts */
|
||||
if (dtype == RETRO_DEVICE_JOYPAD || dtype == RETRO_DEVICE_KEYBOARD)
|
||||
return;
|
||||
/* All other devices have analog */
|
||||
|
||||
/* All other devices have at least one analog word */
|
||||
merge_analog_part(netplay, resstate, simframe, device, clients, 1, 0);
|
||||
merge_analog_part(netplay, resstate, simframe, device, clients, 1, 16);
|
||||
|
||||
/* And the ANALOG device has two (two sticks) */
|
||||
if (dtype == RETRO_DEVICE_ANALOG)
|
||||
{
|
||||
merge_analog_part(netplay, resstate, simframe, device, clients, 2, 0);
|
||||
@ -432,10 +435,14 @@ bool netplay_resolve_input(netplay_t *netplay, size_t sim_ptr, bool resim)
|
||||
else
|
||||
{
|
||||
/* Merge them */
|
||||
/* NOTE: As it happens, all of our devices keep the digital data in
|
||||
* the first word, so this is fine, but it'll have to change when
|
||||
* other devices are supported. */
|
||||
static const uint32_t digital[3] = {-1, 0, 0};
|
||||
/* Most devices have all the digital parts in the first word. */
|
||||
static const uint32_t digital_common[3] = {-1, 0, 0};
|
||||
static const uint32_t digital_keyboard[5] = {-1, -1, -1, -1, -1};
|
||||
const uint32_t *digital;
|
||||
if (dtype == RETRO_DEVICE_KEYBOARD)
|
||||
digital = digital_keyboard;
|
||||
else
|
||||
digital = digital_common;
|
||||
oldresstate = netplay_input_state_for(&simframe->resolved_input[device], 1, dsize, false, false);
|
||||
if (!oldresstate)
|
||||
continue;
|
||||
|
Loading…
x
Reference in New Issue
Block a user