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;