void menu_poll_bind_state(struct menu_bind_state *state) { if (!state) return; unsigned i, b, a, h; memset(state->state, 0, sizeof(state->state)); state->skip = input_input_state_func(NULL, 0, RETRO_DEVICE_KEYBOARD, 0, RETROK_RETURN); const rarch_joypad_driver_t *joypad = NULL; if (driver.input && driver.input_data && driver.input->get_joypad_driver) joypad = driver.input->get_joypad_driver(driver.input_data); if (!joypad) { RARCH_ERR("Cannot poll raw joypad state."); return; } input_joypad_poll(joypad); for (i = 0; i < MAX_PLAYERS; i++) { for (b = 0; b < MENU_MAX_BUTTONS; b++) state->state[i].buttons[b] = input_joypad_button_raw(joypad, i, b); for (a = 0; a < MENU_MAX_AXES; a++) state->state[i].axes[a] = input_joypad_axis_raw(joypad, i, a); for (h = 0; h < MENU_MAX_HATS; h++) { state->state[i].hats[h] |= input_joypad_hat_raw(joypad, i, HAT_UP_MASK, h) ? HAT_UP_MASK : 0; state->state[i].hats[h] |= input_joypad_hat_raw(joypad, i, HAT_DOWN_MASK, h) ? HAT_DOWN_MASK : 0; state->state[i].hats[h] |= input_joypad_hat_raw(joypad, i, HAT_LEFT_MASK, h) ? HAT_LEFT_MASK : 0; state->state[i].hats[h] |= input_joypad_hat_raw(joypad, i, HAT_RIGHT_MASK, h) ? HAT_RIGHT_MASK : 0; } } }
// Updates 16-bit input in same format as SNES itself. static void update_input(state_tracker_t *tracker) { unsigned i; if (driver.input == NULL) return; static const unsigned buttons[] = { RETRO_DEVICE_ID_JOYPAD_R, RETRO_DEVICE_ID_JOYPAD_L, RETRO_DEVICE_ID_JOYPAD_X, RETRO_DEVICE_ID_JOYPAD_A, RETRO_DEVICE_ID_JOYPAD_RIGHT, RETRO_DEVICE_ID_JOYPAD_LEFT, RETRO_DEVICE_ID_JOYPAD_DOWN, RETRO_DEVICE_ID_JOYPAD_UP, RETRO_DEVICE_ID_JOYPAD_START, RETRO_DEVICE_ID_JOYPAD_SELECT, RETRO_DEVICE_ID_JOYPAD_Y, RETRO_DEVICE_ID_JOYPAD_B, }; // Only bind for up to two players for now. static const struct retro_keybind *binds[2] = { g_settings.input.binds[0], g_settings.input.binds[1], }; for (i = 0; i < 2; i++) input_push_analog_dpad(g_settings.input.binds[i], g_settings.input.analog_dpad_mode[i]); for (i = 0; i < MAX_PLAYERS; i++) input_push_analog_dpad(g_settings.input.autoconf_binds[i], g_settings.input.analog_dpad_mode[i]); uint16_t state[2] = {0}; for (i = 4; i < 16; i++) { state[0] |= (input_input_state_func(binds, 0, RETRO_DEVICE_JOYPAD, 0, buttons[i - 4]) ? 1 : 0) << i; state[1] |= (input_input_state_func(binds, 1, RETRO_DEVICE_JOYPAD, 0, buttons[i - 4]) ? 1 : 0) << i; } for (i = 0; i < 2; i++) input_pop_analog_dpad(g_settings.input.binds[i]); for (i = 0; i < MAX_PLAYERS; i++) input_pop_analog_dpad(g_settings.input.autoconf_binds[i]); for (i = 0; i < 2; i++) tracker->input_state[i] = state[i]; }
uint64_t menu_input(void *data) { unsigned i; uint64_t input_state; rgui_handle_t *rgui; #ifdef RARCH_CONSOLE static const struct retro_keybind *binds[] = { g_settings.input.menu_binds }; #else static const struct retro_keybind *binds[] = { g_settings.input.binds[0] }; #endif rgui = (rgui_handle_t*)data; input_state = 0; if (!rgui) return 0; input_push_analog_dpad((struct retro_keybind*)binds[0], (g_settings.input.analog_dpad_mode[0] == ANALOG_DPAD_NONE) ? ANALOG_DPAD_LSTICK : g_settings.input.analog_dpad_mode[0]); for (i = 0; i < MAX_PLAYERS; i++) input_push_analog_dpad(g_settings.input.autoconf_binds[i], g_settings.input.analog_dpad_mode[i]); for (i = 0; i < RETRO_DEVICE_ID_JOYPAD_R2; i++) { input_state |= input_input_state_func(binds, 0, RETRO_DEVICE_JOYPAD, 0, i) ? (1ULL << i) : 0; #ifdef HAVE_OVERLAY input_state |= (driver.overlay_state.buttons & (UINT64_C(1) << i)) ? (1ULL << i) : 0; #endif } input_state |= input_key_pressed_func(RARCH_MENU_TOGGLE) ? (1ULL << RARCH_MENU_TOGGLE) : 0; input_pop_analog_dpad((struct retro_keybind*)binds[0]); for (i = 0; i < MAX_PLAYERS; i++) input_pop_analog_dpad(g_settings.input.autoconf_binds[i]); rgui->trigger_state = input_state & ~rgui->old_input_state; rgui->do_held = (input_state & ( (1ULL << RETRO_DEVICE_ID_JOYPAD_UP) | (1ULL << RETRO_DEVICE_ID_JOYPAD_DOWN) | (1ULL << RETRO_DEVICE_ID_JOYPAD_LEFT) | (1ULL << RETRO_DEVICE_ID_JOYPAD_RIGHT) | (1ULL << RETRO_DEVICE_ID_JOYPAD_L) | (1ULL << RETRO_DEVICE_ID_JOYPAD_R) )) && !(input_state & (1ULL << RARCH_MENU_TOGGLE)); return input_state; }
// Updates 16-bit input in same format as SNES itself. static void update_input(state_tracker_t *tracker) { if (driver.input == NULL) return; static const unsigned buttons[] = { RETRO_DEVICE_ID_JOYPAD_R, RETRO_DEVICE_ID_JOYPAD_L, RETRO_DEVICE_ID_JOYPAD_X, RETRO_DEVICE_ID_JOYPAD_A, RETRO_DEVICE_ID_JOYPAD_RIGHT, RETRO_DEVICE_ID_JOYPAD_LEFT, RETRO_DEVICE_ID_JOYPAD_DOWN, RETRO_DEVICE_ID_JOYPAD_UP, RETRO_DEVICE_ID_JOYPAD_START, RETRO_DEVICE_ID_JOYPAD_SELECT, RETRO_DEVICE_ID_JOYPAD_Y, RETRO_DEVICE_ID_JOYPAD_B, }; // Only bind for up to two players for now. static const struct snes_keybind *binds[2] = { g_settings.input.binds[0], g_settings.input.binds[1], }; uint16_t state[2] = {0}; for (unsigned i = 4; i < 16; i++) { state[0] |= (input_input_state_func(binds, 0, RETRO_DEVICE_JOYPAD, 0, buttons[i - 4]) ? 1 : 0) << i; state[1] |= (input_input_state_func(binds, 1, RETRO_DEVICE_JOYPAD, 0, buttons[i - 4]) ? 1 : 0) << i; } for (unsigned i = 0; i < 2; i++) tracker->input_state[i] = state[i]; }
static PyObject *py_read_input(PyObject *self, PyObject *args) { (void)self; if (!driver.input_data) return PyBool_FromLong(0); unsigned player; unsigned key; if (!PyArg_ParseTuple(args, "II", &player, &key)) return NULL; if (player > MAX_PLAYERS || player < 1 || key >= RARCH_FIRST_META_KEY) return NULL; int16_t res = driver.block_libretro_input ? 0 : input_input_state_func(py_binds, player - 1, RETRO_DEVICE_JOYPAD, 0, key); return PyBool_FromLong(res); }
static PyObject *py_read_analog(PyObject *self, PyObject *args) { (void)self; if (!driver.input_data) return PyBool_FromLong(0); unsigned player; unsigned index; unsigned id; if (!PyArg_ParseTuple(args, "III", &player, &index, &id)) return NULL; if (player > MAX_PLAYERS || player < 1 || index > 1 || id > 1) return NULL; int16_t res = input_input_state_func(py_binds, player - 1, RETRO_DEVICE_ANALOG, index, id); return PyFloat_FromDouble((double)res / 0x7fff); }
static uint64_t rgui_input(void) { uint64_t input_state = 0; // FIXME: Very ugly. Should do something more uniform. #if defined(RARCH_CONSOLE) || defined(ANDROID) for (unsigned i = 0; i < DEVICE_NAV_LAST; i++) input_state |= driver.input->input_state(driver.input_data, menu_nav_binds, 0, RETRO_DEVICE_JOYPAD, 0, i) ? (1ULL << i) : 0; input_state |= driver.input->key_pressed(driver.input_data, RARCH_MENU_TOGGLE) ? (1ULL << DEVICE_NAV_MENU) : 0; #ifdef HAVE_OVERLAY for (unsigned i = 0; i < DEVICE_NAV_LAST; i++) input_state |= driver.overlay_state & menu_nav_binds[0][i].joykey ? (1ULL << i) : 0; #endif #else static const int maps[] = { RETRO_DEVICE_ID_JOYPAD_UP, DEVICE_NAV_UP, RETRO_DEVICE_ID_JOYPAD_DOWN, DEVICE_NAV_DOWN, RETRO_DEVICE_ID_JOYPAD_LEFT, DEVICE_NAV_LEFT, RETRO_DEVICE_ID_JOYPAD_RIGHT, DEVICE_NAV_RIGHT, RETRO_DEVICE_ID_JOYPAD_A, DEVICE_NAV_A, RETRO_DEVICE_ID_JOYPAD_B, DEVICE_NAV_B, RETRO_DEVICE_ID_JOYPAD_START, DEVICE_NAV_START, RETRO_DEVICE_ID_JOYPAD_SELECT, DEVICE_NAV_SELECT, }; static const struct retro_keybind *binds[] = { g_settings.input.binds[0] }; for (unsigned i = 0; i < ARRAY_SIZE(maps); i += 2) { input_state |= input_input_state_func(binds, 0, RETRO_DEVICE_JOYPAD, 0, maps[i + 0]) ? (1ULL << maps[i + 1]) : 0; #ifdef HAVE_OVERLAY input_state |= (driver.overlay_state & (UINT64_C(1) << maps[i + 0])) ? (1ULL << maps[i + 1]) : 0; #endif } input_state |= input_key_pressed_func(RARCH_MENU_TOGGLE) ? (1ULL << DEVICE_NAV_MENU) : 0; #endif rgui->trigger_state = input_state & ~rgui->old_input_state; #if defined(HAVE_RGUI) rgui->do_held = (input_state & ( (1ULL << DEVICE_NAV_UP) | (1ULL << DEVICE_NAV_DOWN) | (1ULL << DEVICE_NAV_LEFT) | (1ULL << DEVICE_NAV_RIGHT))) && !(input_state & (1ULL << DEVICE_NAV_MENU)); #elif defined(HAVE_RMENU) rgui->do_held = (input_state & ( (1ULL << DEVICE_NAV_LEFT) | (1ULL << DEVICE_NAV_RIGHT) | (1ULL << DEVICE_NAV_UP) | (1ULL << DEVICE_NAV_DOWN) | (1ULL << RARCH_ANALOG_LEFT_Y_DPAD_UP) | (1ULL << RARCH_ANALOG_LEFT_Y_DPAD_DOWN) | (1ULL << RARCH_ANALOG_LEFT_X_DPAD_LEFT) | (1ULL << RARCH_ANALOG_LEFT_X_DPAD_RIGHT) | (1ULL << RARCH_ANALOG_RIGHT_Y_DPAD_UP) | (1ULL << RARCH_ANALOG_RIGHT_Y_DPAD_DOWN) | (1ULL << RARCH_ANALOG_RIGHT_X_DPAD_LEFT) | (1ULL << RARCH_ANALOG_RIGHT_X_DPAD_RIGHT) | (1ULL << DEVICE_NAV_L2) | (1ULL << DEVICE_NAV_R2) )) && !(input_state & (1ULL << DEVICE_NAV_MENU)); #endif return input_state; }