From 5490d869dfb3f1be9393bec1ef251dab060293b3 Mon Sep 17 00:00:00 2001 From: Toni Wilen Date: Sat, 14 Jan 2023 15:59:57 +0200 Subject: [PATCH] Color change and sprite buffer limit checks. --- custom.cpp | 29 ++++++++++++++++++++++++++--- include/drawing.h | 2 +- 2 files changed, 27 insertions(+), 4 deletions(-) diff --git a/custom.cpp b/custom.cpp index 33086e37..d7d43399 100644 --- a/custom.cpp +++ b/custom.cpp @@ -153,6 +153,7 @@ static bool nosignal_trigger; int display_reset; static evt_t line_start_cycles; static bool initial_frame; +static evt_t custom_color_write_cycle; #define LOF_TOGGLES_NEEDED 3 //#define NLACE_CNT_NEEDED 50 @@ -546,7 +547,7 @@ static struct draw_info line_drawinfo[2][2 * (MAXVPOS + MAXVPOS_WRAPLINES) + 1]; #define COLOR_TABLE_SIZE (MAXVPOS + MAXVPOS_WRAPLINES) * 2 static struct color_entry color_tables[2][COLOR_TABLE_SIZE]; -static int next_sprite_entry = 0; +static int next_sprite_entry = 0, last_sprite_entry = 0; static int prev_next_sprite_entry; static int next_sprite_forced = 1; @@ -997,6 +998,10 @@ static void record_color_change2(int hpos, int regno, uae_u32 value) return; } + if (next_color_change > MAX_REG_CHANGE - 30) { + return; + } + int pos = hpos < 0 ? -hpos : hpos_to_diwx(hpos); // AGA has extra hires pixel delay in color changes @@ -5022,6 +5027,11 @@ static void record_sprite(int num, int sprxp, uae_u16 *data, uae_u16 *datb, unsi int attachment; int spr_width; + // do nothing if buffer is full (shouldn't happen normally) + if (next_sprite_entry >= last_sprite_entry) { + return; + } + half = 0; dbl = sprite_buffer_res - sprres; if (dbl < 0) { @@ -9173,6 +9183,13 @@ bool get_custom_color_reg(int colreg, uae_u8 *r, uae_u8 *g, uae_u8 *b) static void COLOR_WRITE(int hpos, uae_u16 v, int num) { bool colzero = false; + + // skip color register write color change state update if color register was already written in same cycle + // fast CPU modes can write tens of thousands of color registers in single frame. + evt_t c = get_cycles() & ~(CYCLE_UNIT - 1); + bool samecycle = c == custom_color_write_cycle; + custom_color_write_cycle = c; + #ifdef AGA if (aga_mode) { int r,g,b; @@ -9214,7 +9231,9 @@ static void COLOR_WRITE(int hpos, uae_u16 v, int num) } /* Call this with the old table still intact. */ - record_color_change(hpos, colreg, cval); + if (!samecycle) { + record_color_change(hpos, colreg, cval); + } remembered_color_entry = -1; current_colors.color_regs_aga[colreg] = cval; current_colors.acolors[colreg] = getxcolor(cval); @@ -9237,7 +9256,9 @@ static void COLOR_WRITE(int hpos, uae_u16 v, int num) } /* Call this with the old table still intact. */ - record_color_change(hpos, num, v); + if (!samecycle) { + record_color_change(hpos, num, v); + } remembered_color_entry = -1; current_colors.color_regs_ecs[num] = v; current_colors.acolors[num] = getxcolor (v); @@ -10765,6 +10786,7 @@ void init_hardware_for_drawing_frame(void) } prev_next_sprite_entry = next_sprite_entry; next_sprite_entry = 0; + last_sprite_entry = MAX_SPR_PIXELS - 1; next_lineno = calculate_lineno(vpos); last_color_change = 0; @@ -13362,6 +13384,7 @@ void custom_reset(bool hardreset, bool keyboardreset) copper_dma_change_cycle = -1; blitter_dma_change_cycle = -1; sprite_dma_change_cycle_on = -1; + custom_color_write_cycle = -1; if (hardreset || savestate_state) { maxhpos = ntsc ? MAXHPOS_NTSC : MAXHPOS_PAL; diff --git a/include/drawing.h b/include/drawing.h index 04895b99..c303a8e5 100644 --- a/include/drawing.h +++ b/include/drawing.h @@ -259,7 +259,7 @@ struct color_change { #define MAXVPOS_WRAPLINES 10 /* No divisors for MAX_PIXELS_PER_LINE; we support AGA and SHRES sprites */ -#define MAX_SPR_PIXELS (((MAXVPOS + MAXVPOS_WRAPLINES) * 2 + 1) * MAX_PIXELS_PER_LINE) +#define MAX_SPR_PIXELS ((((MAXVPOS + MAXVPOS_WRAPLINES) * 2 + 1) * MAX_PIXELS_PER_LINE) / 16) struct sprite_entry { -- 2.47.3