void input_state_overlay(int16_t *ret, unsigned port, unsigned device, unsigned idx, unsigned id) { input_overlay_state_t *ol_state = &overlay_st_ptr; if (!ol_state) return; if (port != 0) return; switch (device) { case RETRO_DEVICE_JOYPAD: if (input_overlay_key_pressed(id)) *ret |= 1; break; case RETRO_DEVICE_KEYBOARD: if (id < RETROK_LAST) { if (OVERLAY_GET_KEY(ol_state, id)) *ret |= 1; } break; case RETRO_DEVICE_ANALOG: { unsigned base = 0; if (idx == RETRO_DEVICE_INDEX_ANALOG_RIGHT) base = 2; if (id == RETRO_DEVICE_ID_ANALOG_Y) base += 1; if (ol_state && ol_state->analog[base]) *ret = ol_state->analog[base]; } break; } }
/* * input_poll_overlay: * @overlay_device : pointer to overlay * * Poll pressed buttons/keys on currently active overlay. **/ static INLINE void input_poll_overlay(input_overlay_t *overlay_device, float opacity) { input_overlay_state_t old_key_state; unsigned i, j, device; uint16_t key_mod = 0; bool polled = false; driver_t *driver = driver_get_ptr(); settings_t *settings = config_get_ptr(); if (overlay_device->state != OVERLAY_STATUS_ALIVE) return; memcpy(old_key_state.keys, driver->overlay_state.keys, sizeof(driver->overlay_state.keys)); memset(&driver->overlay_state, 0, sizeof(driver->overlay_state)); device = input_overlay_full_screen(overlay_device) ? RARCH_DEVICE_POINTER_SCREEN : RETRO_DEVICE_POINTER; for (i = 0; input_driver_state(NULL, 0, device, i, RETRO_DEVICE_ID_POINTER_PRESSED); i++) { input_overlay_state_t polled_data; int16_t x = input_driver_state(NULL, 0, device, i, RETRO_DEVICE_ID_POINTER_X); int16_t y = input_driver_state(NULL, 0, device, i, RETRO_DEVICE_ID_POINTER_Y); input_overlay_poll(overlay_device, &polled_data, x, y); driver->overlay_state.buttons |= polled_data.buttons; for (j = 0; j < ARRAY_SIZE(driver->overlay_state.keys); j++) driver->overlay_state.keys[j] |= polled_data.keys[j]; /* Fingers pressed later take prio and matched up * with overlay poll priorities. */ for (j = 0; j < 4; j++) if (polled_data.analog[j]) driver->overlay_state.analog[j] = polled_data.analog[j]; polled = true; } if (OVERLAY_GET_KEY(&driver->overlay_state, RETROK_LSHIFT) || OVERLAY_GET_KEY(&driver->overlay_state, RETROK_RSHIFT)) key_mod |= RETROKMOD_SHIFT; if (OVERLAY_GET_KEY(&driver->overlay_state, RETROK_LCTRL) || OVERLAY_GET_KEY(&driver->overlay_state, RETROK_RCTRL)) key_mod |= RETROKMOD_CTRL; if (OVERLAY_GET_KEY(&driver->overlay_state, RETROK_LALT) || OVERLAY_GET_KEY(&driver->overlay_state, RETROK_RALT)) key_mod |= RETROKMOD_ALT; if (OVERLAY_GET_KEY(&driver->overlay_state, RETROK_LMETA) || OVERLAY_GET_KEY(&driver->overlay_state, RETROK_RMETA)) key_mod |= RETROKMOD_META; /* CAPSLOCK SCROLLOCK NUMLOCK */ for (i = 0; i < ARRAY_SIZE(driver->overlay_state.keys); i++) { if (driver->overlay_state.keys[i] != old_key_state.keys[i]) { uint32_t orig_bits = old_key_state.keys[i]; uint32_t new_bits = driver->overlay_state.keys[i]; for (j = 0; j < 32; j++) if ((orig_bits & (1 << j)) != (new_bits & (1 << j))) input_keyboard_event(new_bits & (1 << j), i * 32 + j, 0, key_mod, RETRO_DEVICE_POINTER); } } /* Map "analog" buttons to analog axes like regular input drivers do. */ for (j = 0; j < 4; j++) { unsigned bind_plus = RARCH_ANALOG_LEFT_X_PLUS + 2 * j; unsigned bind_minus = bind_plus + 1; if (driver->overlay_state.analog[j]) continue; if (driver->overlay_state.buttons & (1ULL << bind_plus)) driver->overlay_state.analog[j] += 0x7fff; if (driver->overlay_state.buttons & (1ULL << bind_minus)) driver->overlay_state.analog[j] -= 0x7fff; } /* Check for analog_dpad_mode. * Map analogs to d-pad buttons when configured. */ switch (settings->input.analog_dpad_mode[0]) { case ANALOG_DPAD_LSTICK: case ANALOG_DPAD_RSTICK: { float analog_x, analog_y; unsigned analog_base = 2; if (settings->input.analog_dpad_mode[0] == ANALOG_DPAD_LSTICK) analog_base = 0; analog_x = (float)driver->overlay_state.analog[analog_base + 0] / 0x7fff; analog_y = (float)driver->overlay_state.analog[analog_base + 1] / 0x7fff; if (analog_x <= -settings->input.axis_threshold) driver->overlay_state.buttons |= (1ULL << RETRO_DEVICE_ID_JOYPAD_LEFT); if (analog_x >= settings->input.axis_threshold) driver->overlay_state.buttons |= (1ULL << RETRO_DEVICE_ID_JOYPAD_RIGHT); if (analog_y <= -settings->input.axis_threshold) driver->overlay_state.buttons |= (1ULL << RETRO_DEVICE_ID_JOYPAD_UP); if (analog_y >= settings->input.axis_threshold) driver->overlay_state.buttons |= (1ULL << RETRO_DEVICE_ID_JOYPAD_DOWN); break; } default: break; } if (polled) input_overlay_post_poll(overlay_device, opacity); else input_overlay_poll_clear(overlay_device, opacity); }
/** * input_state: * @port : user number. * @device : device identifier of user. * @idx : index value of user. * @id : identifier of key pressed by user. * * Input state callback function. * * Returns: Non-zero if the given key (identified by @id) was pressed by the user * (assigned to @port). **/ static int16_t input_state(unsigned port, unsigned device, unsigned idx, unsigned id) { int16_t res = 0; settings_t *settings = config_get_ptr(); driver_t *driver = driver_get_ptr(); global_t *global = global_get_ptr(); const struct retro_keybind *libretro_input_binds[MAX_USERS] = { settings->input.binds[0], settings->input.binds[1], settings->input.binds[2], settings->input.binds[3], settings->input.binds[4], settings->input.binds[5], settings->input.binds[6], settings->input.binds[7], settings->input.binds[8], settings->input.binds[9], settings->input.binds[10], settings->input.binds[11], settings->input.binds[12], settings->input.binds[13], settings->input.binds[14], settings->input.binds[15], }; device &= RETRO_DEVICE_MASK; if (global->bsv.movie && global->bsv.movie_playback) { int16_t ret; if (bsv_movie_get_input(global->bsv.movie, &ret)) return ret; global->bsv.movie_end = true; } if (settings->input.remap_binds_enable) input_remapping_state(port, &device, &idx, &id); if (!driver->block_libretro_input) { if (((id < RARCH_FIRST_META_KEY) || (device == RETRO_DEVICE_KEYBOARD))) res = input_driver_state(libretro_input_binds, port, device, idx, id); #ifdef HAVE_OVERLAY if (port == 0) { switch (device) { case RETRO_DEVICE_JOYPAD: if (driver->overlay_state.buttons & (UINT64_C(1) << id)) res |= 1; break; case RETRO_DEVICE_KEYBOARD: if (id < RETROK_LAST) { if (OVERLAY_GET_KEY(&driver->overlay_state, id)) res |= 1; } break; case RETRO_DEVICE_ANALOG: { unsigned base = 0; if (idx == RETRO_DEVICE_INDEX_ANALOG_RIGHT) base = 2; if (id == RETRO_DEVICE_ID_ANALOG_Y) base += 1; if (driver->overlay_state.analog[base]) res = driver->overlay_state.analog[base]; } break; } } #endif } /* flushing_input will be cleared in rarch_main_iterate. */ if (driver->flushing_input) res = 0; /* Don't allow turbo for D-pad. */ if (device == RETRO_DEVICE_JOYPAD && (id < RETRO_DEVICE_ID_JOYPAD_UP || id > RETRO_DEVICE_ID_JOYPAD_RIGHT)) res = input_apply_turbo(port, id, res); if (global->bsv.movie && !global->bsv.movie_playback) bsv_movie_set_input(global->bsv.movie, res); return res; }