diff --git a/Makefile.common b/Makefile.common index 1a8f323f9a..265e6ab966 100644 --- a/Makefile.common +++ b/Makefile.common @@ -1522,7 +1522,9 @@ else ifeq ($(HAVE_SDL), 1) else ifeq ($(HAVE_SDL_DINGUX), 1) HAVE_SDL_COMMON = 1 DEF_FLAGS += -DHAVE_SDL -DHAVE_SDL_DINGUX - OBJ += gfx/drivers/sdl_dingux_gfx.o + OBJ += gfx/drivers/sdl_dingux_gfx.o \ + input/drivers/sdl_dingux_input.o \ + input/drivers_joypad/sdl_dingux_joypad.o DEF_FLAGS += $(SDL_DINGUX_CFLAGS) LIBS += $(SDL_DINGUX_LIBS) endif diff --git a/Makefile.dingux b/Makefile.dingux index 1043eaa3f0..32d3fd54d6 100644 --- a/Makefile.dingux +++ b/Makefile.dingux @@ -20,7 +20,7 @@ HAVE_CC = 1 HAVE_CC_RESAMPLER = 1 HAVE_CHD = 1 HAVE_CHEEVOS = 1 -HAVE_COMMAND = 1 +HAVE_COMMAND = 0 HAVE_CXX = 1 HAVE_DR_MP3 = 1 HAVE_DYNAMIC = 1 @@ -58,7 +58,7 @@ HAVE_SHADERPIPELINE = 1 HAVE_STB_FONT = 1 HAVE_STB_IMAGE = 1 HAVE_STB_VORBIS = 1 -HAVE_STDIN_CMD = 1 +HAVE_STDIN_CMD = 0 HAVE_STRCASESTR = 1 HAVE_THREADS = 1 HAVE_TRANSLATE = 1 diff --git a/Makefile.rg350 b/Makefile.rg350 index 518f02ad02..3d916009fb 100644 --- a/Makefile.rg350 +++ b/Makefile.rg350 @@ -23,7 +23,7 @@ HAVE_C99 = 1 HAVE_CC = 1 HAVE_CC_RESAMPLER = 1 HAVE_CHD = 1 -HAVE_COMMAND = 1 +HAVE_COMMAND = 0 HAVE_CXX = 1 HAVE_DR_MP3 = 1 HAVE_DYNAMIC = 1 @@ -60,7 +60,7 @@ HAVE_SHADERPIPELINE = 0 HAVE_STB_FONT = 0 HAVE_STB_IMAGE = 1 HAVE_STB_VORBIS = 1 -HAVE_STDIN_CMD = 1 +HAVE_STDIN_CMD = 0 HAVE_STRCASESTR = 1 HAVE_THREADS = 1 HAVE_UDEV = 1 @@ -72,6 +72,7 @@ HAVE_ZLIB = 1 HAVE_CONFIGFILE = 1 HAVE_PATCH = 1 HAVE_CHEATS = 1 +HAVE_CHEEVOS = 0 OS = Linux TARGET = retroarch diff --git a/config.def.h b/config.def.h index 8b97577df7..32aa225277 100644 --- a/config.def.h +++ b/config.def.h @@ -1195,7 +1195,11 @@ static const bool input_descriptor_label_show = true; static const bool input_descriptor_hide_unbound = false; +#if defined(DINGUX) +static const unsigned input_max_users = 1; +#else static const unsigned input_max_users = 5; +#endif static const unsigned input_poll_type_behavior = 2; diff --git a/configuration.c b/configuration.c index bb0f3a90d1..6ab9292978 100644 --- a/configuration.c +++ b/configuration.c @@ -142,6 +142,7 @@ enum input_driver_enum INPUT_ANDROID = AUDIO_RESAMPLER_NULL + 1, INPUT_SDL, INPUT_SDL2, + INPUT_SDL_DINGUX, INPUT_X, INPUT_WAYLAND, INPUT_DINPUT, @@ -183,6 +184,7 @@ enum joypad_driver_enum JOYPAD_LINUXRAW, JOYPAD_ANDROID, JOYPAD_SDL, + JOYPAD_SDL_DINGUX, JOYPAD_DOS, JOYPAD_HID, JOYPAD_QNX, @@ -424,6 +426,8 @@ static const enum input_driver_enum INPUT_DEFAULT_DRIVER = INPUT_SWITCH; static const enum input_driver_enum INPUT_DEFAULT_DRIVER = INPUT_WII; #elif defined(WIIU) static const enum input_driver_enum INPUT_DEFAULT_DRIVER = INPUT_WIIU; +#elif defined(DINGUX) && defined(HAVE_SDL_DINGUX) +static const enum input_driver_enum INPUT_DEFAULT_DRIVER = INPUT_SDL_DINGUX; #elif defined(HAVE_X11) static const enum input_driver_enum INPUT_DEFAULT_DRIVER = INPUT_X; #elif defined(HAVE_UDEV) @@ -466,6 +470,8 @@ static const enum joypad_driver_enum JOYPAD_DEFAULT_DRIVER = JOYPAD_PS2; static const enum joypad_driver_enum JOYPAD_DEFAULT_DRIVER = JOYPAD_CTR; #elif defined(SWITCH) static const enum joypad_driver_enum JOYPAD_DEFAULT_DRIVER = JOYPAD_SWITCH; +#elif defined(DINGUX) && defined(HAVE_SDL_DINGUX) +static const enum joypad_driver_enum JOYPAD_DEFAULT_DRIVER = JOYPAD_SDL_DINGUX; #elif defined(HAVE_DINPUT) static const enum joypad_driver_enum JOYPAD_DEFAULT_DRIVER = JOYPAD_DINPUT; #elif defined(HAVE_UDEV) @@ -902,6 +908,8 @@ const char *config_get_default_input(void) return "sdl"; case INPUT_SDL2: return "sdl2"; + case INPUT_SDL_DINGUX: + return "sdl_dingux"; case INPUT_DINPUT: return "dinput"; case INPUT_WINRAW: @@ -990,6 +998,8 @@ const char *config_get_default_joypad(void) #else return "sdl"; #endif + case JOYPAD_SDL_DINGUX: + return "sdl_dingux"; case JOYPAD_HID: return "hid"; case JOYPAD_QNX: diff --git a/gfx/drivers/sdl_dingux_gfx.c b/gfx/drivers/sdl_dingux_gfx.c index 5dd2743175..55bdabb98c 100644 --- a/gfx/drivers/sdl_dingux_gfx.c +++ b/gfx/drivers/sdl_dingux_gfx.c @@ -327,6 +327,75 @@ static void sdl_dingux_gfx_free(void *data) free(vid); } +static void sdl_dingux_input_driver_init( + const char *input_driver_name, const char *joypad_driver_name, + input_driver_t **input, void **input_data) +{ + /* Sanity check */ + if (!input || !input_data) + return; + + *input = NULL; + *input_data = NULL; + + /* If input driver name is empty, cannot + * initialise anything... */ + if (string_is_empty(input_driver_name)) + return; + +#if defined(HAVE_SDL_DINGUX) + if (string_is_equal(input_driver_name, "sdl_dingux")) + { + *input_data = input_driver_init_wrap(&input_sdl_dingux, + joypad_driver_name); + + if (*input_data) + *input = &input_sdl_dingux; + + return; + } +#endif + +#if defined(HAVE_SDL) || defined(HAVE_SDL2) + if (string_is_equal(input_driver_name, "sdl")) + { + *input_data = input_driver_init_wrap(&input_sdl, + joypad_driver_name); + + if (*input_data) + *input = &input_sdl; + + return; + } +#endif + +#if defined(HAVE_UDEV) + if (string_is_equal(input_driver_name, "udev")) + { + *input_data = input_driver_init_wrap(&input_udev, + joypad_driver_name); + + if (*input_data) + *input = &input_udev; + + return; + } +#endif + +#if defined(__linux__) + if (string_is_equal(input_driver_name, "linuxraw")) + { + *input_data = input_driver_init_wrap(&input_linuxraw, + joypad_driver_name); + + if (*input_data) + *input = &input_linuxraw; + + return; + } +#endif +} + static void *sdl_dingux_gfx_init(const video_info_t *video, input_driver_t **input, void **input_data) { @@ -336,7 +405,8 @@ static void *sdl_dingux_gfx_init(const video_info_t *video, bool ipu_integer_scaling = settings->bools.video_scale_integer; enum dingux_ipu_filter_type ipu_filter_type = (enum dingux_ipu_filter_type) settings->uints.video_dingux_ipu_filter_type; - const char *input_joypad_driver = settings->arrays.input_joypad_driver; + const char *input_driver_name = settings->arrays.input_driver; + const char *joypad_driver_name = settings->arrays.input_joypad_driver; uint32_t surface_flags = (video->vsync) ? (SDL_HWSURFACE | SDL_TRIPLEBUF | SDL_FULLSCREEN) : (SDL_HWSURFACE | SDL_FULLSCREEN); @@ -383,22 +453,8 @@ static void *sdl_dingux_gfx_init(const video_info_t *video, SDL_ShowCursor(SDL_DISABLE); - if (input && input_data) - { - void *sdl_input = input_driver_init_wrap( - &input_sdl, input_joypad_driver); - - if (sdl_input) - { - *input = &input_sdl; - *input_data = sdl_input; - } - else - { - *input = NULL; - *input_data = NULL; - } - } + sdl_dingux_input_driver_init(input_driver_name, + joypad_driver_name, input, input_data); sdl_dingux_init_font_color(vid); sdl_dingux_init_font_lut(vid); diff --git a/griffin/griffin.c b/griffin/griffin.c index 78c2a47e7c..76b12b3723 100644 --- a/griffin/griffin.c +++ b/griffin/griffin.c @@ -743,6 +743,9 @@ INPUT #elif defined(__WINRT__) #include "../input/drivers/xdk_xinput_input.c" #include "../input/drivers/uwp_input.c" +#elif defined(DINGUX) && defined(HAVE_SDL_DINGUX) +#include "../input/drivers/sdl_dingux_input.c" +#include "../input/drivers_joypad/sdl_dingux_joypad.c" #endif #ifdef HAVE_WAYLAND diff --git a/input/drivers/sdl_dingux_input.c b/input/drivers/sdl_dingux_input.c new file mode 100644 index 0000000000..94d155faf3 --- /dev/null +++ b/input/drivers/sdl_dingux_input.c @@ -0,0 +1,54 @@ +/* RetroArch - A frontend for libretro. + * Copyright (C) 2011-2020 - Daniel De Matteis + * Copyright (C) 2019-2020 - James Leaver + * + * 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 + +#include "../input_driver.h" + +#include "../../verbosity.h" + +/* Empty input driver - all functionality + * is handled in the sdl_dingux joypad driver */ + +static void* sdl_dingux_input_init(const char *joypad_driver) +{ + return (void*)-1; +} + +static void sdl_dingux_input_free_input(void *data) +{ +} + +static uint64_t sdl_dingux_input_get_capabilities(void *data) +{ + return (1 << RETRO_DEVICE_JOYPAD) | (1 << RETRO_DEVICE_ANALOG); +} + +input_driver_t input_sdl_dingux = { + sdl_dingux_input_init, + NULL, /* poll */ + NULL, /* input_state */ + sdl_dingux_input_free_input, + NULL, /* set_sensor_state */ + NULL, /* get_sensor_input */ + sdl_dingux_input_get_capabilities, + "sdl_dingux", + NULL, /* grab_mouse */ + NULL /* grab_stdin */ +}; diff --git a/input/drivers_joypad/sdl_dingux_joypad.c b/input/drivers_joypad/sdl_dingux_joypad.c new file mode 100644 index 0000000000..72e29c07f8 --- /dev/null +++ b/input/drivers_joypad/sdl_dingux_joypad.c @@ -0,0 +1,463 @@ +/* RetroArch - A frontend for libretro. + * Copyright (C) 2011-2020 - Daniel De Matteis + * Copyright (C) 2019-2020 - James Leaver + * + * 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 + +#include + +#include "../input_driver.h" + +#include "../../tasks/tasks_internal.h" +#include "../../verbosity.h" + +/* Simple joypad driver designed to rationalise + * the bizarre keyboard/gamepad hybrid setup + * of OpenDingux devices */ + +#define SDL_DINGUX_JOYPAD_NAME "Dingux Gamepad" + +typedef struct +{ + SDL_Joystick *device; + uint16_t pad_state; + int16_t analog_state[2][2]; + unsigned num_axes; + bool connected; + bool menu_toggle; +} dingux_joypad_t; + +/* TODO/FIXME - global referenced outside */ +extern uint64_t lifecycle_state; + +static dingux_joypad_t dingux_joypad; + +static const char *sdl_dingux_joypad_name(unsigned port) +{ + const char *joypad_name = NULL; + + if (port != 0) + return NULL; + + return SDL_DINGUX_JOYPAD_NAME; +} + +static void sdl_dingux_joypad_connect(void) +{ + dingux_joypad_t *joypad = (dingux_joypad_t*)&dingux_joypad; + + /* Open joypad device */ + if (SDL_NumJoysticks() > 0) + joypad->device = SDL_JoystickOpen(0); + + /* If joypad exists, get number of axes */ + if (joypad->device) + joypad->num_axes = SDL_JoystickNumAxes(joypad->device); + + /* 'Register' joypad connection via + * autoconfig task */ + input_autoconfigure_connect( + sdl_dingux_joypad_name(0), /* name */ + NULL, /* display_name */ + sdl_dingux_joypad.ident, /* driver */ + 0, /* port */ + 0, /* vid */ + 0); /* pid */ + + joypad->connected = true; +} + +static void sdl_dingux_joypad_disconnect(void) +{ + dingux_joypad_t *joypad = (dingux_joypad_t*)&dingux_joypad; + + if (joypad->device) + SDL_JoystickClose(joypad->device); + + if (joypad->connected) + input_autoconfigure_disconnect(0, sdl_dingux_joypad.ident); + + memset(joypad, 0, sizeof(dingux_joypad_t)); +} + +static void sdl_dingux_joypad_destroy(void) +{ + SDL_Event event; + + /* Disconnect joypad */ + sdl_dingux_joypad_disconnect(); + + /* De-initialise joystick subsystem */ + SDL_QuitSubSystem(SDL_INIT_JOYSTICK); + + /* Flush out all pending events */ + while (SDL_PollEvent(&event)); + + BIT64_CLEAR(lifecycle_state, RARCH_MENU_TOGGLE); +} + +static void *sdl_dingux_joypad_init(void *data) +{ + dingux_joypad_t *joypad = (dingux_joypad_t*)&dingux_joypad; + + memset(joypad, 0, sizeof(dingux_joypad_t)); + BIT64_CLEAR(lifecycle_state, RARCH_MENU_TOGGLE); + + /* Initialise joystick subsystem */ + if (SDL_WasInit(0) == 0) + { + if (SDL_Init(SDL_INIT_JOYSTICK) < 0) + return NULL; + } + else if (SDL_InitSubSystem(SDL_INIT_JOYSTICK) < 0) + return NULL; + + /* Connect joypad */ + sdl_dingux_joypad_connect(); + + return (void*)-1; +} + +static bool sdl_dingux_joypad_query_pad(unsigned port) +{ + dingux_joypad_t *joypad = (dingux_joypad_t*)&dingux_joypad; + + return (port == 0) && joypad->connected; +} + +static int16_t sdl_dingux_joypad_button(unsigned port, uint16_t joykey) +{ + dingux_joypad_t *joypad = (dingux_joypad_t*)&dingux_joypad; + + if (port != 0) + return 0; + + return (joypad->pad_state & (1 << joykey)); +} + +static void sdl_dingux_joypad_get_buttons(unsigned port, input_bits_t *state) +{ + dingux_joypad_t *joypad = (dingux_joypad_t*)&dingux_joypad; + + /* Macros require braces here... */ + if (port == 0) + { + BITS_COPY16_PTR(state, joypad->pad_state); + } + else + { + BIT256_CLEAR_ALL_PTR(state); + } +} + +static int16_t sdl_dingux_joypad_axis_state(unsigned port, uint32_t joyaxis) +{ + dingux_joypad_t *joypad = (dingux_joypad_t*)&dingux_joypad; + int val = 0; + int axis = -1; + bool is_neg = false; + bool is_pos = false; + + if (port != 0) + return 0; + + if (AXIS_NEG_GET(joyaxis) < 4) + { + axis = AXIS_NEG_GET(joyaxis); + is_neg = true; + } + else if (AXIS_POS_GET(joyaxis) < 4) + { + axis = AXIS_POS_GET(joyaxis); + is_pos = true; + } + else + return 0; + + switch (axis) + { + case 0: + case 1: + val = joypad->analog_state[0][axis]; + break; + case 2: + case 3: + val = joypad->analog_state[1][axis - 2]; + break; + } + + if (is_neg && val > 0) + return 0; + else if (is_pos && val < 0) + return 0; + + return val; +} + +static int16_t sdl_dingux_joypad_axis(unsigned port, uint32_t joyaxis) +{ + if (port != 0) + return 0; + + return sdl_dingux_joypad_axis_state(port, joyaxis); +} + +static int16_t sdl_dingux_joypad_state( + rarch_joypad_info_t *joypad_info, + const struct retro_keybind *binds, + unsigned port) +{ + dingux_joypad_t *joypad = (dingux_joypad_t*)&dingux_joypad; + uint16_t port_idx = joypad_info->joy_idx; + int16_t ret = 0; + size_t i; + + if (port_idx != 0) + return 0; + + for (i = 0; i < RARCH_FIRST_CUSTOM_BIND; i++) + { + /* Auto-binds are per joypad, not per user. */ + const uint64_t joykey = (binds[i].joykey != NO_BTN) + ? binds[i].joykey : joypad_info->auto_binds[i].joykey; + const uint32_t joyaxis = (binds[i].joyaxis != AXIS_NONE) + ? binds[i].joyaxis : joypad_info->auto_binds[i].joyaxis; + + if ((uint16_t)joykey != NO_BTN && + (joypad->pad_state & (1 << (uint16_t)joykey))) + ret |= (1 << i); + else if (joyaxis != AXIS_NONE && + ((float)abs(sdl_dingux_joypad_axis_state(port_idx, joyaxis)) + / 0x8000) > joypad_info->axis_threshold) + ret |= (1 << i); + } + + return ret; +} + +static void sdl_dingux_joypad_poll(void) +{ + dingux_joypad_t *joypad = (dingux_joypad_t*)&dingux_joypad; + SDL_Event event; + + /* Note: The menu toggle key is an awkward special + * case - the press/release events happen almost + * instantaneously, and since we only sample once + * per frame the input is often 'missed'. + * If the toggle key gets pressed, we therefore have + * to wait until the *next* frame to release it */ + if (joypad->menu_toggle) + { + BIT64_CLEAR(lifecycle_state, RARCH_MENU_TOGGLE); + joypad->menu_toggle = false; + } + + /* All digital inputs map to keyboard keys + * - X: SDLK_SPACE + * - A: SDLK_LCTRL + * - B: SDLK_LALT + * - Y: SDLK_LSHIFT + * - L: SDLK_TAB + * - R: SDLK_BACKSPACE + * - L2: SDLK_PAGEUP + * - R2: SDLK_PAGEDOWN + * - Select: SDLK_ESCAPE + * - Start: SDLK_RETURN + * - L3: SDLK_KP_DIVIDE + * - R3: SDLK_KP_PERIOD + * - Up: SDLK_UP + * - Right: SDLK_RIGHT + * - Down: SDLK_DOWN + * - Left: SDLK_LEFT + * - Menu: SDLK_HOME + */ + while (SDL_PollEvent(&event)) + { + switch (event.type) + { + case SDL_KEYDOWN: + switch (event.key.keysym.sym) + { + case SDLK_SPACE: + BIT16_SET(joypad->pad_state, RETRO_DEVICE_ID_JOYPAD_X); + break; + case SDLK_LCTRL: + BIT16_SET(joypad->pad_state, RETRO_DEVICE_ID_JOYPAD_A); + break; + case SDLK_LALT: + BIT16_SET(joypad->pad_state, RETRO_DEVICE_ID_JOYPAD_B); + break; + case SDLK_LSHIFT: + BIT16_SET(joypad->pad_state, RETRO_DEVICE_ID_JOYPAD_Y); + break; + case SDLK_TAB: + BIT16_SET(joypad->pad_state, RETRO_DEVICE_ID_JOYPAD_L); + break; + case SDLK_BACKSPACE: + BIT16_SET(joypad->pad_state, RETRO_DEVICE_ID_JOYPAD_R); + break; + case SDLK_PAGEUP: + BIT16_SET(joypad->pad_state, RETRO_DEVICE_ID_JOYPAD_L2); + break; + case SDLK_PAGEDOWN: + BIT16_SET(joypad->pad_state, RETRO_DEVICE_ID_JOYPAD_R2); + break; + case SDLK_ESCAPE: + BIT16_SET(joypad->pad_state, RETRO_DEVICE_ID_JOYPAD_SELECT); + break; + case SDLK_RETURN: + BIT16_SET(joypad->pad_state, RETRO_DEVICE_ID_JOYPAD_START); + break; + case SDLK_KP_DIVIDE: + BIT16_SET(joypad->pad_state, RETRO_DEVICE_ID_JOYPAD_L3); + break; + case SDLK_KP_PERIOD: + BIT16_SET(joypad->pad_state, RETRO_DEVICE_ID_JOYPAD_R3); + break; + case SDLK_UP: + BIT16_SET(joypad->pad_state, RETRO_DEVICE_ID_JOYPAD_UP); + break; + case SDLK_RIGHT: + BIT16_SET(joypad->pad_state, RETRO_DEVICE_ID_JOYPAD_RIGHT); + break; + case SDLK_DOWN: + BIT16_SET(joypad->pad_state, RETRO_DEVICE_ID_JOYPAD_DOWN); + break; + case SDLK_LEFT: + BIT16_SET(joypad->pad_state, RETRO_DEVICE_ID_JOYPAD_LEFT); + break; + case SDLK_HOME: + BIT64_SET(lifecycle_state, RARCH_MENU_TOGGLE); + joypad->menu_toggle = true; + break; + default: + break; + } + break; + case SDL_KEYUP: + switch (event.key.keysym.sym) + { + case SDLK_SPACE: + BIT16_CLEAR(joypad->pad_state, RETRO_DEVICE_ID_JOYPAD_X); + break; + case SDLK_LCTRL: + BIT16_CLEAR(joypad->pad_state, RETRO_DEVICE_ID_JOYPAD_A); + break; + case SDLK_LALT: + BIT16_CLEAR(joypad->pad_state, RETRO_DEVICE_ID_JOYPAD_B); + break; + case SDLK_LSHIFT: + BIT16_CLEAR(joypad->pad_state, RETRO_DEVICE_ID_JOYPAD_Y); + break; + case SDLK_TAB: + BIT16_CLEAR(joypad->pad_state, RETRO_DEVICE_ID_JOYPAD_L); + break; + case SDLK_BACKSPACE: + BIT16_CLEAR(joypad->pad_state, RETRO_DEVICE_ID_JOYPAD_R); + break; + case SDLK_PAGEUP: + BIT16_CLEAR(joypad->pad_state, RETRO_DEVICE_ID_JOYPAD_L2); + break; + case SDLK_PAGEDOWN: + BIT16_CLEAR(joypad->pad_state, RETRO_DEVICE_ID_JOYPAD_R2); + break; + case SDLK_ESCAPE: + BIT16_CLEAR(joypad->pad_state, RETRO_DEVICE_ID_JOYPAD_SELECT); + break; + case SDLK_RETURN: + BIT16_CLEAR(joypad->pad_state, RETRO_DEVICE_ID_JOYPAD_START); + break; + case SDLK_KP_DIVIDE: + BIT16_CLEAR(joypad->pad_state, RETRO_DEVICE_ID_JOYPAD_L3); + break; + case SDLK_KP_PERIOD: + BIT16_CLEAR(joypad->pad_state, RETRO_DEVICE_ID_JOYPAD_R3); + break; + case SDLK_UP: + BIT16_CLEAR(joypad->pad_state, RETRO_DEVICE_ID_JOYPAD_UP); + break; + case SDLK_RIGHT: + BIT16_CLEAR(joypad->pad_state, RETRO_DEVICE_ID_JOYPAD_RIGHT); + break; + case SDLK_DOWN: + BIT16_CLEAR(joypad->pad_state, RETRO_DEVICE_ID_JOYPAD_DOWN); + break; + case SDLK_LEFT: + BIT16_CLEAR(joypad->pad_state, RETRO_DEVICE_ID_JOYPAD_LEFT); + break; + default: + break; + } + break; + default: + break; + } + } + + /* Analog inputs come from the joypad device, + * if connected */ + if (joypad->device) + { + int16_t axis_value; + + SDL_JoystickUpdate(); + + if (joypad->num_axes > 0) + { + axis_value = SDL_JoystickGetAxis(joypad->device, 0); + /* -0x8000 can cause trouble if we later abs() it */ + joypad->analog_state[RETRO_DEVICE_INDEX_ANALOG_LEFT][RETRO_DEVICE_ID_ANALOG_X] = + (axis_value < -0x7FFF) ? -0x7FFF : axis_value; + } + + if (joypad->num_axes > 1) + { + axis_value = SDL_JoystickGetAxis(joypad->device, 1); + joypad->analog_state[RETRO_DEVICE_INDEX_ANALOG_LEFT][RETRO_DEVICE_ID_ANALOG_Y] = + (axis_value < -0x7FFF) ? -0x7FFF : axis_value; + } + + if (joypad->num_axes > 2) + { + axis_value = SDL_JoystickGetAxis(joypad->device, 2); + joypad->analog_state[RETRO_DEVICE_INDEX_ANALOG_RIGHT][RETRO_DEVICE_ID_ANALOG_X] = + (axis_value < -0x7FFF) ? -0x7FFF : axis_value; + } + + if (joypad->num_axes > 3) + { + axis_value = SDL_JoystickGetAxis(joypad->device, 3); + joypad->analog_state[RETRO_DEVICE_INDEX_ANALOG_RIGHT][RETRO_DEVICE_ID_ANALOG_Y] = + (axis_value < -0x7FFF) ? -0x7FFF : axis_value; + } + } +} + +input_device_driver_t sdl_dingux_joypad = { + sdl_dingux_joypad_init, + sdl_dingux_joypad_query_pad, + sdl_dingux_joypad_destroy, + sdl_dingux_joypad_button, + sdl_dingux_joypad_state, + sdl_dingux_joypad_get_buttons, + sdl_dingux_joypad_axis, + sdl_dingux_joypad_poll, + NULL, /* set_rumble */ + sdl_dingux_joypad_name, + "sdl_dingux", +}; diff --git a/input/input_autodetect_builtin.c b/input/input_autodetect_builtin.c index b2e4818ce5..08f2615e25 100644 --- a/input/input_autodetect_builtin.c +++ b/input/input_autodetect_builtin.c @@ -66,6 +66,34 @@ DECL_AXIS(r_x_minus, -2) \ DECL_AXIS(r_y_plus, -3) \ DECL_AXIS(r_y_minus, +3) +#if defined(DINGUX) && defined(HAVE_SDL_DINGUX) +#define DINGUX_SDL_DEFAULT_BINDS \ +DECL_BTN_EX(a, 8, "A") \ +DECL_BTN_EX(b, 0, "B") \ +DECL_BTN_EX(x, 9, "X") \ +DECL_BTN_EX(y, 1, "Y") \ +DECL_BTN_EX(start, 3, "Start") \ +DECL_BTN_EX(select, 2, "Select") \ +DECL_BTN_EX(up, 4, "D-Pad Up") \ +DECL_BTN_EX(down, 5, "D-Pad Down") \ +DECL_BTN_EX(left, 6, "D-Pad Left") \ +DECL_BTN_EX(right, 7, "D-Pad Right") \ +DECL_BTN_EX(l, 10, "L") \ +DECL_BTN_EX(r, 11, "R") \ +DECL_BTN_EX(l2, 12, "L2") \ +DECL_BTN_EX(r2, 13, "R2") \ +DECL_BTN_EX(l3, 14, "L3") \ +DECL_BTN_EX(r3, 15, "R3") \ +DECL_AXIS_EX(l_x_plus, +0, "L-Stick right") \ +DECL_AXIS_EX(l_x_minus, -0, "L-Stick left") \ +DECL_AXIS_EX(l_y_plus, +1, "L-Stick down") \ +DECL_AXIS_EX(l_y_minus, -1, "L-Stick up") \ +DECL_AXIS_EX(r_x_plus, +2, "R-Stick right") \ +DECL_AXIS_EX(r_x_minus, -2, "R-Stick left") \ +DECL_AXIS_EX(r_y_plus, +3, "R-Stick down") \ +DECL_AXIS_EX(r_y_minus, -3, "R-Stick up") +#endif + #if defined(ANDROID) #define ANDROID_DEFAULT_BINDS \ DECL_BTN(a, 97) \ @@ -671,6 +699,9 @@ const char* const input_builtin_autoconfs[] = #ifdef HAVE_SDL2 DECL_AUTOCONF_DEVICE("Standard Gamepad", "sdl2", SDL2_DEFAULT_BINDS), #endif +#if defined(DINGUX) && defined(HAVE_SDL_DINGUX) + DECL_AUTOCONF_DEVICE("Dingux Gamepad", "sdl_dingux", DINGUX_SDL_DEFAULT_BINDS), +#endif #if defined(ANDROID) DECL_AUTOCONF_DEVICE("Android Gamepad", "android", ANDROID_DEFAULT_BINDS), #endif diff --git a/input/input_driver.h b/input/input_driver.h index d6c21b78c0..b99870c893 100644 --- a/input/input_driver.h +++ b/input/input_driver.h @@ -518,6 +518,7 @@ extern input_device_driver_t parport_joypad; extern input_device_driver_t udev_joypad; extern input_device_driver_t xinput_joypad; extern input_device_driver_t sdl_joypad; +extern input_device_driver_t sdl_dingux_joypad; extern input_device_driver_t ps4_joypad; extern input_device_driver_t ps3_joypad; extern input_device_driver_t psp_joypad; @@ -536,6 +537,7 @@ extern input_device_driver_t rwebpad_joypad; extern input_driver_t input_android; extern input_driver_t input_sdl; +extern input_driver_t input_sdl_dingux; extern input_driver_t input_dinput; extern input_driver_t input_x; extern input_driver_t input_ps4; diff --git a/retroarch.c b/retroarch.c index 67fa04d72a..d1424ff135 100644 --- a/retroarch.c +++ b/retroarch.c @@ -728,6 +728,9 @@ static input_driver_t *input_drivers[] = { #if defined(HAVE_SDL) || defined(HAVE_SDL2) &input_sdl, #endif +#if defined(DINGUX) && defined(HAVE_SDL_DINGUX) + &input_sdl_dingux, +#endif #ifdef HAVE_DINPUT &input_dinput, #endif @@ -843,6 +846,9 @@ static input_device_driver_t *joypad_drivers[] = { #if defined(HAVE_SDL) || defined(HAVE_SDL2) &sdl_joypad, #endif +#if defined(DINGUX) && defined(HAVE_SDL_DINGUX) + &sdl_dingux_joypad, +#endif #ifdef __QNX__ &qnx_joypad, #endif @@ -26998,7 +27004,11 @@ static bool input_driver_find_driver(struct rarch_state *p_rarch) i = (int)drv.len; if (i >= 0) + { p_rarch->current_input = (input_driver_t*)input_drivers[i]; + RARCH_LOG("[Input]: Found input driver: \"%s\".\n", + p_rarch->current_input->ident); + } else { unsigned d;