From: Toni Wilen Date: Sat, 25 Mar 2017 17:24:20 +0000 (+0200) Subject: Check overrun even if whole line is emulated in single pass. Check for extremely... X-Git-Tag: 3500~76 X-Git-Url: https://git.unchartedbackwaters.co.uk/w/?a=commitdiff_plain;h=42a686a6fd4f869ebe36e53ded76504c9764d311;p=francis%2Fwinuae.git Check overrun even if whole line is emulated in single pass. Check for extremely wide overrun line lengths and limit to sane size. --- diff --git a/custom.cpp b/custom.cpp index 930fa761..30e726fc 100644 --- a/custom.cpp +++ b/custom.cpp @@ -1301,8 +1301,9 @@ static void update_toscr_planes (int fm) STATIC_INLINE void maybe_first_bpl1dat (int hpos) { - if (thisline_decision.plfleft < 0) + if (thisline_decision.plfleft < 0) { thisline_decision.plfleft = hpos; + } } static int fetch_warn (int nr, int hpos) @@ -2364,6 +2365,9 @@ static void finish_final_fetch (void) // This is really the end of scanline, we can finally flush all remaining data. thisline_decision.plfright += flush_plane_data (fetchmode); + // This can overflow if display setup is really bad. + if (out_offs > MAX_PIXELS_PER_LINE / 32) + out_offs = MAX_PIXELS_PER_LINE / 32; thisline_decision.plflinelen = out_offs; finish_playfield_line (); @@ -2740,7 +2744,7 @@ static void decide_fetch (int hpos) STATIC_INLINE void decide_fetch_safe (int hpos) { - if (!blitter_dangerous_bpl) { + if (!blitter_dangerous_bpl && !bitplane_overrun) { decide_fetch (hpos); decide_blitter (hpos); } else { @@ -3700,6 +3704,10 @@ static void finish_decisions (void) if (nodraw ()) return; + // if overrun at the beginning of scanline was not handled: do it here first. + if (bitplane_overrun) { + do_overrun_fetch(hpos, fetchmode); + } decide_diw (hpos); decide_line (hpos); decide_fetch_safe (hpos); diff --git a/drawing.cpp b/drawing.cpp index fd88ac3b..734a4ace 100644 --- a/drawing.cpp +++ b/drawing.cpp @@ -1002,6 +1002,8 @@ static void pfield_init_linetoscr (bool border) /* Now, compute some offsets. */ ddf_left -= DISPLAY_LEFT_SHIFT; + if (ddf_left < 0) + ddf_left = 0; pixels_offset = MAX_PIXELS_PER_LINE - (ddf_left << bplres); ddf_left <<= bplres; @@ -1033,8 +1035,11 @@ static void pfield_init_linetoscr (bool border) if (linetoscr_diw_end > native_ddf_right) { int pos = res_shift_from_window (native_ddf_right - native_ddf_left); int size = res_shift_from_window (linetoscr_diw_end - native_ddf_right); + if (pos + size > MAX_PIXELS_PER_LINE) + size = MAX_PIXELS_PER_LINE - pos; + if (size > 0) + memset (pixdata.apixels + MAX_PIXELS_PER_LINE + pos, 0, size); linetoscr_diw_start = native_ddf_left; - memset (pixdata.apixels + MAX_PIXELS_PER_LINE + pos, 0, size); } } @@ -1048,7 +1053,10 @@ static void pfield_erase_hborder_sprites (void) if (sprite_last_x > native_ddf_right) { int pos = res_shift_from_window (native_ddf_right - native_ddf_left); int size = res_shift_from_window (sprite_last_x - native_ddf_right); - memset (pixdata.apixels + MAX_PIXELS_PER_LINE + pos, 0, size); + if (pos + size > MAX_PIXELS_PER_LINE) + size = MAX_PIXELS_PER_LINE - pos; + if (size > 0) + memset (pixdata.apixels + MAX_PIXELS_PER_LINE + pos, 0, size); } }