1
0

3 Commits 78bfaabe3b ... 56a6bbf454

Autor SHA1 Nachricht Datum
  ZengGengSen 56a6bbf454 fix the gamepad auto_plugin problem vor 2 Jahren
  ZengGengSen 7bff8769aa Merge remote-tracking branch 'origin/master' vor 2 Jahren
  ZengGengSen a795ab876f 1. add JoypadManager vor 2 Jahren

+ 2 - 0
app/src/main/cpp/defaults.h

@@ -40,7 +40,9 @@ enum default_dirs
 #endif
    DEFAULT_DIR_CORE,
    DEFAULT_DIR_CORE_INFO,
+#ifdef HAVE_OVERLAY
    DEFAULT_DIR_OVERLAY,
+#endif
    DEFAULT_DIR_PORT,
    DEFAULT_DIR_SHADER,
    DEFAULT_DIR_SAVESTATE,

+ 40 - 1
app/src/main/cpp/frontend/drivers/platform_unix.c

@@ -588,6 +588,35 @@ Java_com_retroarch_browser_retroactivity_RetroActivityCommon_registerBeans(
             android_app->beans.input_descriptor_bean.clazz,
             "<init>", "(IIIILjava/lang/String;)V"
     );
+
+   FIND_CLASS(
+           env,
+           android_app->beans.joypad_manager.clazz,
+           "com/xugame/app/JoypadManager"
+   );
+   android_app->beans.joypad_manager.clazz =
+           (*env)->NewGlobalRef(env, android_app->beans.joypad_manager.clazz);
+
+   GET_STATIC_METHOD_ID(
+           env,
+           android_app->beans.joypad_manager.initialize,
+           android_app->beans.joypad_manager.clazz,
+           "initialize", "()V"
+   );
+
+   GET_STATIC_METHOD_ID(
+           env,
+           android_app->beans.joypad_manager.uninitialize,
+           android_app->beans.joypad_manager.clazz,
+           "uninitialize", "()V"
+   );
+
+   GET_STATIC_METHOD_ID(
+           env,
+           android_app->beans.joypad_manager.pollInputDevices,
+           android_app->beans.joypad_manager.clazz,
+           "pollInputDevices", "()V"
+   );
 }
 
 JNIEXPORT void JNICALL
@@ -599,6 +628,7 @@ Java_com_retroarch_browser_retroactivity_RetroActivityCommon_unregisterBeans(
       return;
 
    (*env)->DeleteGlobalRef(env, android_app->beans.input_descriptor_bean.clazz);
+   (*env)->DeleteGlobalRef(env, android_app->beans.joypad_manager.clazz);
 }
 /*
  * Native activity interaction (called from main thread)
@@ -1682,9 +1712,10 @@ static void frontend_unix_get_env(int *argc,
                   "assets", sizeof(g_defaults.dirs[DEFAULT_DIR_ASSETS]));
             fill_pathname_join(g_defaults.dirs[DEFAULT_DIR_SHADER], app_dir,
                   "shaders", sizeof(g_defaults.dirs[DEFAULT_DIR_SHADER]));
+#ifdef HAVE_OVERLAY
             fill_pathname_join(g_defaults.dirs[DEFAULT_DIR_OVERLAY], app_dir,
                   "overlays", sizeof(g_defaults.dirs[DEFAULT_DIR_OVERLAY]));
-
+#endif
             fill_pathname_join(g_defaults.dirs[DEFAULT_DIR_CORE], app_dir,
                   "cores", sizeof(g_defaults.dirs[DEFAULT_DIR_CORE]));
             fill_pathname_join(g_defaults.dirs[DEFAULT_DIR_CORE_INFO],
@@ -1986,8 +2017,10 @@ static void frontend_unix_get_env(int *argc,
          "shaders", sizeof(g_defaults.dirs[DEFAULT_DIR_SHADER]));
    fill_pathname_join(g_defaults.dirs[DEFAULT_DIR_CHEATS], base_path,
          "cheats", sizeof(g_defaults.dirs[DEFAULT_DIR_CHEATS]));
+#ifdef HAVE_OVERLAY
    fill_pathname_join(g_defaults.dirs[DEFAULT_DIR_OVERLAY], base_path,
          "overlay", sizeof(g_defaults.dirs[DEFAULT_DIR_OVERLAY]));
+#endif
    fill_pathname_join(g_defaults.dirs[DEFAULT_DIR_CORE_ASSETS], base_path,
          "downloads", sizeof(g_defaults.dirs[DEFAULT_DIR_CORE_ASSETS]));
    fill_pathname_join(g_defaults.dirs[DEFAULT_DIR_SCREENSHOT], base_path,
@@ -2120,6 +2153,7 @@ static void frontend_unix_deinit(void *data)
 static void frontend_unix_init(void *data)
 {
 #ifdef ANDROID
+   int i;
    char device_model[PROP_VALUE_MAX] = {0};
    JNIEnv                     *env   = NULL;
    ALooper                 *looper   = NULL;
@@ -2161,6 +2195,10 @@ static void frontend_unix_init(void *data)
    if (!(env = jni_thread_getenv()))
       return;
 
+   for (i = 0; i < MAX_USERS; ++i) {
+      android_app->id[i] = -1;
+   }
+
    GET_OBJECT_CLASS(env, class, android_app->activity->clazz);
    GET_METHOD_ID(env, android_app->getIntent, class,
          "getIntent", "()Landroid/content/Intent;");
@@ -3044,3 +3082,4 @@ frontend_ctx_driver_t frontend_ctx_unix = {
 };
 
 
+

+ 11 - 0
app/src/main/cpp/frontend/drivers/platform_unix.h

@@ -199,6 +199,13 @@ struct android_app
            jclass clazz;
            jmethodID constructor;
        } input_descriptor_bean;
+
+       struct {
+           jclass clazz;
+           jmethodID initialize;
+           jmethodID uninitialize;
+           jmethodID pollInputDevices;
+       } joypad_manager;
    } beans;
 };
 
@@ -356,6 +363,10 @@ enum
    (*env)->CallVoidMethod(env, clazz_obj, methodId); \
    JNI_EXCEPTION(env)
 
+#define CALL_VOID_STATIC_METHOD(env, clazz_obj, methodId) \
+   (*env)->CallStaticVoidMethod(env, clazz_obj, methodId); \
+   JNI_EXCEPTION(env)
+
 #define CALL_VOID_METHOD_PARAM(env, clazz_obj, methodId, ...) \
    (*env)->CallVoidMethod(env, clazz_obj, methodId, __VA_ARGS__); \
    JNI_EXCEPTION(env)

+ 2 - 21
app/src/main/cpp/gfx/video_driver.c

@@ -1548,27 +1548,8 @@ void video_driver_free_internal(void)
    if (!(video_st->flags & VIDEO_FLAG_CACHE_CONTEXT))
       video_driver_free_hw_context();
 
-   if (!(input_st->current_data == video_st->data))
-   {
-      if (input_st->current_driver)
-         if (input_st->current_driver->free)
-            input_st->current_driver->free(input_st->current_data);
-      if (input_st->primary_joypad)
-      {
-         const input_device_driver_t *tmp   = input_st->primary_joypad;
-         input_st->primary_joypad    = NULL;
-         tmp->destroy();
-      }
-#ifdef HAVE_MFI
-      if (input_st->secondary_joypad)
-      {
-         const input_device_driver_t *tmp   = input_st->secondary_joypad;
-         input_st->secondary_joypad         = NULL;
-         tmp->destroy();
-      }
-#endif
-      input_st->flags &= ~INP_FLAG_KB_MAPPING_BLOCKED;
-      input_st->current_data                = NULL;
+   if (input_st->current_data != video_st->data) {
+      video_driver_free_input();
    }
 
    if (     video_st->data

+ 1 - 109
app/src/main/cpp/griffin/griffin.c

@@ -698,61 +698,16 @@ INPUT
 #endif
 #endif
 
-#if defined(SN_TARGET_PSP2) || defined(PSP) || defined(VITA)
-#include "../input/drivers/psp_input.c"
-#include "../input/drivers_joypad/psp_joypad.c"
-#elif defined(PS2)
-#include "../input/drivers/ps2_input.c"
-#include "../input/drivers_joypad/ps2_joypad.c"
-#elif defined(__PS3__)
-#include "../input/drivers/ps3_input.c"
-#include "../input/drivers_joypad/ps3_joypad.c"
-#elif defined(ORBIS)
-#include "../input/drivers/ps4_input.c"
-#include "../input/drivers_joypad/ps4_joypad.c"
-#elif defined(_3DS)
-#include "../input/drivers/ctr_input.c"
-#include "../input/drivers_joypad/ctr_joypad.c"
-#elif defined(GEKKO)
-#include "../input/drivers/gx_input.c"
-#include "../input/drivers_joypad/gx_joypad.c"
-#elif defined(__wiiu__)
-#include "../input/common/hid/hid_device_driver.c"
-#include "../input/common/hid/device_wiiu_gca.c"
-#include "../input/common/hid/device_ds3.c"
-#include "../input/common/hid/device_ds4.c"
-#include "../input/common/hid/device_null.c"
-#include "../input/drivers/wiiu_input.c"
-#include "../input/drivers_joypad/wiiu_joypad.c"
-#include "../input/drivers_joypad/wiiu/hidpad_driver.c"
-#include "../input/drivers_joypad/wiiu/kpad_driver.c"
-#include "../input/drivers_joypad/wiiu/wpad_driver.c"
-#include "../input/drivers_joypad/wiiu/pad_functions.c"
-#elif defined(_XBOX)
+#if defined(_XBOX)
 #include "../input/drivers/xdk_xinput_input.c"
-#ifdef _XBOX1
-#include "../input/drivers_joypad/xdk_joypad.c"
-#endif
 #elif defined(XENON)
 #include "../input/drivers/xenon360_input.c"
 #elif defined(ANDROID)
 #include "../input/drivers/android_input.c"
 #include "../input/drivers_joypad/android_joypad.c"
-#elif defined(__QNX__)
-#include "../input/drivers/qnx_input.c"
-#include "../input/drivers_joypad/qnx_joypad.c"
-#elif defined(EMSCRIPTEN)
-#include "../input/drivers/rwebinput_input.c"
-#include "../input/drivers_joypad/rwebpad_joypad.c"
-#elif defined(DJGPP)
-#include "../input/drivers/dos_input.c"
-#include "../input/drivers_joypad/dos_joypad.c"
 #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
@@ -760,34 +715,10 @@ INPUT
 #include "../input/drivers/wayland_input.c"
 #endif
 
-#ifdef HAVE_DINPUT
-#include "../input/drivers/dinput.c"
-#include "../input/drivers_joypad/dinput_joypad.c"
-#endif
-
-#ifdef HAVE_XINPUT
-#ifdef HAVE_DINPUT
-#include "../input/drivers_joypad/xinput_hybrid_joypad.c"
-#else
-#include "../input/drivers_joypad/xinput_joypad.c"
-#endif
-#endif
-
-#if defined(__linux__) && !defined(ANDROID)
-#include "../input/common/linux_common.c"
-#include "../input/drivers/linuxraw_input.c"
-#include "../input/drivers_joypad/linuxraw_joypad.c"
-#endif
-
 #ifdef HAVE_X11
 #include "../input/drivers/x11_input.c"
 #endif
 
-#ifdef HAVE_UDEV
-#include "../input/drivers/udev_input.c"
-#include "../input/drivers_joypad/udev_joypad.c"
-#endif
-
 #if defined(HAVE_LIBSHAKE)
 #include "../deps/libShake/src/common/error.c"
 #include "../deps/libShake/src/common/helpers.c"
@@ -799,45 +730,6 @@ INPUT
 #endif
 #endif
 
-/*============================================================
-INPUT (HID)
-============================================================ */
-#ifdef HAVE_HID
-#include "../input/common/input_hid_common.c"
-#include "../input/drivers_joypad/hid_joypad.c"
-
-#if defined(HAVE_LIBUSB) && defined(HAVE_THREADS)
-#include "../input/drivers_hid/libusb_hid.c"
-#endif
-
-#ifdef HAVE_BTSTACK
-#include "../input/drivers_hid/btstack_hid.c"
-#endif
-
-#if defined(__APPLE__) && defined(HAVE_IOHIDMANAGER)
-#include "../input/drivers_hid/iohidmanager_hid.c"
-#endif
-
-#ifdef HAVE_WIIUSB_HID
-#include "../input/drivers_hid/wiiusb_hid.c"
-#endif
-
-#include "../input/connect/joypad_connection.c"
-#include "../input/connect/connect_ps3.c"
-#include "../input/connect/connect_ps4.c"
-#include "../input/connect/connect_wii.c"
-#include "../input/connect/connect_wiiupro.c"
-#include "../input/connect/connect_snesusb.c"
-#include "../input/connect/connect_nesusb.c"
-#include "../input/connect/connect_wiiugca.c"
-#include "../input/connect/connect_ps2adapter.c"
-#include "../input/connect/connect_psxadapter.c"
-#include "../input/connect/connect_retrode.c"
-#include "../input/connect/connect_ps4_hori_mini.c"
-#include "../input/connect/connect_kade.c"
-#include "../input/connect/connect_zerodelay_dragonrise.c"
-#endif
-
 /*============================================================
  KEYBOARD EVENT
  ============================================================ */

