From fe8a0657b4cb55ae5695218f86fb21536690d508 Mon Sep 17 00:00:00 2001 From: radius Date: Thu, 7 Sep 2017 22:30:42 -0500 Subject: [PATCH] add input_mapper scafolding --- Makefile.common | 4 ++ command.c | 8 ++++ command.h | 4 ++ configuration.c | 6 +++ configuration.h | 2 + griffin/griffin.c | 4 ++ input/input_driver.c | 36 ++++++++++++++++ input/input_driver.h | 4 ++ input/input_mapper.c | 96 +++++++++++++++++++++++++++++++++++++++++ input/input_mapper.h | 51 ++++++++++++++++++++++ input/input_remapping.c | 2 +- input/input_remapping.h | 1 + input/input_remote.c | 34 +++++++-------- qb/config.params.sh | 1 + retroarch.c | 2 + 15 files changed, 237 insertions(+), 18 deletions(-) create mode 100644 input/input_mapper.c create mode 100644 input/input_mapper.h diff --git a/Makefile.common b/Makefile.common index 7b0938a4c0..5fd8c21386 100644 --- a/Makefile.common +++ b/Makefile.common @@ -1441,6 +1441,10 @@ ifeq ($(HAVE_NETWORKING), 1) endif endif + ifeq ($(HAVE_KEYMAPPER), 1) + OBJ += input/input_mapper.o + endif + ifeq ($(HAVE_NETWORKGAMEPAD), 1) OBJ += input/input_remote.o \ cores/libretro-net-retropad/net_retropad_core.o diff --git a/command.c b/command.c index 89997e8b23..7712b51ebd 100644 --- a/command.c +++ b/command.c @@ -2491,6 +2491,14 @@ TODO: Add a setting for these tweaks */ command_event(CMD_EVENT_REMOTE_DEINIT, NULL); input_driver_init_remote(); break; + + case CMD_EVENT_MAPPER_DEINIT: + input_driver_deinit_mapper(); + break; + case CMD_EVENT_MAPPER_INIT: + command_event(CMD_EVENT_MAPPER_DEINIT, NULL); + input_driver_init_mapper(); + break; case CMD_EVENT_LOG_FILE_DEINIT: retro_main_log_file_deinit(); break; diff --git a/command.h b/command.h index 4709d3f404..71bd968dec 100644 --- a/command.h +++ b/command.h @@ -193,6 +193,10 @@ enum event_command CMD_EVENT_REMOTE_INIT, /* Deinitializes remote gamepad interface. */ CMD_EVENT_REMOTE_DEINIT, + /* Initializes keyboard to gamepad mapper interface. */ + CMD_EVENT_MAPPER_INIT, + /* Deinitializes keyboard to gamepad mapper interface. */ + CMD_EVENT_MAPPER_DEINIT, /* Reinitializes audio driver. */ CMD_EVENT_AUDIO_REINIT, /* Resizes windowed scale. Will reinitialize video driver. */ diff --git a/configuration.c b/configuration.c index 4fc23eae5b..bb85056ac6 100644 --- a/configuration.c +++ b/configuration.c @@ -1241,6 +1241,9 @@ static struct config_bool_setting *populate_settings_bool(settings_t *settings, #ifdef HAVE_NETWORKGAMEPAD SETTING_BOOL("network_remote_enable", &settings->bools.network_remote_enable, false, false /* TODO */, false); #endif +#ifdef HAVE_KEYMAPPER + SETTING_BOOL("keyboard_mapper_enable", &settings->bools.keyboard_mapper_enable, false, false /* TODO */, false); +#endif #ifdef HAVE_NETWORKING SETTING_BOOL("netplay_nat_traversal", &settings->bools.netplay_nat_traversal, true, true, false); #endif @@ -1343,6 +1346,9 @@ static struct config_uint_setting *populate_settings_uint(settings_t *settings, #ifdef HAVE_NETWORKGAMEPAD SETTING_UINT("network_remote_base_port", &settings->uints.network_remote_base_port, true, network_remote_base_port, false); #endif +#ifdef HAVE_KEYMAPPER + SETTING_UINT("keyboard_mapper_port", &settings->uints.keyboard_mapper_port, true, network_remote_base_port, false); +#endif #ifdef GEKKO SETTING_UINT("video_viwidth", &settings->uints.video_viwidth, true, video_viwidth, false); #endif diff --git a/configuration.h b/configuration.h index 62590e07ce..852a3d906f 100644 --- a/configuration.h +++ b/configuration.h @@ -199,6 +199,7 @@ typedef struct settings bool savestate_thumbnail_enable; bool network_cmd_enable; bool stdin_cmd_enable; + bool keyboard_mapper_enable; bool network_remote_enable; bool network_remote_enable_user[MAX_USERS]; bool load_dummy_on_core_shutdown; @@ -303,6 +304,7 @@ typedef struct settings unsigned autosave_interval; unsigned network_cmd_port; unsigned network_remote_base_port; + unsigned keyboard_mapper_port; unsigned video_window_x; unsigned video_window_y; unsigned video_monitor_index; diff --git a/griffin/griffin.c b/griffin/griffin.c index 967ee00162..6652dd5067 100644 --- a/griffin/griffin.c +++ b/griffin/griffin.c @@ -1097,6 +1097,10 @@ MENU #include "../cores/libretro-net-retropad/net_retropad_core.c" #endif +#ifdef HAVE_KEYMAPPER +#include "../input/input_mapper.c" +#endif + #include "../command.c" #ifdef __cplusplus diff --git a/input/input_driver.c b/input/input_driver.c index ac413f3c06..8ee1462591 100644 --- a/input/input_driver.c +++ b/input/input_driver.c @@ -34,6 +34,10 @@ #include "input_remote.h" #endif +#ifdef HAVE_KEYMAPPER +#include "input_mapper.h" +#endif + #include "input_driver.h" #include "input_keymaps.h" #include "input_remapping.h" @@ -346,6 +350,9 @@ static command_t *input_driver_command = NULL; #ifdef HAVE_NETWORKGAMEPAD static input_remote_t *input_driver_remote = NULL; #endif +#ifdef HAVE_KEYMAPPER +static input_mapper_t *input_driver_mapper = NULL; +#endif const input_driver_t *current_input = NULL; void *current_input_data = NULL; static bool input_driver_block_hotkey = false; @@ -1327,6 +1334,15 @@ void input_driver_deinit_remote(void) #endif } +void input_driver_deinit_mapper(void) +{ +#ifdef HAVE_NETWORKGAMEPAD + if (input_driver_mapper) + input_mapper_free(input_driver_mapper); + input_driver_mapper = NULL; +#endif +} + bool input_driver_init_remote(void) { #ifdef HAVE_NETWORKGAMEPAD @@ -1347,6 +1363,26 @@ bool input_driver_init_remote(void) return false; } +bool input_driver_init_mapper(void) +{ +#ifdef HAVE_KEYMAPPER + settings_t *settings = config_get_ptr(); + + if (!settings->bools.keyboard_mapper_enable) + return false; + + input_driver_mapper = input_mapper_new( + settings->uints.keyboard_mapper_port); + + if (input_driver_mapper) + return true; + + RARCH_ERR("Failed to initialize input mapper.\n"); +#endif + return false; +} + + bool input_driver_grab_mouse(void) { if (!current_input || !current_input->grab_mouse) diff --git a/input/input_driver.h b/input/input_driver.h index 7b1325fe34..111613ae02 100644 --- a/input/input_driver.h +++ b/input/input_driver.h @@ -397,6 +397,10 @@ void input_driver_deinit_remote(void); bool input_driver_init_remote(void); +void input_driver_deinit_mapper(void); + +bool input_driver_init_mapper(void); + bool input_driver_grab_mouse(void); bool input_driver_ungrab_mouse(void); diff --git a/input/input_mapper.c b/input/input_mapper.c new file mode 100644 index 0000000000..8ed7f4bb59 --- /dev/null +++ b/input/input_mapper.c @@ -0,0 +1,96 @@ +/* RetroArch - A frontend for libretro. + * Copyright (C) 2010-2014 - Hans-Kristian Arntzen + * Copyright (C) 2011-2017 - Daniel De Matteis + * Copyright (C) 2016-2017 - Andrés Suárez + * + * 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 . + */ + + +#include +#include +#include + +#ifdef _WIN32 +#include +#else +#include +#endif + +#include +#include +#include +#include +#include +#include +#include + +#ifdef HAVE_CONFIG_H +#include "../config.h" +#endif + +#include "input_mapper.h" + +#include "../configuration.h" +#include "../msg_hash.h" +#include "../verbosity.h" + + +struct input_mapper +{ + +#if defined(HAVE_NETWORKING) && defined(HAVE_NETWORKGAMEPAD) + int net_fd[MAX_USERS]; +#endif + + bool state[RARCH_BIND_LIST_END]; +}; + +typedef struct input_mapper_state +{ + /* This is a bitmask of (1 << key_bind_id). */ + uint64_t buttons; + /* Left X, Left Y, Right X, Right Y */ + int16_t analog[4]; + /* the whole keyboard state */ + uint32_t keys[RETROK_LAST / 32 + 1]; +} input_mapper_state_t; + +input_mapper_t *input_mapper_new(uint16_t port) +{ + return NULL; +} + +void input_mapper_free(input_mapper_t *handle) +{ + return; +} + +void input_mapper_poll(input_mapper_t *handle, unsigned max_users) +{ + return; +} + +bool input_mapper_key_pressed(int key, unsigned port) +{ + return false; +} + +void input_mapper_state( + int16_t *ret, + unsigned port, + unsigned device, + unsigned idx, + unsigned id) +{ + return; +} \ No newline at end of file diff --git a/input/input_mapper.h b/input/input_mapper.h new file mode 100644 index 0000000000..1de7a18a01 --- /dev/null +++ b/input/input_mapper.h @@ -0,0 +1,51 @@ +/* RetroArch - A frontend for libretro. + * Copyright (C) 2010-2014 - Hans-Kristian Arntzen + * Copyright (C) 2011-2017 - Daniel De Matteis + * Copyright (C) 2016-2017 - Andrés Suárez + * + * 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 . + */ + +#ifndef INPUT_MAPPER_H__ +#define INPUT_MAPPER_H__ + +#ifdef HAVE_CONFIG_H +#include "config.h" +#endif + +#include + +#include +#include + +RETRO_BEGIN_DECLS + +typedef struct input_mapper input_mapper_t; + +input_mapper_t *input_mapper_new(uint16_t port); + +void input_mapper_free(input_mapper_t *handle); + +void input_mapper_poll(input_mapper_t *handle, unsigned max_users); + +bool input_mapper_key_pressed(int key, unsigned port); + +void input_mapper_state( + int16_t *ret, + unsigned port, + unsigned device, + unsigned idx, + unsigned id); + +RETRO_END_DECLS + +#endif diff --git a/input/input_remapping.c b/input/input_remapping.c index 7e66086903..2f3bf3cb85 100644 --- a/input/input_remapping.c +++ b/input/input_remapping.c @@ -1,6 +1,6 @@ /* RetroArch - A frontend for libretro. * Copyright (C) 2011-2017 - Daniel De Matteis - * Copyright (C) 2015-2017 - Andrés Suárez + * Copyright (C) 2016-2017 - Andrés Suárez * * 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- diff --git a/input/input_remapping.h b/input/input_remapping.h index d2bdec05ac..147136f1ef 100644 --- a/input/input_remapping.h +++ b/input/input_remapping.h @@ -1,5 +1,6 @@ /* RetroArch - A frontend for libretro. * Copyright (C) 2011-2017 - Daniel De Matteis + * Copyright (C) 2016-2017 - Andrés Suárez * * 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- diff --git a/input/input_remote.c b/input/input_remote.c index 05dbcfb7fe..307c73611b 100644 --- a/input/input_remote.c +++ b/input/input_remote.c @@ -169,18 +169,18 @@ void input_remote_free(input_remote_t *handle, unsigned max_users) #if defined(HAVE_NETWORKING) && defined(HAVE_NETWORKGAMEPAD) static void input_remote_parse_packet(struct remote_message *msg, unsigned user) { - input_remote_state_t *ol_state = input_remote_get_state_ptr(); + input_remote_state_t *input_state = input_remote_get_state_ptr(); /* Parse message */ switch (msg->device) { case RETRO_DEVICE_JOYPAD: - ol_state->buttons[user] &= ~(1 << msg->id); + input_state->buttons[user] &= ~(1 << msg->id); if (msg->state) - ol_state->buttons[user] |= 1 << msg->id; + input_state->buttons[user] |= 1 << msg->id; break; case RETRO_DEVICE_ANALOG: - ol_state->analog[msg->index * 2 + msg->id][user] = msg->state; + input_state->analog[msg->index * 2 + msg->id][user] = msg->state; break; } } @@ -202,17 +202,17 @@ void input_remote_state( case RETRO_DEVICE_ANALOG: { unsigned base = 0; - input_remote_state_t *ol_state = input_remote_get_state_ptr(); + input_remote_state_t *input_state = input_remote_get_state_ptr(); - if (!ol_state) + if (!input_state) return; if (idx == RETRO_DEVICE_INDEX_ANALOG_RIGHT) base = 2; if (id == RETRO_DEVICE_ID_ANALOG_Y) base += 1; - if (ol_state && ol_state->analog[base][port]) - *ret = ol_state->analog[base][port]; + if (input_state && input_state->analog[base][port]) + *ret = input_state->analog[base][port]; } break; } @@ -220,19 +220,19 @@ void input_remote_state( bool input_remote_key_pressed(int key, unsigned port) { - input_remote_state_t *ol_state = input_remote_get_state_ptr(); + input_remote_state_t *input_state = input_remote_get_state_ptr(); - if (!ol_state) + if (!input_state) return false; - return (ol_state->buttons[port] & (UINT64_C(1) << key)); + return (input_state->buttons[port] & (UINT64_C(1) << key)); } void input_remote_poll(input_remote_t *handle, unsigned max_users) { unsigned user; settings_t *settings = config_get_ptr(); - input_remote_state_t *ol_state = input_remote_get_state_ptr(); + input_remote_state_t *input_state = input_remote_get_state_ptr(); for(user = 0; user < max_users; user++) { @@ -257,11 +257,11 @@ void input_remote_poll(input_remote_t *handle, unsigned max_users) else if ((ret != -1) || ((errno != EAGAIN) && (errno != ENOENT))) #endif { - ol_state->buttons[user] = 0; - ol_state->analog[0][user] = 0; - ol_state->analog[1][user] = 0; - ol_state->analog[2][user] = 0; - ol_state->analog[3][user] = 0; + input_state->buttons[user] = 0; + input_state->analog[0][user] = 0; + input_state->analog[1][user] = 0; + input_state->analog[2][user] = 0; + input_state->analog[3][user] = 0; } } } diff --git a/qb/config.params.sh b/qb/config.params.sh index 8f9913e9af..5f7d9abd05 100644 --- a/qb/config.params.sh +++ b/qb/config.params.sh @@ -28,6 +28,7 @@ HAVE_SSA=auto # SSA/ASS for FFmpeg subtitle support HAVE_DYLIB=auto # Dynamic loading support HAVE_NETWORKING=auto # Networking features (recommended) HAVE_NETWORKGAMEPAD=auto # Networked game pad (plus baked-in core) +HAVE_KEYMAPPER=yes # Networked game pad (plus baked-in core) C89_NETWORKGAMEPAD=no HAVE_MINIUPNPC=auto # Mini UPnP client library (for NAT traversal) HAVE_BUILTINMINIUPNPC=yes # Bake in Mini UPnP client library (for NAT traversal) diff --git a/retroarch.c b/retroarch.c index 1e06c7f97f..db45deaea9 100644 --- a/retroarch.c +++ b/retroarch.c @@ -1289,6 +1289,7 @@ bool retroarch_main_init(int argc, char *argv[]) drivers_init(DRIVERS_CMD_ALL); command_event(CMD_EVENT_COMMAND_INIT, NULL); command_event(CMD_EVENT_REMOTE_INIT, NULL); + command_event(CMD_EVENT_MAPPER_INIT, NULL); command_event(CMD_EVENT_REWIND_INIT, NULL); command_event(CMD_EVENT_CONTROLLERS_INIT, NULL); command_event(CMD_EVENT_RECORD_INIT, NULL); @@ -1455,6 +1456,7 @@ bool rarch_ctl(enum rarch_ctl_state state, void *data) command_event(CMD_EVENT_NETPLAY_DEINIT, NULL); command_event(CMD_EVENT_COMMAND_DEINIT, NULL); command_event(CMD_EVENT_REMOTE_DEINIT, NULL); + command_event(CMD_EVENT_MAPPER_DEINIT, NULL); command_event(CMD_EVENT_AUTOSAVE_DEINIT, NULL);