uint64_t menu_input(void) { unsigned i; uint64_t input_state = 0; retro_input_t input_meta = 0, old_state = 0; static const struct retro_keybind *binds[] = { g_settings.input.binds[0] }; if (!driver.menu) 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]); if (!driver.block_libretro_input) { for (i = 0; i < RETRO_DEVICE_ID_JOYPAD_R2; i++) { input_state |= driver.input->input_state(driver.input_data, 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_meta = input_keys_pressed_func(RARCH_MENU_TOGGLE, RARCH_MENU_TOGGLE + 1, &old_state); input_state |= BIND_PRESSED(input_meta, 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]); driver.menu->trigger_state = input_state & ~driver.menu->old_input_state; driver.menu->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; }
bool menu_iterate(retro_input_t input, retro_input_t old_input, retro_input_t trigger_input) { unsigned action = MENU_ACTION_NOOP; static bool initial_held = true; static bool first_held = false; uint64_t input_state = 0; int32_t ret = 0; if (!driver.menu) return false; #ifdef HAVE_OVERLAY if (BIND_PRESSED(trigger_input, RARCH_OVERLAY_NEXT)) input_overlay_next(driver.overlay); #endif check_fullscreen_func(trigger_input); driver.retro_ctx.poll_cb(); input_state = menu_input(); if (driver.menu->do_held) { if (!first_held) { first_held = true; driver.menu->delay_timer = initial_held ? 12 : 6; driver.menu->delay_count = 0; } if (driver.menu->delay_count >= driver.menu->delay_timer) { first_held = false; driver.menu->trigger_state = input_state; driver.menu->scroll_accel = min(driver.menu->scroll_accel + 1, 64); } initial_held = false; } else { first_held = false; initial_held = true; driver.menu->scroll_accel = 0; } driver.menu->delay_count++; driver.menu->old_input_state = input_state; if (driver.block_input) driver.menu->trigger_state = 0; /* don't run anything first frame, only capture held inputs * for old_input_state. */ action = input_frame(driver.menu->trigger_state); if (driver.menu_ctx && driver.menu_ctx->backend && driver.menu_ctx->backend->iterate) ret = driver.menu_ctx->backend->iterate(action); draw_frame(true); throttle_frame(); draw_frame(false); if (driver.menu_ctx && driver.menu_ctx->input_postprocess) driver.menu_ctx->input_postprocess(driver.menu->old_input_state); #if 0 /* Go back to Main Menu when exiting */ if (ret < 0) menu_flush_stack_type(driver.menu->menu_stack, MENU_SETTINGS); #endif if (ret) return false; return true; }