From 16e995025304b7be105409bf3074e4be8867b77b Mon Sep 17 00:00:00 2001 From: sonninnos Date: Sat, 2 May 2026 07:43:42 +0300 Subject: [PATCH 1/2] XMB/Ozone: Fix startup page glitch --- menu/drivers/xmb.c | 12 ++++++++++-- runloop.c | 1 + 2 files changed, 11 insertions(+), 2 deletions(-) diff --git a/menu/drivers/xmb.c b/menu/drivers/xmb.c index b80c1f3e33a..1d93268effd 100644 --- a/menu/drivers/xmb.c +++ b/menu/drivers/xmb.c @@ -2793,7 +2793,7 @@ static void xmb_list_switch(xmb_handle_t *xmb) unsigned remember_selection_type = settings->uints.menu_remember_selection; unsigned xmb_system_tab = xmb_get_system_tab(xmb, (unsigned)xmb->categories_selection_ptr); bool xmb_main_tab_selected = false; - bool horizontal_animation = settings->bools.menu_horizontal_animation; + bool horizontal_animation = settings->bools.menu_horizontal_animation && xmb->allow_horizontal_animation; int list_delta = 0; unsigned animation_horizontal_highlight = settings->uints.menu_xmb_animation_horizontal_highlight; @@ -3500,7 +3500,7 @@ static void xmb_populate_entries(void *data, else xmb_list_open(xmb, settings->uints.menu_xmb_animation_opening_main_menu, - settings->bools.menu_horizontal_animation, + settings->bools.menu_horizontal_animation && xmb->allow_horizontal_animation, settings->bools.savestate_thumbnail_enable); xmb_set_title(xmb); @@ -9309,6 +9309,10 @@ static void xmb_frame(void *data, video_frame_info_t *video_info) if (ctx_gen != xmb->context_generation) goto ctx_destroyed; + /* Restore horizontal animation ability after first toggle */ + if (xmb->is_first_frame) + xmb->allow_horizontal_animation = true; + /* First-frame init done — subsequent frames are normal. * Cleared after the last ctx-destroyed guard so that a context * death mid-frame leaves the flag set for the retry. */ @@ -9999,6 +10003,10 @@ static void xmb_toggle(void *userdata, bool menu_on) else menu_st->flags |= MENU_ST_FLAG_PREVENT_POPULATE; + /* Prevent initial jumping with startup page and CLI launch */ + if (xmb->is_first_frame) + xmb->allow_horizontal_animation = false; + xmb_toggle_horizontal_list(xmb); /* Skip the fade-in on the very first frame after init: at diff --git a/runloop.c b/runloop.c index 5e63dde936d..e2591708536 100644 --- a/runloop.c +++ b/runloop.c @@ -6281,6 +6281,7 @@ static enum runloop_state_enum runloop_check_state( } menu_st->flags &= ~MENU_ST_FLAG_PENDING_STARTUP_PAGE; + return RUNLOOP_STATE_POLLED_AND_SLEEP; } else if (!menu_driver_iterate(menu_st, p_disp, anim_get_ptr(), settings, action, current_time)) From e447a438dd3f51b61b2300cc9d1cbcf38205bd84 Mon Sep 17 00:00:00 2001 From: sonninnos Date: Sat, 2 May 2026 08:24:16 +0300 Subject: [PATCH 2/2] Scanline Sync tweaks --- gfx/video_driver.c | 12 +++++++----- 1 file changed, 7 insertions(+), 5 deletions(-) diff --git a/gfx/video_driver.c b/gfx/video_driver.c index 67688351608..b3d9a0463da 100644 --- a/gfx/video_driver.c +++ b/gfx/video_driver.c @@ -5364,11 +5364,13 @@ static INLINE void video_driver_scanline_before_frame(video_driver_state_t *vide } else if (video_st->frame_count > refresh_rate) { - /* Disable if the core frame takes too long or has too much deviation */ - double stddev = 0.0; - video_monitor_fps_statistics(NULL, &stddev, NULL); + /* Disable if the core and/or frame takes too long */ + uint16_t frame_time_index = video_st->frame_time_count & (MEASURE_FRAME_TIME_SAMPLES_COUNT - 1); + uint16_t sample_index = (uint16_t)((frame_time_index - 1) & (MEASURE_FRAME_TIME_SAMPLES_COUNT - 1)); + retro_time_t frame_time = video_st->frame_time_samples[sample_index]; - if (stddev > 0.75f || core_run_time > frame_time_target) + if ( core_run_time > frame_time_target + || frame_time > frame_time_target * 2) { scanline_next = 0; scanline_hold = refresh_rate / 2; @@ -5394,7 +5396,7 @@ static INLINE void video_driver_scanline_before_frame(video_driver_state_t *vide /* Core time based minimum nudge */ while ( corelines > 0 && scanline_next >= -corelines - && core_run_time < frame_time_target / 4) + && core_run_time < frame_time_target / 3) { scanline_next--; corelines--;