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)); }
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); }
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); }
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)); } }
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; }
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; }
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 }
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; }
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; }