+ 0 - 160
app/src/main/cpp/input/connect/joypad_connection.h

@@ -1,160 +0,0 @@
-/*  RetroArch - A frontend for libretro.
- *  Copyright (C) 2013-2014 - Jason Fetters
- *  Copyright (C) 2011-2017 - Daniel De Matteis
- *
- *  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/>.
- */
-
-#ifndef _JOYPAD_CONNECTION_H
-#define _JOYPAD_CONNECTION_H
-
-#include <stdint.h>
-#include <stddef.h>
-
-#include <libretro.h>
-#include <retro_miscellaneous.h>
-#include <retro_endianness.h>
-#include "../input_driver.h"
-
-/* Gekko (NGC/Wii) has PID/VID already swapped by USB_GetDescriptors from libogc, so skip bigendian byteswap */
-#if defined(MSB_FIRST) && !defined(GEKKO)
-#define SWAP_IF_BIG(val) ((((val) & 0x00ff) << 8) | (((val) & 0xff00) >> 8))
-#else
-#define SWAP_IF_BIG(val) (val)
-#endif
-
-#define VID_NONE          0x0000
-#define VID_NINTENDO      SWAP_IF_BIG(0x057e)
-#define VID_SONY          SWAP_IF_BIG(0x054c)
-#define VID_MICRONTEK     SWAP_IF_BIG(0x0079)
-#define VID_PCS           SWAP_IF_BIG(0x0810)
-#define VID_PS3_CLONE     SWAP_IF_BIG(0x0313)
-#define VID_SNES_CLONE    SWAP_IF_BIG(0x081f)
-#define VID_RETRODE       SWAP_IF_BIG(0x0403)
-#define VID_HORI_1        SWAP_IF_BIG(0x0f0d)
-#define VID_KADE          SWAP_IF_BIG(0x10c4)
-#define VID_DRAGONRISE    SWAP_IF_BIG(0x0079)
-
-#define PID_NONE          0x0000
-#define PID_NINTENDO_PRO  SWAP_IF_BIG(0x0330)
-#define PID_SONY_DS3      SWAP_IF_BIG(0x0268)
-#define PID_SONY_DS4      SWAP_IF_BIG(0x05c4)
-#define PID_SONY_DS4_R2   SWAP_IF_BIG(0x09cc)
-#define PID_DS3_CLONE     SWAP_IF_BIG(0x20d6)
-#define PID_SNES_CLONE    SWAP_IF_BIG(0xe401)
-#define PID_MICRONTEK_NES SWAP_IF_BIG(0x0011)
-#define PID_NINTENDO_GCA  SWAP_IF_BIG(0x0337)
-#define PID_PCS_PS2PSX    SWAP_IF_BIG(0x0001)
-#define PID_PCS_PSX2PS3   SWAP_IF_BIG(0x0003)
-#define PID_RETRODE       SWAP_IF_BIG(0x97c1)
-#define PID_HORI_MINI_WIRED_PS4 SWAP_IF_BIG(0x00ee)
-#define PID_KADE          SWAP_IF_BIG(0x82c0)
-#define PID_DRAGONRISE    SWAP_IF_BIG(0x0006)
-
-struct joypad_connection
-{
-    struct pad_connection_interface *iface;
-    input_device_driver_t *input_driver;
-    void* data;
-    void* connection;
-    bool connected;
-};
-
-#define PAD_CONNECT_OFFLINE     0x00 /* the pad is offline and cannot be used */
-#define PAD_CONNECT_READY       0x01 /* the pad is ready but is not bound to a RA slot */
-#define PAD_CONNECT_BOUND       0x02 /* the pad is offline and is bound to a RA slot */
-#define PAD_CONNECT_IN_USE      0x03 /* the pad is ready and is bound to a RA slot */
-
-#define SLOT_AUTO -1
-
-typedef struct pad_connection_interface
-{
-   void*    	(*init)(void *data, uint32_t slot, hid_driver_t *driver);
-   void     	(*deinit)(void* device);
-   void     	(*packet_handler)(void* device, uint8_t *packet, uint16_t size);
-   void     	(*set_rumble)(void* device, enum retro_rumble_effect effect,
-					uint16_t strength);
-   void			(*get_buttons)(void *data, input_bits_t *state);
-   int16_t  	(*get_axis)(void *data, unsigned axis);
-   const char*	(*get_name)(void *data);
-   int32_t     (*button)(void *data, uint16_t joykey);
-   /* all fields/methods below this point are only required for multi-pad devices */
-   bool        multi_pad;  /* does the device provide multiple pads? */
-   int8_t      max_pad;    /* number of pads this device can provide */
-   void*       (*pad_init)(void *data, int pad_index, joypad_connection_t *joyconn);
-   void        (*pad_deinit)(void *pad_data);
-   /* pad_index is a number from 0 to max_pad-1 */
-   int8_t      (*status)(void *data, int pad_index); /* returns a PAD_CONNECT_* state */
-   joypad_connection_t* (*joypad)(void *device_data, int pad_index);
-} pad_connection_interface_t;
-
-typedef struct joypad_connection_entry {
-   const char* name;
-   uint16_t vid;
-   uint16_t pid;
-   pad_connection_interface_t *iface;
-} joypad_connection_entry_t;
-
-extern pad_connection_interface_t pad_connection_wii;
-extern pad_connection_interface_t pad_connection_wiiupro;
-extern pad_connection_interface_t pad_connection_ps3;
-extern pad_connection_interface_t pad_connection_ps4;
-extern pad_connection_interface_t pad_connection_snesusb;
-extern pad_connection_interface_t pad_connection_nesusb;
-extern pad_connection_interface_t pad_connection_wiiugca;
-extern pad_connection_interface_t pad_connection_ps2adapter;
-extern pad_connection_interface_t pad_connection_psxadapter;
-extern pad_connection_interface_t pad_connection_retrode;
-extern pad_connection_interface_t pad_connection_ps4_hori_mini;
-extern pad_connection_interface_t pad_connection_kade;
-extern pad_connection_interface_t pad_connection_dragonrise;
-
-int32_t pad_connection_pad_init(joypad_connection_t *joyconn,
-   const char* name, uint16_t vid, uint16_t pid,
-   void *data, hid_driver_t *driver);
-
-joypad_connection_t *pad_connection_init(unsigned pads);
-
-void pad_connection_destroy(joypad_connection_t *joyconn);
-
-void pad_connection_pad_deinit(joypad_connection_t *joyconn,
-   uint32_t idx);
-
-void pad_connection_packet(joypad_connection_t *joyconn,
-   uint32_t idx, uint8_t* data, uint32_t length);
-
-void pad_connection_get_buttons(joypad_connection_t *joyconn,
-   unsigned idx, input_bits_t* state);
-
-int16_t pad_connection_get_axis(joypad_connection_t *joyconn,
-   unsigned idx, unsigned i);
-
-/* Determine if connected joypad is a hidpad backed device.
- * If false, pad_connection_packet cannot be used */
-
-bool pad_connection_has_interface(joypad_connection_t *joyconn,
-   unsigned idx);
-
-int pad_connection_find_vacant_pad(joypad_connection_t *joyconn);
-
-bool pad_connection_rumble(joypad_connection_t *s,
-   unsigned pad, enum retro_rumble_effect effect, uint16_t strength);
-
-const char* pad_connection_get_name(joypad_connection_t *joyconn,
-   unsigned idx);
-
-joypad_connection_entry_t *find_connection_entry(uint16_t vid, uint16_t pid, const char *name);
-int32_t pad_connection_pad_init_entry(joypad_connection_t *joyconn, joypad_connection_entry_t *entry, void *data, hid_driver_t *driver);
-void pad_connection_pad_register(joypad_connection_t *joyconn, pad_connection_interface_t *iface, void *pad_data, void *handle, input_device_driver_t *input_driver, int slot);
-void pad_connection_pad_deregister(joypad_connection_t *joyconn, pad_connection_interface_t *iface, void *pad_data);
-void pad_connection_pad_refresh(joypad_connection_t *joyconn, pad_connection_interface_t *iface, void *device_data, void *handle, input_device_driver_t *input_driver);
-#endif

