bool menu_iterate(void *data) { unsigned action; static bool initial_held = true; static bool first_held = false; uint64_t input_state; int32_t input_entry_ret, ret; rgui_handle_t *rgui; input_state = 0; input_entry_ret = 0; ret = 0; rgui = (rgui_handle_t*)data; if (!rgui) return false; if (g_extern.lifecycle_state & (1ULL << MODE_MENU_PREINIT)) { rgui->need_refresh = true; g_extern.lifecycle_state &= ~(1ULL << MODE_MENU_PREINIT); rgui->old_input_state |= 1ULL << RARCH_MENU_TOGGLE; } rarch_input_poll(); rarch_check_block_hotkey(); #ifdef HAVE_OVERLAY rarch_check_overlay(); #endif rarch_check_fullscreen(); if (input_key_pressed_func(RARCH_QUIT_KEY) || !video_alive_func()) { g_extern.lifecycle_state |= (1ULL << MODE_GAME); return false; } input_state = menu_input(rgui); if (rgui->do_held) { if (!first_held) { first_held = true; rgui->delay_timer = initial_held ? 12 : 6; rgui->delay_count = 0; } if (rgui->delay_count >= rgui->delay_timer) { first_held = false; rgui->trigger_state = input_state; rgui->scroll_accel = min(rgui->scroll_accel + 1, 64); } initial_held = false; } else { first_held = false; initial_held = true; rgui->scroll_accel = 0; } rgui->delay_count++; rgui->old_input_state = input_state; if (driver.block_input) rgui->trigger_state = 0; action = RGUI_ACTION_NOOP; // don't run anything first frame, only capture held inputs for old_input_state if (rgui->trigger_state & (1ULL << RETRO_DEVICE_ID_JOYPAD_UP)) action = RGUI_ACTION_UP; else if (rgui->trigger_state & (1ULL << RETRO_DEVICE_ID_JOYPAD_DOWN)) action = RGUI_ACTION_DOWN; else if (rgui->trigger_state & (1ULL << RETRO_DEVICE_ID_JOYPAD_LEFT)) action = RGUI_ACTION_LEFT; else if (rgui->trigger_state & (1ULL << RETRO_DEVICE_ID_JOYPAD_RIGHT)) action = RGUI_ACTION_RIGHT; else if (rgui->trigger_state & (1ULL << RETRO_DEVICE_ID_JOYPAD_L)) action = RGUI_ACTION_SCROLL_UP; else if (rgui->trigger_state & (1ULL << RETRO_DEVICE_ID_JOYPAD_R)) action = RGUI_ACTION_SCROLL_DOWN; else if (rgui->trigger_state & (1ULL << RETRO_DEVICE_ID_JOYPAD_B)) action = RGUI_ACTION_CANCEL; else if (rgui->trigger_state & (1ULL << RETRO_DEVICE_ID_JOYPAD_A)) action = RGUI_ACTION_OK; else if (rgui->trigger_state & (1ULL << RETRO_DEVICE_ID_JOYPAD_START)) action = RGUI_ACTION_START; if (driver.menu_ctx && driver.menu_ctx->backend && driver.menu_ctx->backend->iterate) input_entry_ret = driver.menu_ctx->backend->iterate(rgui, action); if (driver.video_data && driver.video_poke && driver.video_poke->set_texture_enable) driver.video_poke->set_texture_enable(driver.video_data, rgui->frame_buf_show, MENU_TEXTURE_FULLSCREEN); rarch_render_cached_frame(); // Throttle in case VSync is broken (avoid 1000+ FPS RGUI). rgui->time = rarch_get_time_usec(); rgui->delta = (rgui->time - rgui->last_time) / 1000; rgui->target_msec = 750 / g_settings.video.refresh_rate; // Try to sleep less, so we can hopefully rely on FPS logger. rgui->sleep_msec = rgui->target_msec - rgui->delta; if (rgui->sleep_msec > 0) rarch_sleep((unsigned int)rgui->sleep_msec); rgui->last_time = rarch_get_time_usec(); if (driver.video_data && driver.video_poke && driver.video_poke->set_texture_enable) driver.video_poke->set_texture_enable(driver.video_data, false, MENU_TEXTURE_FULLSCREEN); if (driver.menu_ctx && driver.menu_ctx->input_postprocess) ret = driver.menu_ctx->input_postprocess(rgui, rgui->old_input_state); if (ret < 0) { unsigned type = 0; file_list_get_last(rgui->menu_stack, NULL, &type); while (type != RGUI_SETTINGS) { file_list_pop(rgui->menu_stack, &rgui->selection_ptr); file_list_get_last(rgui->menu_stack, NULL, &type); } } if (ret || input_entry_ret) return false; return true; }
bool menu_iterate(void) { rarch_time_t time, delta, target_msec, sleep_msec; static bool initial_held = true; static bool first_held = false; uint64_t input_state = 0; int input_entry_ret; if (g_extern.lifecycle_mode_state & (1ULL << MODE_MENU_PREINIT)) { rgui->need_refresh = true; g_extern.lifecycle_mode_state &= ~(1ULL << MODE_MENU_PREINIT); rgui->old_input_state |= 1ULL << DEVICE_NAV_MENU; } rarch_input_poll(); #ifdef HAVE_OVERLAY rarch_check_overlay(); #endif if (input_key_pressed_func(RARCH_QUIT_KEY) || !video_alive_func()) { g_extern.lifecycle_mode_state |= (1ULL << MODE_GAME); goto deinit; } input_state = rgui_input(); if (rgui->do_held) { if (!first_held) { first_held = true; rgui->delay_timer = initial_held ? 12 : 6; rgui->delay_count = 0; } if (rgui->delay_count >= rgui->delay_timer) { first_held = false; rgui->trigger_state = input_state; } initial_held = false; } else { first_held = false; initial_held = true; } rgui->delay_count++; rgui->old_input_state = input_state; input_entry_ret = rgui_iterate(rgui); if (driver.video_poke && driver.video_poke->set_texture_enable) driver.video_poke->set_texture_enable(driver.video_data, rgui->frame_buf_show, MENU_TEXTURE_FULLSCREEN); rarch_render_cached_frame(); // Throttle in case VSync is broken (avoid 1000+ FPS RGUI). time = rarch_get_time_usec(); delta = (time - rgui->last_time) / 1000; target_msec = 750 / g_settings.video.refresh_rate; // Try to sleep less, so we can hopefully rely on FPS logger. sleep_msec = target_msec - delta; if (sleep_msec > 0) rarch_sleep(sleep_msec); rgui->last_time = rarch_get_time_usec(); if (driver.video_poke && driver.video_poke->set_texture_enable) driver.video_poke->set_texture_enable(driver.video_data, false, MENU_TEXTURE_FULLSCREEN); if (rgui_input_postprocess(rgui, rgui->old_input_state) || input_entry_ret) goto deinit; return true; deinit: return false; }