@@ -5368,13 +5368,15 @@ static INLINE void video_driver_scanline_before_frame(video_driver_state_t *vide
53685368 uint16_t frame_time_index = video_st -> frame_time_count & (MEASURE_FRAME_TIME_SAMPLES_COUNT - 1 );
53695369 uint16_t sample_index = (uint16_t )((frame_time_index - 1 ) & (MEASURE_FRAME_TIME_SAMPLES_COUNT - 1 ));
53705370 retro_time_t frame_time = video_st -> frame_time_samples [sample_index ];
5371+ bool frame_time_deviation = frame_time >= frame_time_target * 1.66f || frame_time <= frame_time_target * 0.33f ;
53715372
5372- if ( core_run_time > frame_time_target
5373- || frame_time > frame_time_target * 2 )
5373+ if (scanline_hold && (frame_time_deviation || core_run_time >= frame_time_target - 3000 ))
53745374 {
53755375 scanline_next = 0 ;
53765376 scanline_hold = refresh_rate / 2 ;
53775377 }
5378+ else if (!scanline_hold && frame_time_deviation )
5379+ scanline_hold += 3 ;
53785380 }
53795381
53805382 /* Shift overflow */
@@ -5384,19 +5386,28 @@ static INLINE void video_driver_scanline_before_frame(video_driver_state_t *vide
53845386 /* Allow change */
53855387 if (!scanline_hold )
53865388 {
5387- int16_t corelines = video_height * ((double )core_run_time / (double )frame_time_target );
5389+ int16_t corelines = ( video_height + scanline_blank ) * ((double )core_run_time / (double )frame_time_target );
53885390
53895391 /* Fine-tuning */
53905392 if ( scanline > - scanline_blank
5391- && scanline < corelines )
5393+ && scanline < corelines + scanline_blank )
53925394 scanline_next -= 2 ;
5393- else if (scanline_next < scanline + corelines )
5395+ else if (scanline_next <= scanline + corelines )
53945396 scanline_next += 4 ;
53955397
5398+ if ( scanline > 0
5399+ && scanline < video_height - scanline_blank
5400+ && scanline_next >= - (scanline + corelines + scanline_blank ))
5401+ scanline_next -- ;
5402+ else if (scanline > (video_height - scanline_blank ) / 2
5403+ || scanline < - scanline_blank )
5404+ scanline_next ++ ;
5405+
53965406 /* Core time based minimum nudge */
53975407 while ( corelines > 0
5408+ && scanline > scanline_blank
53985409 && scanline_next >= - corelines
5399- && core_run_time < frame_time_target / 3 )
5410+ && core_run_time <= frame_time_target / 2 )
54005411 {
54015412 scanline_next -- ;
54025413 corelines -- ;
@@ -5447,7 +5458,7 @@ static INLINE void video_driver_scanline_after_frame(video_driver_state_t *video
54475458 if (wait && frame_time_target > core_run_time )
54485459 {
54495460 int8_t sleep = (frame_time_target - core_run_time ) / 1000 ;
5450- if (sleep > 0 )
5461+ if (sleep > 1 )
54515462 {
54525463 /* Sleeping too much causes problems */
54535464 sleep -= 4 ;
0 commit comments