+ 19 - 6
app/src/main/cpp/input/drivers/android_input.c

@@ -601,6 +601,7 @@ static bool android_input_init_handle(void)
 
 static void *android_input_init(const char *joypad_driver)
 {
+   int i;
    int32_t sdk;
    struct android_app *android_app = (struct android_app*)g_android;
    android_input_t *android = (android_input_t*)
@@ -611,6 +612,11 @@ static void *android_input_init(const char *joypad_driver)
 
    android->pads_connected = 0;
    android->quick_tap_time = 0;
+   for (i = 0; i < MAX_USERS; ++i) {
+      android->pad_states[i].id = -1;
+      android->pad_states[i].port = -1;
+      android->pad_states[i].name[0] = '\0';
+   }
 
    input_keymaps_init_keyboard_lut(rarch_key_map_android);
 
@@ -1422,9 +1428,12 @@ static void android_input_poll_input_gingerbread(
       if (port < 0 && !android_is_keyboard_id(id))
          port = android_input_recover_port(android, id);
 
-      if (port < 0 && !android_is_keyboard_id(id))
-         handle_hotplug(android, android_app,
-         &port, id, source);
+      if (port < 0 && !android_is_keyboard_id(id)) {
+         AInputQueue_finishEvent(android_app->inputQueue, event, handled);
+         return;
+         // handle_hotplug(android, android_app,
+         // &port, id, source);
+      }
 
       switch (type_event)
       {
@@ -1484,9 +1493,13 @@ static void android_input_poll_input_default(android_input_t *android)
          if (port < 0 && !android_is_keyboard_id(id))
             port = android_input_recover_port(android, id);
 
-         if (port < 0 && !android_is_keyboard_id(id))
-            handle_hotplug(android, android_app,
-                  &port, id, source);
+         if (port < 0 && !android_is_keyboard_id(id)) {
+            if (!predispatched)
+               AInputQueue_finishEvent(android_app->inputQueue, event, handled);
+            return;
+            // handle_hotplug(android, android_app,
+            // &port, id, source);
+         }
 
          switch (type_event)
          {

+ 418 - 4
app/src/main/cpp/input/drivers_joypad/android_joypad.c

@@ -26,7 +26,399 @@ static const char *android_joypad_name(unsigned pad)
    return input_config_get_device_name(pad);
 }
 
-static void *android_joypad_init(void *data) { return (void*)-1; }
+JNIEXPORT void JNICALL
+Java_com_xugame_app_JoypadManager_addJoystickNative(
+        JNIEnv *env, jclass clazz,
+        jint id, jint source
+) {
+   struct android_app   *android_app = (struct android_app*)g_android;
+   input_driver_state_t *input_st    = input_state_get_ptr();
+   android_input_t      *android     = (android_input_t*)input_st->current_data;
+   int                   port        = -1;
+
+   char device_name[256];
+   char name_buf[256];
+   int vendorId                 = 0;
+   int productId                = 0;
+   const char *device_model     = android->device_model;
+
+   if (android->pads_connected > MAX_USERS) {
+      return;
+   }
+
+   device_name[0] = name_buf[0] = '\0';
+
+   if (!engine_lookup_name(device_name, &vendorId,
+                           &productId, sizeof(device_name), id))
+      return;
+
+   /* FIXME - per-device hacks for NVidia Shield, Xperia Play and
+    * similar devices
+    *
+    * These hacks depend on autoconf, but can work with user
+    * created autoconfs properly
+    */
+
+   /* NVIDIA Shield Console
+    * This is the most complicated example, the built-in controller
+    * has an extra button that can't be used and a remote.
+    *
+    * We map the remote for navigation and overwrite whenever a
+    * real controller is connected.
+    * Also group the NVIDIA button on the controller with the
+    * main controller inputs so it's usable. It's mapped to
+    * menu by default
+    *
+    * The NVIDIA button is identified as "Virtual" device when first
+    * pressed. CEC remote input is also identified as "Virtual" device.
+    * If a virtual device is detected before a controller then it will
+    * be assigned to port 0 as "SHIELD Virtual Controller". When a real
+    * controller is detected it will overwrite the virtual controller
+    * and be grouped with the NVIDIA button of the virtual device.
+    *
+    */
+   if (strstr(device_model, "SHIELD Android TV") && (
+           strstr(device_name, "Virtual") ||
+           strstr(device_name, "NVIDIA Corporation NVIDIA Controller v01.0")))
+   {
+      /* only use the hack if the device is one of the built-in devices */
+      RARCH_LOG("Special Device Detected: %s\n", device_model);
+      {
+#if 0
+         RARCH_LOG("- Pads Mapped: %d\n- Device Name: %s\n- IDS: %d, %d, %d",
+               android->pads_connected, device_name, id, pad_id1, pad_id2);
+#endif
+         /* Remove the remote or virtual controller device if it is mapped */
+         if (strstr(android->pad_states[0].name,"SHIELD Remote") ||
+             strstr(android->pad_states[0].name,"SHIELD Virtual Controller"))
+         {
+            pad_id1 = -1;
+            pad_id2 = -1;
+            android->pads_connected = 0;
+            port = 0;
+            strlcpy(name_buf, device_name, sizeof(name_buf));
+         }
+
+         /* if the actual controller has not been mapped yet,
+          * then configure Virtual device for now */
+         if (strstr(device_name, "Virtual") && android->pads_connected==0)
+            strlcpy (name_buf, "SHIELD Virtual Controller", sizeof(name_buf));
+         else
+            strlcpy (name_buf, "NVIDIA SHIELD Controller", sizeof(name_buf));
+
+         /* apply the hack only for the first controller
+          * store the id for later use
+         */
+         if (strstr(device_name, "NVIDIA Corporation NVIDIA Controller v01.0")
+             && android->pads_connected==0)
+            pad_id1 = id;
+         else if (strstr(device_name, "Virtual") && pad_id1 != -1)
+         {
+            id = pad_id1;
+            return;
+         }
+      }
+   }
+
+   else if (strstr(device_model, "SHIELD") && (
+           strstr(device_name, "Virtual") || strstr(device_name, "gpio") ||
+           strstr(device_name, "NVIDIA Corporation NVIDIA Controller v01.01") ||
+           strstr(device_name, "NVIDIA Corporation NVIDIA Controller v01.02")))
+   {
+      /* only use the hack if the device is one of the built-in devices */
+      RARCH_LOG("Special Device Detected: %s\n", device_model);
+      {
+         if ( pad_id1 < 0 )
+            pad_id1 = id;
+         else
+            pad_id2 = id;
+
+         if ( pad_id2 > 0)
+            return;
+         strlcpy (name_buf, "NVIDIA SHIELD Portable", sizeof(name_buf));
+      }
+   }
+
+   else if (strstr(device_model, "SHIELD") && (
+           strstr(device_name, "Virtual") || strstr(device_name, "gpio") ||
+           strstr(device_name, "NVIDIA Corporation NVIDIA Controller v01.03")))
+   {
+      /* only use the hack if the device is one of the built-in devices */
+      RARCH_LOG("Special Device Detected: %s\n", device_model);
+      {
+         if (strstr(device_name, "NVIDIA Corporation NVIDIA Controller v01.03")
+             && android->pads_connected==0)
+            pad_id1 = id;
+         else if (strstr(device_name, "Virtual") || strstr(device_name, "gpio"))
+         {
+            id = pad_id1;
+            return;
+         }
+         strlcpy (name_buf, "NVIDIA SHIELD Gamepad", sizeof(name_buf));
+      }
+   }
+
+      /* Other ATV Devices
+       * Add other common ATV devices that will follow the Android
+       * Gaempad convention as "Android Gamepad"
+       */
+      /* to-do: add DS4 on Bravia ATV */
+   else if (strstr(device_name, "NVIDIA"))
+      strlcpy (name_buf, "Android Gamepad", sizeof(name_buf));
+
+      /* GPD XD
+       * This is a simple hack, basically groups the "back"
+       * button with the rest of the gamepad
+       */
+   else if (strstr(device_model, "XD") && (
+           strstr(device_name, "Virtual") || strstr(device_name, "rk29-keypad") ||
+           strstr(device_name,"Playstation3") || strstr(device_name,"XBOX")))
+   {
+      /* only use the hack if the device is one of the built-in devices */
+      RARCH_LOG("Special Device Detected: %s\n", device_model);
+      {
+         if ( pad_id1 < 0 )
+            pad_id1 = id;
+         else
+            pad_id2 = id;
+
+         if ( pad_id2 > 0)
+            return;
+
+         strlcpy (name_buf, "GPD XD", sizeof(name_buf));
+         port = 0;
+      }
+   }
+
+      /* XPERIA Play
+       * This device is composed of two hid devices
+       * We make it look like one device
+       */
+   else if (
+           (
+                   string_starts_with_size(device_model, "R800", STRLEN_CONST("R800")) ||
+                   strstr(device_model, "Xperia Play") ||
+                   strstr(device_model, "Play") ||
+                   strstr(device_model, "SO-01D")
+           ) || (
+                   strstr(device_name, "keypad-game-zeus") ||
+                   strstr(device_name, "keypad-zeus") ||
+                   strstr(device_name, "Android Gamepad")
+           )
+           )
+   {
+      /* only use the hack if the device is one of the built-in devices */
+      RARCH_LOG("Special Device Detected: %s\n", device_model);
+      {
+         if ( pad_id1 < 0 )
+            pad_id1 = id;
+         else
+            pad_id2 = id;
+
+         if ( pad_id2 > 0)
+            return;
+
+         strlcpy (name_buf, "XPERIA Play", sizeof(name_buf));
+         port = 0;
+      }
+   }
+
+      /* ARCHOS Gamepad
+       * This device is composed of two hid devices
+       * We make it look like one device
+       */
+   else if (strstr(device_model, "ARCHOS GAMEPAD") && (
+           strstr(device_name, "joy_key") || strstr(device_name, "joystick")))
+   {
+      /* only use the hack if the device is one of the built-in devices */
+      RARCH_LOG("ARCHOS GAMEPAD Detected: %s\n", device_model);
+      {
+         if ( pad_id1 < 0 )
+            pad_id1 = id;
+         else
+            pad_id2 = id;
+
+         if ( pad_id2 > 0)
+            return;
+
+         strlcpy (name_buf, "ARCHOS GamePad", sizeof(name_buf));
+         port = 0;
+      }
+   }
+
+      /* Amazon Fire TV & Fire stick */
+   else if (
+           string_starts_with_size(device_model, "AFT", STRLEN_CONST("AFT")) &&
+           (
+                   strstr(device_model, "AFTB") ||
+                   strstr(device_model, "AFTT") ||
+                   strstr(device_model, "AFTS") ||
+                   strstr(device_model, "AFTM") ||
+                   strstr(device_model, "AFTRS")
+           )
+           )
+   {
+      RARCH_LOG("Special Device Detected: %s\n", device_model);
+      {
+         /* always map remote to port #0 */
+         if (strstr(device_name, "Amazon Fire TV Remote"))
+         {
+            android->pads_connected = 0;
+            port = 0;
+            strlcpy(name_buf, device_name, sizeof(name_buf));
+         }
+            /* remove the remote when a gamepad enters */
+         else if (strstr(android->pad_states[0].name,"Amazon Fire TV Remote"))
+         {
+            android->pads_connected = 0;
+            port = 0;
+            strlcpy(name_buf, device_name, sizeof(name_buf));
+         }
+         else
+            strlcpy(name_buf, device_name, sizeof(name_buf));
+      }
+   }
+
+      /* Other uncommon devices
+       * These are mostly remote control type devices, bind them always to port 0
+       * And overwrite the binding whenever a controller button is pressed
+       */
+   else if (strstr(device_name, "Amazon Fire TV Remote")
+            || strstr(device_name, "Nexus Remote")
+            || strstr(device_name, "SHIELD Remote"))
+   {
+      android->pads_connected = 0;
+      port = 0;
+      strlcpy(name_buf, device_name, sizeof(name_buf));
+   }
+
+   else if (strstr(device_name, "iControlPad-"))
+      strlcpy(name_buf, "iControlPad HID Joystick profile", sizeof(name_buf));
+
+   else if (strstr(device_name, "TTT THT Arcade console 2P USB Play"))
+   {
+      if (port == 0)
+         strlcpy(name_buf, "TTT THT Arcade (User 1)", sizeof(name_buf));
+      else if (port == 1)
+         strlcpy(name_buf, "TTT THT Arcade (User 2)", sizeof(name_buf));
+   }
+   else if (strstr(device_name, "MOGA"))
+      strlcpy(name_buf, "Moga IME", sizeof(name_buf));
+
+      /* If device is keyboard only and didn't match any of the devices above
+       * then assume it is a keyboard, register the id, and return unless the
+       * maximum number of keyboards are already registered. */
+   else if (source == AINPUT_SOURCE_KEYBOARD && kbd_num < MAX_NUM_KEYBOARDS)
+   {
+      kbd_id[kbd_num] = id;
+      kbd_num++;
+      return;
+   }
+
+      /* If the device is a keyboard, didn't match any of the devices above
+       * and is designated as the physical keyboard, then assume it is a keyboard,
+       * register the id, and return unless the
+       * maximum number of keyboards are already registered. */
+   else if ((source & AINPUT_SOURCE_KEYBOARD) && kbd_num < MAX_NUM_KEYBOARDS &&
+            is_configured_as_physical_keyboard(vendorId, productId, device_name))
+   {
+      kbd_id[kbd_num] = id;
+      kbd_num++;
+      return;
+   }
+
+      /* if device was not keyboard only, yet did not match any of the devices
+       * then try to autoconfigure as gamepad based on device_name. */
+   else if (!string_is_empty(device_name))
+      strlcpy(name_buf, device_name, sizeof(name_buf));
+
+   if (strstr(android_app->current_ime, "net.obsidianx.android.mogaime"))
+      strlcpy(name_buf, android_app->current_ime, sizeof(name_buf));
+   else if (strstr(android_app->current_ime, "com.ccpcreations.android.WiiUseAndroid"))
+      strlcpy(name_buf, android_app->current_ime, sizeof(name_buf));
+   else if (strstr(android_app->current_ime, "com.hexad.bluezime"))
+      strlcpy(name_buf, android_app->current_ime, sizeof(name_buf));
+
+   if (port < 0) {
+      for (int i = 0; i < MAX_USERS; ++i) {
+         if (android->pad_states[i].id == -1) {
+            port = i;
+            break;
+         }
+      }
+
+      if (port < 0) {
+         return;
+      }
+   }
+
+   input_autoconfigure_connect(
+           name_buf,
+           NULL,
+           android_joypad.ident,
+           port,
+           vendorId,
+           productId);
+
+   android->pad_states[port].id = id;
+   android_app->id[port] = id;
+   android->pad_states[port].port = port;
+
+   strlcpy(android->pad_states[port].name, name_buf,
+           sizeof(android->pad_states[port].name));
+
+   android->pads_connected++;
+}
+
+JNIEXPORT void JNICALL
+Java_com_xugame_app_JoypadManager_removeJoystickNative(
+        JNIEnv *env, jclass clazz,
+        jint id
+) {
+   struct android_app   *android_app = (struct android_app*)g_android;
+   input_driver_state_t *input_st    = input_state_get_ptr();
+   android_input_t      *android     = (android_input_t*)input_st->current_data;
+   int                   port        = -1;
+
+   for (int i = 0; i < MAX_USERS; ++i) {
+      if (android->pad_states[i].id == id) {
+         port = i;
+         break;
+      }
+   }
+
+   if (port < 0) {
+      return;
+   }
+
+   input_autoconfigure_disconnect(
+           port,
+           android_joypad.ident
+   );
+
+   android->pad_states[port].id = -1;
+   android_app->id[port] = -1;
+   android->pad_states[port].port = -1;
+   android->pad_states[port].name[0] = '\0';
+
+   android->pads_connected--;
+}
+
+static void *android_joypad_init(void *data) {
+   struct android_app *android_app = (struct android_app*)g_android;
+   JNIEnv                     *env  = jni_thread_getenv();
+
+   if (!env)
+      return NULL;
+
+   CALL_VOID_STATIC_METHOD(
+           env,
+           android_app->beans.joypad_manager.clazz,
+           android_app->beans.joypad_manager.initialize
+   );
+
+   return (void*)-1;
+}
 
 static int32_t android_joypad_button_state(
       struct android_app *android_app,
@@ -134,7 +526,20 @@ static int16_t android_joypad_state(
    return ret;
 }
 
-static void android_joypad_poll(void) { }
+// todo: add 3 second detect delay
+static void android_joypad_poll(void) {
+   struct android_app *android_app = (struct android_app*)g_android;
+   JNIEnv                     *env  = jni_thread_getenv();
+
+   if (!env)
+      return;
+
+   CALL_VOID_STATIC_METHOD(
+           env,
+           android_app->beans.joypad_manager.clazz,
+           android_app->beans.joypad_manager.pollInputDevices
+   );
+}
 
 static bool android_joypad_query_pad(unsigned pad)
 {
@@ -145,6 +550,7 @@ static void android_joypad_destroy(void)
 {
    unsigned i, j;
    struct android_app *android_app = (struct android_app*)g_android;
+   JNIEnv                     *env = jni_thread_getenv();
 
    for (i = 0; i < DEFAULT_MAX_PADS; i++)
    {
@@ -154,13 +560,21 @@ static void android_joypad_destroy(void)
          android_app->analog_state[i][j] = 0;
    }
 
-   for (i = 0; i < MAX_USERS; i++)
-   {
+   for (i = 0; i < MAX_USERS; i++) {
       android_app->rumble_last_strength_strong[i] = 0;
       android_app->rumble_last_strength_weak  [i] = 0;
       android_app->rumble_last_strength       [i] = 0;
       android_app->id                         [i] = 0;
    }
+
+   if (!env)
+      return;
+
+   CALL_VOID_STATIC_METHOD(
+           env,
+           android_app->beans.joypad_manager.clazz,
+           android_app->beans.joypad_manager.uninitialize
+   );
 }
 
 static void android_input_set_rumble_internal(

+ 0 - 32
app/src/main/cpp/input/include/gamepad.h

@@ -1,32 +0,0 @@
-/*  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 <http://www.gnu.org/licenses/>.
- */
-
-#ifndef GAMEPAD_H__
-#define GAMEPAD_H__
-
-#include "../input_driver.h"
-
-typedef struct _axis_data
-{
-   int32_t axis;
-   bool is_negative;
-} axis_data;
-
-void gamepad_read_axis_data(uint32_t axis, axis_data *data);
-int16_t gamepad_get_axis_value(int16_t state[3][2], axis_data *data);
-int16_t gamepad_get_axis_value_raw(int16_t state[3][2], axis_data *data, bool do_clamp);
-#endif /* GAMEPAD_H__ */

+ 0 - 60
app/src/main/cpp/input/include/hid_driver.h

@@ -1,60 +0,0 @@
-/*  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 <http://www.gnu.org/licenses/>.
- */
-
-#ifndef HID_DRIVER_H__
-#define HID_DRIVER_H__
-
-#include "../connect/joypad_connection.h"
-#include "../input_driver.h"
-
-/* what is 1? */
-#define HID_REPORT_INPUT   1
-#define HID_REPORT_OUTPUT  2
-#define HID_REPORT_FEATURE 3
-#define HID_REPORT_COUNT   4
-/* are there more? */
-
-/*
- * This is the interface for the HID subsystem.
- *
- * The handle parameter is the pointer returned by init() and stores the implementation
- * state data for the HID driver.
- */
-
-struct hid_driver
-{
-   void *(*init)(void);
-   bool (*query_pad)(void *handle, unsigned pad);
-   void (*free)(const void *handle);
-   int16_t (*button)(void *handle, unsigned pad, uint16_t button);
-   int16_t (*state)(void *data, rarch_joypad_info_t *joypad_info,
-         const void *binds_data, unsigned port);
-   void (*get_buttons)(void *handle, unsigned pad, input_bits_t *state);
-   int16_t (*axis)(void *handle, unsigned pad, uint32_t axis);
-   void (*poll)(void *handle);
-   bool (*set_rumble)(void *handle, unsigned pad, enum retro_rumble_effect effect, uint16_t);
-   const char *(*name)(void *handle, unsigned pad);
-   const char *ident;
-   void (*send_control)(void *handle, uint8_t *buf, size_t size);
-   int32_t (*set_report)(void *handle, uint8_t report_type, uint8_t report_id, uint8_t *data, size_t length);
-   int32_t (*get_report)(void *handle, uint8_t report_type, uint8_t report_id, uint8_t *data, size_t length);
-   int32_t (*set_idle)(void *handle, uint8_t amount);
-   int32_t (*set_protocol)(void *handle, uint8_t protocol);
-   int32_t (*read)(void *handle, void *buf, size_t size);
-};
-
-#endif /* HID_DRIVER_H__ */

+ 0 - 23
app/src/main/cpp/input/include/hid_types.h

@@ -1,23 +0,0 @@
-/*  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 <http://www.gnu.org/licenses/>.
- */
-
-#ifndef HID_TYPES_H__
-#define HID_TYPES_H__
-
-typedef struct hid_driver hid_driver_t;
-
-#endif /* HID_TYPES_H__ */

+ 24 - 198
app/src/main/cpp/input/input_driver.c

@@ -172,220 +172,22 @@ static input_device_driver_t null_joypad = {
    "null",
 };
 
-
-#ifdef HAVE_HID
-static bool null_hid_joypad_query(void *data, unsigned pad) {
-   return pad < MAX_USERS; }
-static const char *null_hid_joypad_name(
-      void *data, unsigned pad) { return NULL; }
-static void null_hid_joypad_get_buttons(void *data,
-      unsigned port, input_bits_t *state) { BIT256_CLEAR_ALL_PTR(state); }
-static int16_t null_hid_joypad_button(
-      void *data, unsigned port, uint16_t joykey) { return 0; }
-static bool null_hid_joypad_rumble(void *data, unsigned pad,
-      enum retro_rumble_effect effect, uint16_t strength) { return false; }
-static int16_t null_hid_joypad_axis(
-      void *data, unsigned port, uint32_t joyaxis) { return 0; }
-static void *null_hid_init(void) { return (void*)-1; }
-static void null_hid_free(const void *data) { }
-static void null_hid_poll(void *data) { }
-static int16_t null_hid_joypad_state(
-      void *data,
-      rarch_joypad_info_t *joypad_info,
-      const void *binds_data,
-      unsigned port) { return 0; }
-
-static hid_driver_t null_hid = {
-   null_hid_init,               /* init */
-   null_hid_joypad_query,       /* joypad_query */
-   null_hid_free,               /* free */
-   null_hid_joypad_button,      /* button */
-   null_hid_joypad_state,       /* state */
-   null_hid_joypad_get_buttons, /* get_buttons */
-   null_hid_joypad_axis,        /* axis */
-   null_hid_poll,               /* poll */
-   null_hid_joypad_rumble,      /* rumble */
-   null_hid_joypad_name,        /* joypad_name */
-   "null",
-};
-#endif
-
 input_device_driver_t *joypad_drivers[] = {
-#ifdef HAVE_XINPUT
-   &xinput_joypad,
-#endif
-#ifdef GEKKO
-   &gx_joypad,
-#endif
-#ifdef WIIU
-   &wiiu_joypad,
-#endif
-#ifdef _XBOX1
-   &xdk_joypad,
-#endif
-#if defined(ORBIS)
-   &ps4_joypad,
-#endif
-#if defined(__PSL1GHT__) || defined(__PS3__)
-   &ps3_joypad,
-#endif
-#if defined(PSP) || defined(VITA)
-   &psp_joypad,
-#endif
-#if defined(PS2)
-   &ps2_joypad,
-#endif
-#ifdef _3DS
-   &ctr_joypad,
-#endif
-#ifdef SWITCH
-   &switch_joypad,
-#endif
-#ifdef HAVE_DINPUT
-   &dinput_joypad,
-#endif
-#ifdef HAVE_UDEV
-   &udev_joypad,
-#endif
-#if defined(__linux) && !defined(ANDROID)
-   &linuxraw_joypad,
-#endif
-#ifdef HAVE_PARPORT
-   &parport_joypad,
-#endif
 #ifdef ANDROID
    &android_joypad,
-#endif
-#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
-#ifdef HAVE_MFI
-   &mfi_joypad,
-#endif
-#ifdef DJGPP
-   &dos_joypad,
-#endif
-/* Selecting the HID gamepad driver disables the Wii U gamepad. So while
- * we want the HID code to be compiled & linked, we don't want the driver
- * to be selectable in the UI. */
-#if defined(HAVE_HID) && !defined(WIIU)
-   &hid_joypad,
-#endif
-#ifdef EMSCRIPTEN
-   &rwebpad_joypad,
 #endif
    &null_joypad,
    NULL,
 };
 
 input_driver_t *input_drivers[] = {
-#ifdef ORBIS
-   &input_ps4,
-#endif
-#if defined(__PSL1GHT__) || defined(__PS3__)
-   &input_ps3,
-#endif
-#if defined(SN_TARGET_PSP2) || defined(PSP) || defined(VITA)
-   &input_psp,
-#endif
-#if defined(PS2)
-   &input_ps2,
-#endif
-#if defined(_3DS)
-   &input_ctr,
-#endif
-#if defined(SWITCH)
-   &input_switch,
-#endif
-#ifdef HAVE_X11
-   &input_x,
-#endif
-#ifdef HAVE_WAYLAND
-   &input_wayland,
-#endif
-#ifdef __WINRT__
-   &input_uwp,
-#endif
-#ifdef XENON
-   &input_xenon360,
-#endif
-#if defined(_WIN32) && !defined(_XBOX) && _WIN32_WINNT >= 0x0501 && !defined(__WINRT__)
-#ifdef HAVE_WINRAWINPUT
-   /* winraw only available since XP */
-   &input_winraw,
-#endif
-#endif
-#if defined(HAVE_XINPUT2) || defined(HAVE_XINPUT_XBOX1) || defined(__WINRT__)
-   &input_xinput,
-#endif
-#ifdef HAVE_DINPUT
-   &input_dinput,
-#endif
-#if defined(HAVE_SDL) || defined(HAVE_SDL2)
-   &input_sdl,
-#endif
-#if defined(DINGUX) && defined(HAVE_SDL_DINGUX)
-   &input_sdl_dingux,
-#endif
-#ifdef GEKKO
-   &input_gx,
-#endif
-#ifdef WIIU
-   &input_wiiu,
-#endif
 #ifdef ANDROID
    &input_android,
-#endif
-#ifdef HAVE_UDEV
-   &input_udev,
-#endif
-#if defined(__linux__) && !defined(ANDROID)
-   &input_linuxraw,
-#endif
-#if defined(HAVE_COCOA) || defined(HAVE_COCOATOUCH) || defined(HAVE_COCOA_METAL)
-   &input_cocoa,
-#endif
-#ifdef __QNX__
-   &input_qnx,
-#endif
-#ifdef EMSCRIPTEN
-   &input_rwebinput,
-#endif
-#ifdef DJGPP
-   &input_dos,
 #endif
    &input_null,
    NULL,
 };
 
-#ifdef HAVE_HID
-hid_driver_t *hid_drivers[] = {
-#if defined(HAVE_BTSTACK)
-   &btstack_hid,
-#endif
-#if defined(__APPLE__) && defined(HAVE_IOHIDMANAGER)
-   &iohidmanager_hid,
-#endif
-#if defined(HAVE_LIBUSB) && defined(HAVE_THREADS)
-   &libusb_hid,
-#endif
-#ifdef HW_RVL
-   &wiiusb_hid,
-#endif
-#if defined(WIIU)
-   &wiiu_hid,
-#endif
-   &null_hid,
-   NULL,
-};
-#endif
-
 static input_driver_state_t input_driver_st = {}; /* double alignment */
 
 /**************************************/
@@ -3275,6 +3077,30 @@ bool video_driver_init_input(
    return true;
 }
 
+void video_driver_free_input()
+{
+   input_driver_state_t *input_st    = input_state_get_ptr();
+   if (input_st->primary_joypad)
+      if (input_st->primary_joypad->destroy)
+         input_st->primary_joypad->destroy();
+   input_st->primary_joypad    = NULL;
+
+   if (input_st->current_driver)
+      if (input_st->current_driver->free)
+         input_st->current_driver->free(input_st->current_data);
+   input_st->current_driver    = NULL;
+   input_st->current_data      = NULL;
+#ifdef HAVE_MFI
+   if (input_st->secondary_joypad)
+      {
+         const input_device_driver_t *tmp   = input_st->secondary_joypad;
+         input_st->secondary_joypad         = NULL;
+         tmp->destroy();
+      }
+#endif
+   input_st->flags &= ~INP_FLAG_KB_MAPPING_BLOCKED;
+}
+
 bool input_driver_grab_mouse(void)
 {
    if (!input_driver_st.current_driver || !input_driver_st.current_driver->grab_mouse)

+ 1 - 98
app/src/main/cpp/input/input_driver.h

@@ -40,58 +40,13 @@
 #include "input_osk.h"
 
 #include "../msg_hash.h"
-#include "include/hid_types.h"
-// #include "include/hid_driver.h"
 // #include "include/gamepad.h"
 #include "../configuration.h"
 #include "../performance_counters.h"
 
-#ifdef HAVE_COMMAND
-#include "../command.h"
-#endif
-
 #if defined(ANDROID)
 #define DEFAULT_MAX_PADS 8
 #define ANDROID_KEYBOARD_PORT DEFAULT_MAX_PADS
-#elif defined(_3DS)
-#define DEFAULT_MAX_PADS 1
-#elif defined(SWITCH) || defined(HAVE_LIBNX)
-#define DEFAULT_MAX_PADS 8
-#elif defined(WIIU)
-#ifdef WIIU_HID
-#define DEFAULT_MAX_PADS 16
-#else
-#define DEFAULT_MAX_PADS 5
-#endif /* WIIU_HID */
-#elif defined(DJGPP)
-#define DEFAULT_MAX_PADS 1
-#define DOS_KEYBOARD_PORT DEFAULT_MAX_PADS
-#elif defined(XENON)
-#define DEFAULT_MAX_PADS 4
-#elif defined(VITA) || defined(SN_TARGET_PSP2) || defined(ORBIS)
-#define DEFAULT_MAX_PADS 4
-#elif defined(PSP)
-#define DEFAULT_MAX_PADS 1
-#elif defined(PS2)
-#define DEFAULT_MAX_PADS 8
-#elif defined(GEKKO) || defined(HW_RVL)
-#define DEFAULT_MAX_PADS 4
-#elif defined(HAVE_ODROIDGO2)
-#define DEFAULT_MAX_PADS 8
-#elif defined(__linux__) || (defined(BSD) && !defined(__MACH__))
-#define DEFAULT_MAX_PADS 8
-#elif defined(__QNX__)
-#define DEFAULT_MAX_PADS 8
-#elif defined(__PS3__)
-#define DEFAULT_MAX_PADS 7
-#elif defined(_XBOX)
-#define DEFAULT_MAX_PADS 4
-#elif defined(HAVE_XINPUT) && !defined(HAVE_DINPUT)
-#define DEFAULT_MAX_PADS 4
-#elif defined(DINGUX)
-#define DEFAULT_MAX_PADS 2
-#else
-#define DEFAULT_MAX_PADS 16
 #endif /* defined(ANDROID) */
 
 #define MAPPER_GET_KEY(state, key) (((state)->keys[(key) / 32] >> ((key) % 32)) & 1)
@@ -598,6 +553,7 @@ bool video_driver_init_input(
       input_driver_t *tmp,
       settings_t *settings,
       bool verbosity_enabled);
+void video_driver_free_input();
 
 bool input_driver_grab_mouse(void);
 
@@ -1068,60 +1024,7 @@ extern hid_driver_t *hid_drivers[];
 #endif
 
 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;
-extern input_driver_t input_ps3;
-extern input_driver_t input_psp;
-extern input_driver_t input_ps2;
-extern input_driver_t input_ctr;
-extern input_driver_t input_switch;
-extern input_driver_t input_xenon360;
-extern input_driver_t input_gx;
-extern input_driver_t input_wiiu;
-extern input_driver_t input_xinput;
-extern input_driver_t input_uwp;
-extern input_driver_t input_linuxraw;
-extern input_driver_t input_udev;
-extern input_driver_t input_cocoa;
-extern input_driver_t input_qnx;
-extern input_driver_t input_rwebinput;
-extern input_driver_t input_dos;
-extern input_driver_t input_winraw;
-extern input_driver_t input_wayland;
-
-extern input_device_driver_t dinput_joypad;
-extern input_device_driver_t linuxraw_joypad;
-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;
-extern input_device_driver_t ps2_joypad;
-extern input_device_driver_t ctr_joypad;
-extern input_device_driver_t switch_joypad;
-extern input_device_driver_t xdk_joypad;
-extern input_device_driver_t gx_joypad;
-extern input_device_driver_t wiiu_joypad;
-extern input_device_driver_t hid_joypad;
 extern input_device_driver_t android_joypad;
-extern input_device_driver_t qnx_joypad;
-extern input_device_driver_t mfi_joypad;
-extern input_device_driver_t dos_joypad;
-extern input_device_driver_t rwebpad_joypad;
-
-#ifdef HAVE_HID
-extern hid_driver_t iohidmanager_hid;
-extern hid_driver_t btstack_hid;
-extern hid_driver_t libusb_hid;
-extern hid_driver_t wiiusb_hid;
-extern hid_driver_t wiiu_hid;
-#endif /* HAVE_HID */
 
 RETRO_END_DECLS
 

+ 0 - 408
app/src/main/cpp/input/input_overlay.h

@@ -1,408 +0,0 @@
-/*  RetroArch - A frontend for libretro.
- *  Copyright (C) 2010-2014 - Hans-Kristian Arntzen
- *  Copyright (C) 2011-2017 - Daniel De Matteis
- *
- *  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/>.
- */
-
-#ifndef INPUT_OVERLAY_H__
-#define INPUT_OVERLAY_H__
-
-#include <stdint.h>
-#include <boolean.h>
-
-#include <retro_common_api.h>
-#include <retro_miscellaneous.h>
-#include <formats/image.h>
-#include <queues/task_queue.h>
-
-#include "input_types.h"
-
-#define OVERLAY_GET_KEY(state, key) (((state)->keys[(key) / 32] >> ((key) % 32)) & 1)
-#define OVERLAY_SET_KEY(state, key) (state)->keys[(key) / 32] |= 1 << ((key) % 32)
-
-#define MAX_VISIBILITY 32
-
-#define CUSTOM_BINDS_U32_COUNT ((RARCH_CUSTOM_BIND_LIST_END - 1) / 32 + 1)
-
-RETRO_BEGIN_DECLS
-
-/* Overlay driver acts as a medium between input drivers
- * and video driver.
- *
- * Coordinates are fetched from input driver, and an
- * overlay with pressable actions are displayed on-screen.
- *
- * This interface requires that the video driver has support
- * for the overlay interface.
- */
-
-typedef struct video_overlay_interface
-{
-   void (*enable)(void *data, bool state);
-   bool (*load)(void *data,
-         const void *images, unsigned num_images);
-   void (*tex_geom)(void *data, unsigned image,
-         float x, float y, float w, float h);
-   void (*vertex_geom)(void *data, unsigned image,
-         float x, float y, float w, float h);
-   void (*full_screen)(void *data, bool enable);
-   void (*set_alpha)(void *data, unsigned image, float mod);
-} video_overlay_interface_t;
-
-enum overlay_hitbox
-{
-   OVERLAY_HITBOX_RADIAL = 0,
-   OVERLAY_HITBOX_RECT,
-   OVERLAY_HITBOX_NONE
-};
-
-enum overlay_type
-{
-   OVERLAY_TYPE_BUTTONS = 0,
-   OVERLAY_TYPE_ANALOG_LEFT,
-   OVERLAY_TYPE_ANALOG_RIGHT,
-   OVERLAY_TYPE_DPAD_AREA,
-   OVERLAY_TYPE_ABXY_AREA,
-   OVERLAY_TYPE_KEYBOARD
-};
-
-enum overlay_status
-{
-   OVERLAY_STATUS_NONE = 0,
-   OVERLAY_STATUS_DEFERRED_LOAD,
-   OVERLAY_STATUS_DEFERRED_LOADING_IMAGE,
-   OVERLAY_STATUS_DEFERRED_LOADING_IMAGE_PROCESS,
-   OVERLAY_STATUS_DEFERRED_LOADING,
-   OVERLAY_STATUS_DEFERRED_LOADING_RESOLVE,
-   OVERLAY_STATUS_DEFERRED_DONE,
-   OVERLAY_STATUS_DEFERRED_ERROR
-};
-
-enum overlay_image_transfer_status
-{
-   OVERLAY_IMAGE_TRANSFER_NONE = 0,
-   OVERLAY_IMAGE_TRANSFER_BUSY,
-   OVERLAY_IMAGE_TRANSFER_DONE,
-   OVERLAY_IMAGE_TRANSFER_DESC_IMAGE_ITERATE,
-   OVERLAY_IMAGE_TRANSFER_DESC_ITERATE,
-   OVERLAY_IMAGE_TRANSFER_DESC_DONE,
-   OVERLAY_IMAGE_TRANSFER_ERROR
-};
-
-enum overlay_visibility
-{
-   OVERLAY_VISIBILITY_DEFAULT = 0,
-   OVERLAY_VISIBILITY_VISIBLE,
-   OVERLAY_VISIBILITY_HIDDEN
-};
-
-enum overlay_orientation
-{
-   OVERLAY_ORIENTATION_NONE = 0,
-   OVERLAY_ORIENTATION_LANDSCAPE,
-   OVERLAY_ORIENTATION_PORTRAIT
-};
-
-enum overlay_show_input_type
-{
-   OVERLAY_SHOW_INPUT_NONE = 0,
-   OVERLAY_SHOW_INPUT_TOUCHED,
-   OVERLAY_SHOW_INPUT_PHYSICAL,
-   OVERLAY_SHOW_INPUT_LAST
-};
-
-enum OVERLAY_LOADER_FLAGS
-{
-   OVERLAY_LOADER_ENABLE                      = (1 << 0),
-   OVERLAY_LOADER_HIDE_IN_MENU                = (1 << 1),
-   OVERLAY_LOADER_HIDE_WHEN_GAMEPAD_CONNECTED = (1 << 2),
-   OVERLAY_LOADER_RGBA_SUPPORT                = (1 << 3)
-};
-
-enum INPUT_OVERLAY_FLAGS
-{
-   INPUT_OVERLAY_ENABLE  = (1 << 0),
-   INPUT_OVERLAY_ALIVE   = (1 << 1),
-   INPUT_OVERLAY_BLOCKED = (1 << 2)
-};
-
-enum OVERLAY_FLAGS
-{
-   OVERLAY_FULL_SCREEN        = (1 << 0),
-   OVERLAY_BLOCK_SCALE        = (1 << 1),
-   OVERLAY_BLOCK_X_SEPARATION = (1 << 2),
-   OVERLAY_BLOCK_Y_SEPARATION = (1 << 3),
-   OVERLAY_AUTO_X_SEPARATION  = (1 << 4),
-   OVERLAY_AUTO_Y_SEPARATION  = (1 << 5)
-};
-
-enum OVERLAY_DESC_FLAGS
-{
-   OVERLAY_DESC_MOVABLE             = (1 << 0),
-   /* If true, blocks input from overlapped hitboxes */
-   OVERLAY_DESC_EXCLUSIVE           = (1 << 1),
-   /* Similar, but only applies after range_mod takes effect */
-   OVERLAY_DESC_RANGE_MOD_EXCLUSIVE = (1 << 2)
-};
-
-typedef struct overlay_eightway_config
-{
-   input_bits_t up;
-   input_bits_t right;
-   input_bits_t down;
-   input_bits_t left;
-
-   input_bits_t up_right;
-   input_bits_t up_left;
-   input_bits_t down_right;
-   input_bits_t down_left;
-
-   /* diagonal sensitivity */
-   float* slope_high;
-   float* slope_low;
-} overlay_eightway_config_t;
-
-struct overlay_desc
-{
-   struct texture_image image;
-
-   enum overlay_hitbox hitbox;
-   enum overlay_type type;
-
-   unsigned next_index;
-   unsigned image_index;
-
-   float alpha_mod;
-   float range_mod;
-   float analog_saturate_pct;
-   float range_x, range_y;
-   float range_x_mod, range_y_mod;
-   float mod_x, mod_y, mod_w, mod_h;
-   float delta_x, delta_y;
-   float x;
-   float y;
-   /* These are 'raw' x/y values shifted
-    * by a user-configured offset (c.f.
-    * OVERLAY_X/Y_SEPARATION). Used to determine
-    * correct hitbox locations. By default,
-    * will be equal to x/y */
-   float x_shift;
-   float y_shift;
-
-   /* These values are used only for hitbox
-    * detection. A hitbox can be stretched in
-    * any direction(s) by its 'reach' values */
-   float x_hitbox;
-   float y_hitbox;
-   float range_x_hitbox, range_y_hitbox;
-   float reach_right, reach_left, reach_up, reach_down;
-
-   /* This is a retro_key value for keyboards */
-   unsigned retro_key_idx;
-
-   /* This is a bit mask of all input binds to set with this overlay control */
-   input_bits_t button_mask;
-
-   overlay_eightway_config_t *eightway_config;
-
-   char next_index_name[64];
-
-   /* Nonzero if pressed. One bit per input pointer */
-   uint16_t updated;
-
-   uint8_t flags;
-};
-
-
-struct overlay
-{
-   struct overlay_desc *descs;
-   struct texture_image *load_images;
-
-   struct texture_image image;
-
-   unsigned load_images_size;
-   unsigned id;
-   unsigned pos_increment;
-
-   size_t size;
-   size_t pos;
-
-   float mod_x, mod_y, mod_w, mod_h;
-   float x, y, w, h;
-   float center_x, center_y;
-   float aspect_ratio;
-
-   struct
-   {
-      float alpha_mod;
-      float range_mod;
-
-      struct
-      {
-         unsigned size;
-         char key[64];
-      } descs;
-
-      struct
-      {
-         char key[64];
-         char path[PATH_MAX_LENGTH];
-      } paths;
-
-      struct
-      {
-         char key[64];
-      } names;
-
-      struct
-      {
-         char array[256];
-         char key[64];
-      } rect;
-
-      bool normalized;
-   } config;
-
-   char name[64];
-
-   uint8_t flags;
-};
-
-typedef struct input_overlay_state
-{
-   uint32_t keys[RETROK_LAST / 32 + 1];
-   /* Left X, Left Y, Right X, Right Y */
-   int16_t analog[4];
-   /* This is a bitmask of (1 << key_bind_id). */
-   input_bits_t buttons;
-} input_overlay_state_t;
-
-struct input_overlay
-{
-   struct overlay *overlays;
-   const struct overlay *active;
-   void *iface_data;
-   const video_overlay_interface_t *iface;
-   input_overlay_state_t overlay_state;
-
-   size_t index;
-   size_t size;
-
-   unsigned next_index;
-
-   enum overlay_status state;
-
-   uint8_t flags;
-};
-
-/* Holds general layout information for an
- * overlay (overall scaling + positional
- * offset factors) */
-typedef struct
-{
-   float scale_landscape;
-   float aspect_adjust_landscape;
-   float x_separation_landscape;
-   float y_separation_landscape;
-   float x_offset_landscape;
-   float y_offset_landscape;
-   float scale_portrait;
-   float aspect_adjust_portrait;
-   float x_separation_portrait;
-   float y_separation_portrait;
-   float x_offset_portrait;
-   float y_offset_portrait;
-   float touch_scale;
-   bool auto_scale;
-} overlay_layout_desc_t;
-
-/* Holds derived overlay layout information
- * for a specific display orientation */
-typedef struct
-{
-   float x_scale;
-   float y_scale;
-   float x_separation;
-   float y_separation;
-   float x_offset;
-   float y_offset;
-} overlay_layout_t;
-
-typedef struct overlay_desc overlay_desc_t;
-
-typedef struct input_overlay input_overlay_t;
-
-typedef struct
-{
-   struct overlay *overlays;
-   struct overlay *active;
-   size_t size;
-   float overlay_opacity;
-   overlay_layout_desc_t layout_desc;
-   uint16_t overlay_types;
-   uint8_t flags;
-} overlay_task_data_t;
-
-void input_overlay_free_overlay(struct overlay *overlay);
-
-void input_overlay_set_visibility(int overlay_idx,enum overlay_visibility vis);
-
-/* Attempts to automatically rotate the specified overlay.
- * Depends upon proper naming conventions in overlay
- * config file. */
-void input_overlay_auto_rotate_(
-      unsigned video_driver_width,
-      unsigned video_driver_height,
-      bool input_overlay_enable,
-      input_overlay_t *ol);
-
-void input_overlay_load_active(
-      enum overlay_visibility *visibility,
-      input_overlay_t *ol, float opacity);
-
-/**
- * input_overlay_set_scale_factor:
- * @ol                    : Overlay handle.
- * @layout_desc           : Scale + offset factors.
- *
- * Scales the overlay and applies any aspect ratio/
- * offset factors.
- **/
-void input_overlay_set_scale_factor(
-      input_overlay_t *ol, const overlay_layout_desc_t *layout_desc,
-      unsigned video_driver_width,
-      unsigned video_driver_height);
-
-/**
- * input_overlay_set_alpha_mod:
- * @ol                    : Overlay handle.
- * @mod                   : New modulating factor to apply.
- *
- * Sets a modulating factor for alpha channel. Default is 1.0.
- * The alpha factor is applied for all overlays.
- **/
-void input_overlay_set_alpha_mod(
-      enum overlay_visibility *visibility,
-      input_overlay_t *ol, float mod);
-
-/**
- * input_overlay_set_eightway_diagonal_sensitivity:
- *
- * Gets the slope limits defining each eightway type's diagonal zones.
- */
-void input_overlay_set_eightway_diagonal_sensitivity(void);
-
-RETRO_END_DECLS
-
-#endif

+ 1 - 1
app/src/main/cpp/retroarch.c

@@ -6547,7 +6547,7 @@ void retroarch_init_task_queue(void)
 #endif
 
    task_queue_deinit();
-   task_queue_init(threaded_enable, runloop_task_msg_queue_push);
+   task_queue_init(threaded_enable, NULL);
 }
 
 bool retroarch_ctl(enum rarch_ctl_state state, void *data)

+ 0 - 118
app/src/main/cpp/runloop.c

@@ -2059,124 +2059,6 @@ bool runloop_environment_cb(unsigned cmd, void *data)
             "L", "R", "L2", "R2", "L3", "R3",
          };
          android_environment_cb_native(cmd, data);
-
-         if (system)
-         {
-            unsigned retro_id;
-            const struct retro_input_descriptor *desc = NULL;
-            memset((void*)&system->input_desc_btn, 0,
-                  sizeof(system->input_desc_btn));
-
-            desc = (const struct retro_input_descriptor*)data;
-
-            for (; desc->description; desc++)
-            {
-               unsigned retro_port = desc->port;
-
-               retro_id            = desc->id;
-
-               if (desc->port >= MAX_USERS)
-                  continue;
-
-               if (desc->id >= RARCH_FIRST_CUSTOM_BIND)
-                  continue;
-
-               switch (desc->device)
-               {
-                  case RETRO_DEVICE_JOYPAD:
-                     system->input_desc_btn[retro_port]
-                        [retro_id] = desc->description;
-                     break;
-                  case RETRO_DEVICE_ANALOG:
-                     switch (retro_id)
-                     {
-                        case RETRO_DEVICE_ID_ANALOG_X:
-                           switch (desc->index)
-                           {
-                              case RETRO_DEVICE_INDEX_ANALOG_LEFT:
-                                 system->input_desc_btn[retro_port]
-                                    [RARCH_ANALOG_LEFT_X_PLUS]  = desc->description;
-                                 system->input_desc_btn[retro_port]
-                                    [RARCH_ANALOG_LEFT_X_MINUS] = desc->description;
-                                 break;
-                              case RETRO_DEVICE_INDEX_ANALOG_RIGHT:
-                                 system->input_desc_btn[retro_port]
-                                    [RARCH_ANALOG_RIGHT_X_PLUS] = desc->description;
-                                 system->input_desc_btn[retro_port]
-                                    [RARCH_ANALOG_RIGHT_X_MINUS] = desc->description;
-                                 break;
-                           }
-                           break;
-                        case RETRO_DEVICE_ID_ANALOG_Y:
-                           switch (desc->index)
-                           {
-                              case RETRO_DEVICE_INDEX_ANALOG_LEFT:
-                                 system->input_desc_btn[retro_port]
-                                    [RARCH_ANALOG_LEFT_Y_PLUS] = desc->description;
-                                 system->input_desc_btn[retro_port]
-                                    [RARCH_ANALOG_LEFT_Y_MINUS] = desc->description;
-                                 break;
-                              case RETRO_DEVICE_INDEX_ANALOG_RIGHT:
-                                 system->input_desc_btn[retro_port]
-                                    [RARCH_ANALOG_RIGHT_Y_PLUS] = desc->description;
-                                 system->input_desc_btn[retro_port]
-                                    [RARCH_ANALOG_RIGHT_Y_MINUS] = desc->description;
-                                 break;
-                           }
-                           break;
-                        case RETRO_DEVICE_ID_JOYPAD_R2:
-                           switch (desc->index)
-                           {
-                              case RETRO_DEVICE_INDEX_ANALOG_BUTTON:
-                                 system->input_desc_btn[retro_port]
-                                    [retro_id] = desc->description;
-                                 break;
-                           }
-                           break;
-                        case RETRO_DEVICE_ID_JOYPAD_L2:
-                           switch (desc->index)
-                           {
-                              case RETRO_DEVICE_INDEX_ANALOG_BUTTON:
-                                 system->input_desc_btn[retro_port]
-                                    [retro_id] = desc->description;
-                                 break;
-                           }
-                           break;
-                     }
-                     break;
-               }
-            }
-
-            RARCH_LOG("[Environ]: SET_INPUT_DESCRIPTORS:\n");
-
-            {
-               unsigned log_level      = settings->uints.libretro_log_level;
-
-               if (log_level == RETRO_LOG_DEBUG)
-               {
-                  unsigned input_driver_max_users = settings->uints.input_max_users;
-
-                  for (p = 0; p < input_driver_max_users; p++)
-                  {
-                     unsigned mapped_port = settings->uints.input_remap_ports[p];
-
-                     for (retro_id = 0; retro_id < RARCH_FIRST_CUSTOM_BIND; retro_id++)
-                     {
-                        const char *description = system->input_desc_btn[mapped_port][retro_id];
-
-                        if (!description)
-                           continue;
-
-                        RARCH_DBG("   RetroPad, Port %u, Button \"%s\" => \"%s\"\n",
-                              p + 1, libretro_btn_desc[retro_id], description);
-                     }
-                  }
-               }
-            }
-
-            runloop_st->current_core.flags |=
-               RETRO_CORE_FLAG_HAS_SET_INPUT_DESCRIPTORS;
-         }
          break;
       }
 

+ 2 - 5
app/src/main/cpp/tasks/task_content.c

@@ -1978,8 +1978,7 @@ bool task_push_start_dummy_core(content_ctx_info_t *content_info)
    retroarch_init_task_queue();
 
    /* Loads content into currently selected core. */
-   if ((ret = content_load(content_info, p_content)))
-      task_push_to_history_list(p_content, false, false, false);
+   ret = content_load(content_info, p_content);
 
    if (content_ctx.name_ips)
       free(content_ctx.name_ips);
@@ -2576,9 +2575,7 @@ static bool task_load_content_internal(
 #endif
 
    /* Loads content into currently selected core. */
-   if ((ret = content_load(content_info, p_content)))
-      task_push_to_history_list(p_content,
-            true, loading_from_cli, loading_from_companion_ui);
+   ret = content_load(content_info, p_content);
 
 end:
    if (content_ctx.name_ips)

+ 1 - 0
app/src/main/java/com/retroarch/browser/retroactivity/RetroActivityCommon.java

@@ -3,6 +3,7 @@ package com.retroarch.browser.retroactivity;
 import com.xugame.BuildConfig;
 import com.xugame.app.EnvironmentCallback;
 import com.xugame.app.EnvironmentCallbackCmd;
+import com.xugame.app.JoypadManager;
 import com.xugame.bean.InputDescriptorBean;
 import com.xugame.gameconsole.playcore.PlayCoreManager;
 import com.xugame.gameconsole.preferences.UserPreferences;

+ 138 - 0
app/src/main/java/com/xugame/app/JoypadManager.java

@@ -0,0 +1,138 @@
+package com.xugame.app;
+
+import android.view.InputDevice;
+import android.view.MotionEvent;
+
+import java.util.ArrayList;
+import java.util.HashSet;
+
+public class JoypadManager {
+    protected static JoypadHandler mJoystickHandler = null;
+    public static void initialize() {
+        if (mJoystickHandler == null) {
+            mJoystickHandler = new JoypadHandler_API();
+        }
+    }
+
+    public static void uninitialize() {
+        mJoystickHandler.removeInputDevices();
+        mJoystickHandler = null;
+    }
+
+    // Using for JNI
+    public static void pollInputDevices() {
+        mJoystickHandler.pollInputDevices();
+    }
+
+    // Check if a given device is considered a possible SDL joystick
+    public static boolean isDeviceJoystick(int deviceId) {
+        InputDevice device = InputDevice.getDevice(deviceId);
+        // We cannot use InputDevice.isVirtual before API 16, so let's accept
+        // only nonnegative device ids (VIRTUAL_KEYBOARD equals -1)
+        if ((device == null) || (deviceId < 0)) {
+            return false;
+        }
+
+        if (device.isVirtual()) {
+            return false;
+        }
+
+        int sources = device.getSources();
+
+        /* This is called for every button press, so let's not spam the logs */
+        /*
+        if ((sources & InputDevice.SOURCE_CLASS_JOYSTICK) != 0) {
+            Log.v(TAG, "Input device " + device.getName() + " has class joystick.");
+        }
+        if ((sources & InputDevice.SOURCE_DPAD) == InputDevice.SOURCE_DPAD) {
+            Log.v(TAG, "Input device " + device.getName() + " is a dpad.");
+        }
+        if ((sources & InputDevice.SOURCE_GAMEPAD) == InputDevice.SOURCE_GAMEPAD) {
+            Log.v(TAG, "Input device " + device.getName() + " is a gamepad.");
+        }
+        */
+        InputDevice.MotionRange range = device.getMotionRange(MotionEvent.AXIS_HAT_X);
+        if(range == null)
+            return false;
+
+        range = device.getMotionRange(MotionEvent.AXIS_HAT_Y);
+        if(range == null)
+            return false;
+
+        return ((sources & InputDevice.SOURCE_CLASS_JOYSTICK) != 0 ||
+                ((sources & InputDevice.SOURCE_DPAD) == InputDevice.SOURCE_DPAD) ||
+                ((sources & InputDevice.SOURCE_GAMEPAD) == InputDevice.SOURCE_GAMEPAD)
+        );
+    }
+
+    public static native void addJoystickNative(int deviceId, int deviceSource);
+    public static native void removeJoystickNative(int deviceId);
+}
+
+class JoypadHandler {
+    /**
+     * Handles adding and removing of input devices.
+     */
+    public void pollInputDevices() {
+    }
+
+    public void removeInputDevices() {
+    }
+}
+
+class JoypadHandler_API extends JoypadHandler {
+    private final HashSet<Integer> mJoypadIds;
+
+    public JoypadHandler_API() {
+        mJoypadIds = new HashSet<Integer>();
+    }
+
+    @Override
+    public void pollInputDevices() {
+        int[] deviceIds = InputDevice.getDeviceIds();
+
+        for (int deviceId : deviceIds) {
+            if (!mJoypadIds.contains(deviceId)) {
+                if (JoypadManager.isDeviceJoystick(deviceId)) {
+                    InputDevice joypadDevice = InputDevice.getDevice(deviceId);
+                    mJoypadIds.add(deviceId);
+                    JoypadManager.addJoystickNative(
+                            deviceId,
+                            joypadDevice.getSources()
+                    );
+                }
+            }
+        }
+
+        ArrayList<Integer> removedDevices = null;
+        for (Integer joystickId : mJoypadIds) {
+            int i;
+            for (i = 0; i < deviceIds.length; i++) {
+                if (joystickId == deviceIds[i])
+                    break;
+            }
+
+            if (i == deviceIds.length) {
+                if (removedDevices == null) {
+                    removedDevices = new ArrayList<Integer>();
+                }
+                removedDevices.add(joystickId);
+            }
+        }
+
+        if (removedDevices != null) {
+            for (int deviceId : removedDevices) {
+                JoypadManager.removeJoystickNative(deviceId);
+                mJoypadIds.remove(deviceId);
+            }
+        }
+    }
+
+    @Override
+    public void removeInputDevices() {
+        for (int deviceId : mJoypadIds) {
+            JoypadManager.removeJoystickNative(deviceId);
+        }
+        mJoypadIds.clear();
+    }
+}

+ 1 - 0
app/src/main/java/com/xugame/gameconsole/emulator/RetroArchEmulatorActivity.java

@@ -353,6 +353,7 @@ public class RetroArchEmulatorActivity extends RetroActivityCamera {
     protected void onActivityResult(int requestCode, int resultCode, Intent data) {
         if (requestCode == 200) {
             if (resultCode == 201) {//继续游戏
+                gameDialogClosed();
                 if (data != null) {
                     int scanLine = data.getIntExtra("scanLine", 0);
                     int screen = data.getIntExtra("screen", 0);