示例#1
0
static void switch_joypad_autodetect_add(unsigned autoconf_pad)
{
   if(!input_autoconfigure_connect(
            switch_joypad_name(autoconf_pad), /* name */
            NULL,                             /* display name */
            switch_joypad.ident,              /* driver */
            autoconf_pad,                     /* idx */
            0,                                /* vid */
            0))                               /* pid */
      input_config_set_device_name(autoconf_pad, switch_joypad_name(autoconf_pad));
}
示例#2
0
static void wiiusb_hid_device_add_autodetect(unsigned idx,
      const char *device_name, const char *driver_name,
      uint16_t dev_vid, uint16_t dev_pid)
{
   if (!input_autoconfigure_connect(
         device_name,
         NULL,
         driver_name,
         idx,
         dev_vid,
         dev_pid))
      input_config_set_device_name(idx, device_name);
}
示例#3
0
static void iohidmanager_hid_device_add_autodetect(unsigned idx,
      const char *device_name, const char *driver_name,
      uint16_t dev_vid, uint16_t dev_pid)
{
   if (!input_autoconfigure_connect(
         device_name,
         NULL,
         driver_name,
         idx,
         dev_vid,
         dev_pid
         ))
      input_config_set_device_name(idx, device_name);

   RARCH_LOG("Port %d: %s.\n", idx, device_name);
}
示例#4
0
static void handle_hotplug(unsigned port, uint32_t ptype)
{
   pad_type[port] = ptype;

   if (ptype != WPAD_EXP_NOCONTROLLER)
   {
      if (!input_autoconfigure_connect(
            gx_joypad_name(port),
            NULL,
            gx_joypad.ident,
            port,
            0,
            0
            ))
         input_config_set_device_name(port, gx_joypad_name(port));
   }
}
示例#5
0
static EM_BOOL rwebpad_gamepad_cb(int event_type,
   const EmscriptenGamepadEvent *gamepad_event, void *user_data)
{
   unsigned vid = 0;
   unsigned pid = 0;

   (void)event_type;
   (void)gamepad_event;
   (void)user_data;

   if (strncmp(gamepad_event->mapping, "standard",
       sizeof(gamepad_event->mapping)) == 0)
   {
      /* give a dummy vid/pid for automapping */
      vid = 1;
      pid = 1;
   }


   if (event_type == EMSCRIPTEN_EVENT_GAMEPADCONNECTED)
   {
      if(!input_autoconfigure_connect(
               gamepad_event->id,    /* name */
               NULL,                 /* display name */
               rwebpad_joypad.ident, /* driver */
               gamepad_event->index, /* idx */
               vid,                  /* vid */
               pid))                 /* pid */
         input_config_set_device_name(gamepad_event->index,
            gamepad_event->id);
   }
   else if (event_type == EMSCRIPTEN_EVENT_GAMEPADDISCONNECTED)
   {
      input_autoconfigure_disconnect(gamepad_event->index,
         rwebpad_joypad.ident);
   }

   return EM_TRUE;
}
示例#6
0
bool input_autoconfigure_connect(
      const char *name,
      const char *display_name,
      const char *driver,
      unsigned idx,
      unsigned vid,
      unsigned pid)
{
   unsigned i;
   retro_task_t         *task = task_init();
   autoconfig_params_t *state = (autoconfig_params_t*)calloc(1, sizeof(*state));
   settings_t       *settings = config_get_ptr();
   const char *dir_autoconf   = settings ? settings->paths.directory_autoconfig : NULL;
   bool autodetect_enable     = settings ? settings->bools.input_autodetect_enable : false;

   if (!task || !state || !autodetect_enable)
      goto error;

   if (!string_is_empty(name))
      state->name                 = strdup(name);

   if (!string_is_empty(dir_autoconf))
      state->autoconfig_directory = strdup(dir_autoconf);

   state->idx                     = idx;
   state->vid                     = vid;
   state->pid                     = pid;
   state->max_users               = *(
         input_driver_get_uint(INPUT_ACTION_MAX_USERS));

   input_autoconfigure_override_handler(state);

   if (!string_is_empty(state->name))
         input_config_set_device_name(state->idx, state->name);
   input_config_set_pid(state->idx, state->pid);
   input_config_set_vid(state->idx, state->vid);

   for (i = 0; i < RARCH_BIND_LIST_END; i++)
   {
      input_autoconf_binds[state->idx][i].joykey           = NO_BTN;
      input_autoconf_binds[state->idx][i].joyaxis          = AXIS_NONE;
      if (
          !string_is_empty(input_autoconf_binds[state->idx][i].joykey_label))
         free(input_autoconf_binds[state->idx][i].joykey_label);
      if (
          !string_is_empty(input_autoconf_binds[state->idx][i].joyaxis_label))
         free(input_autoconf_binds[state->idx][i].joyaxis_label);
      input_autoconf_binds[state->idx][i].joykey_label      = NULL;
      input_autoconf_binds[state->idx][i].joyaxis_label     = NULL;
   }

   input_autoconfigured[state->idx] = false;

   task->state                      = state;
   task->handler                    = input_autoconfigure_connect_handler;

   task_queue_push(task);

   return true;

error:
   if (state)
   {
      input_autoconfigure_params_free(state);
      free(state);
   }
   if (task)
      free(task);

   return false;
}
示例#7
0
static void sdl_pad_connect(unsigned id)
{
   sdl_joypad_t *pad          = (sdl_joypad_t*)&sdl_pads[id];
   bool success               = false;
   int32_t product            = 0;
   int32_t vendor             = 0;

#ifdef HAVE_SDL2
   SDL_JoystickGUID guid;
   uint16_t *guid_ptr;

   if (SDL_IsGameController(id))
   {
      pad->controller = SDL_GameControllerOpen(id);
      pad->joypad     = SDL_GameControllerGetJoystick(pad->controller);

      success = pad->joypad != NULL && pad->controller != NULL;
   }
   else
#endif
   {
      pad->joypad = SDL_JoystickOpen(id);
      success = pad->joypad != NULL;
   }

   if (!success)
   {
      RARCH_ERR("[SDL]: Couldn't open joystick #%u: %s.\n", id, SDL_GetError());

      if (pad->joypad)
         SDL_JoystickClose(pad->joypad);

      pad->joypad = NULL;

      return;
   }

#ifdef HAVE_SDL2
   guid       = SDL_JoystickGetGUID(pad->joypad);
   guid_ptr   = (uint16_t*)guid.data;
#ifdef __linux
   vendor     = guid_ptr[2];
   product    = guid_ptr[4];
#elif _WIN32
   vendor     = guid_ptr[0];
   product    = guid_ptr[1];
#endif
#endif

   if (!input_autoconfigure_connect(
         sdl_joypad_name(id),
         NULL,
         sdl_joypad.ident,
         id,
         vendor,
         product))
      input_config_set_device_name(id, sdl_joypad_name(id));

   RARCH_LOG("[SDL]: Device #%u (%04x:%04x) connected: %s.\n", id, vendor,
             product, sdl_joypad_name(id));

#ifdef HAVE_SDL2
   if (pad->controller)
   {
      /* SDL_GameController internally supports all axis/button IDs, even if
       * the controller's mapping does not have a binding for it.
       *
       * So, we can claim to support all axes/buttons, and when we try to poll
       * an unbound ID, SDL simply returns the correct unpressed value.
       *
       * Note that, in addition to 0 trackballs, we also have 0 hats. This is
       * because the d-pad is in the button list, as the last 4 enum entries.
       *
       * -flibit
       */
      pad->num_axes    = SDL_CONTROLLER_AXIS_MAX;
      pad->num_buttons = SDL_CONTROLLER_BUTTON_MAX;
      pad->num_hats    = 0;
      pad->num_balls   = 0;

      RARCH_LOG("[SDL]: Device #%u supports game controller api.\n", id);
   }
   else
   {
      pad->num_axes    = SDL_JoystickNumAxes(pad->joypad);
      pad->num_buttons = SDL_JoystickNumButtons(pad->joypad);
      pad->num_hats    = SDL_JoystickNumHats(pad->joypad);
      pad->num_balls   = SDL_JoystickNumBalls(pad->joypad);

      RARCH_LOG("[SDL]: Device #%u has: %u axes, %u buttons, %u hats and %u trackballs.\n",
                id, pad->num_axes, pad->num_buttons, pad->num_hats, pad->num_balls);
   }

   pad->haptic = g_has_haptic ? SDL_HapticOpenFromJoystick(pad->joypad) : NULL;

   if (g_has_haptic && !pad->haptic)
      RARCH_WARN("[SDL]: Couldn't open haptic device of the joypad #%u: %s\n",
                 id, SDL_GetError());

   pad->rumble_effect = -1;

   if (pad->haptic)
   {
      SDL_HapticEffect efx;
      efx.type = SDL_HAPTIC_LEFTRIGHT;
      efx.leftright.type = SDL_HAPTIC_LEFTRIGHT;
      efx.leftright.large_magnitude = efx.leftright.small_magnitude = 0x4000;
      efx.leftright.length = 5000;

      if (SDL_HapticEffectSupported(pad->haptic, &efx) == SDL_FALSE)
      {
         pad->rumble_effect = -2;
         RARCH_WARN("[SDL]: Device #%u does not support rumble.\n", id);
      }
   }
#else
   pad->num_axes    = SDL_JoystickNumAxes(pad->joypad);
   pad->num_buttons = SDL_JoystickNumButtons(pad->joypad);
   pad->num_hats    = SDL_JoystickNumHats(pad->joypad);

   RARCH_LOG("[SDL]: Device #%u has: %u axes, %u buttons, %u hats.\n",
             id, pad->num_axes, pad->num_buttons, pad->num_hats);
#endif
}
示例#8
0
static BOOL CALLBACK enum_joypad_cb(const DIDEVICEINSTANCE *inst, void *p)
{
#ifdef HAVE_XINPUT
   bool is_xinput_pad;
#endif
   LPDIRECTINPUTDEVICE8 *pad = NULL;

   (void)p;

   if (g_joypad_cnt == MAX_USERS)
      return DIENUM_STOP;

   pad = &g_pads[g_joypad_cnt].joypad;

#ifdef __cplusplus
   if (FAILED(IDirectInput8_CreateDevice(
               g_dinput_ctx, inst->guidInstance, pad, NULL)))
#else
   if (FAILED(IDirectInput8_CreateDevice(
               g_dinput_ctx, &inst->guidInstance, pad, NULL)))
#endif
   return DIENUM_CONTINUE;

   g_pads[g_joypad_cnt].joy_name          = strdup((const char*)inst->tszProductName);
   g_pads[g_joypad_cnt].joy_friendly_name = strdup((const char*)inst->tszInstanceName);

   /* there may be more useful info in the GUID so leave this here for a while */
#if 0
   printf("Guid = {%08lX-%04hX-%04hX-%02hhX%02hhX-%02hhX%02hhX%02hhX%02hhX%02hhX%02hhX}\n",
   inst->guidProduct.Data1,
   inst->guidProduct.Data2,
   inst->guidProduct.Data3,
   inst->guidProduct.Data4[0],
   inst->guidProduct.Data4[1],
   inst->guidProduct.Data4[2],
   inst->guidProduct.Data4[3],
   inst->guidProduct.Data4[4],
   inst->guidProduct.Data4[5],
   inst->guidProduct.Data4[6],
   inst->guidProduct.Data4[7]);
#endif

   g_pads[g_joypad_cnt].vid = inst->guidProduct.Data1 % 0x10000;
   g_pads[g_joypad_cnt].pid = inst->guidProduct.Data1 / 0x10000;

   RARCH_LOG("[DINPUT]: Device #%u PID: {%04lX} VID:{%04lX}\n",
         g_joypad_cnt,
         g_pads[g_joypad_cnt].pid,
         g_pads[g_joypad_cnt].vid);

#ifdef HAVE_XINPUT
   is_xinput_pad = g_xinput_block_pads
      && guid_is_xinput_device(&inst->guidProduct);

   if (is_xinput_pad)
   {
      if (g_last_xinput_pad_idx < 4)
         g_xinput_pad_indexes[g_joypad_cnt] = g_last_xinput_pad_idx++;
      goto enum_iteration_done;
   }
#endif

   IDirectInputDevice8_SetDataFormat(*pad, &c_dfDIJoystick2);
   IDirectInputDevice8_SetCooperativeLevel(*pad,
         (HWND)video_driver_window_get(),
         DISCL_EXCLUSIVE | DISCL_BACKGROUND);

   IDirectInputDevice8_EnumObjects(*pad, enum_axes_cb,
         *pad, DIDFT_ABSAXIS);

   dinput_create_rumble_effects(&g_pads[g_joypad_cnt]);

#ifdef HAVE_XINPUT
   if (!is_xinput_pad)
#endif
   {
      if (!input_autoconfigure_connect(
               dinput_joypad_name(g_joypad_cnt),
               dinput_joypad_friendly_name(g_joypad_cnt),
               dinput_joypad.ident,
               g_joypad_cnt,
               dinput_joypad_vid(g_joypad_cnt),
               dinput_joypad_pid(g_joypad_cnt)))
         input_config_set_device_name(g_joypad_cnt, dinput_joypad_name(g_joypad_cnt));
   }

#ifdef HAVE_XINPUT
enum_iteration_done:
#endif
   g_joypad_cnt++;
   return DIENUM_CONTINUE;
}
示例#9
0
static bool parport_joypad_init(void *data)
{
   unsigned i, j;
   bool found_enabled_button             = false;
   bool found_disabled_button            = false;
   char buf[PARPORT_NUM_BUTTONS * 3 + 1] = {0};
   char pin[3 + 1]                       = {0};

   (void)data;

   memset(buf, 0, PARPORT_NUM_BUTTONS * 3 + 1);

   for (i = 0; i < MAX_USERS; i++)
   {
      char path[PATH_MAX_LENGTH] = {0};
      struct parport_joypad *pad = &parport_pads[i];

      pad->fd    = -1;
      pad->ident = input_device_names[i];

      snprintf(path, sizeof(path), "/dev/parport%u", i);

      if (parport_joypad_init_pad(path, pad))
      {
         /* If a pin is low on initialization it can either mean
          * a button is pressed or that nothing is connected.
          * Polling non-connected pins can render the menu unusable
          * so assume the user is not holding any button on startup
          * and disable any low pins.
          */
         parport_poll_pad(pad);
         found_enabled_button = false;
         found_disabled_button = false;

         for (j = 0; j < PARPORT_NUM_BUTTONS; j++)
         {
            if (!(BIT32_GET(pad->buttons, j)))
            {
               pad->button_enable[j] = true;
               found_enabled_button = true;
            }
            else
            {
               pad->button_enable[j] = false;
               found_disabled_button = true;
            }
         }

         if (found_enabled_button)
         {
            if (found_disabled_button)
            {
               buf[0] = '\0';
               for (j = 0; j < PARPORT_NUM_BUTTONS; j++)
               {
                  if (!pad->button_enable[j])
                  {
                     snprintf(pin, sizeof(pin), "%d ", j);
                     strlcat(buf, pin, sizeof(buf));
                  }
               }
               RARCH_WARN("[Joypad]: Pin(s) %son %s were low on init, assuming not connected\n", \
                     buf, path);
            }
         }
         else
         {
            RARCH_WARN("[Joypad]: All pins low on %s, assuming nothing connected\n", path);
            parport_free_pad(pad);
         }
      }

      if (!input_autoconfigure_connect(
            "Generic Parallel Port device",
            NULL,
            "parport",
            i,
            0,
            0
            ))
         input_config_set_device_name(i, "Generic Parallel Port device");
   }

   return true;
}