changeset 2574:0da40b1978fd

Sprite overflow flag should only be set when there are too many sprites in a line and not when there are just too many sprite pixels. Fixes regression in Madou Monogatari I
author Michael Pavone <pavone@retrodev.com>
date Sun, 02 Feb 2025 23:02:55 -0800
parents 639561060a28
children dddd16a6c69b
files vdp.c vdp.h
diffstat 2 files changed, 15 insertions(+), 17 deletions(-) [+]
line wrap: on
line diff
--- a/vdp.c	Sun Feb 02 19:12:50 2025 -0800
+++ b/vdp.c	Sun Feb 02 23:02:55 2025 -0800
@@ -739,7 +739,7 @@
 
 static void scan_sprite_table(uint32_t line, vdp_context * context)
 {
-	if (context->sprite_index && ((uint8_t)context->slot_counter) < context->max_sprites_line) {
+	if (context->sprite_index && !(context->flags & FLAG_SPRITE_OFLOW)) {
 		line += 1;
 		uint16_t ymask, ymin;
 		uint8_t height_mult;
@@ -769,6 +769,10 @@
 		uint8_t height = ((context->sat_cache[address+2] & 0x3) + 1) * height_mult;
 		//printf("Sprite %d | y: %d, height: %d\n", context->sprite_index, y, height);
 		if (y <= line && line < (y + height)) {
+			if (((uint8_t)context->slot_counter) == context->max_sprites_line) {
+				context->flags |= FLAG_SPRITE_OFLOW;
+				return;
+			}
 			//printf("Sprite %d at y: %d with height %d is on line %d\n", context->sprite_index, y, height, line);
 			context->sprite_info_list[context->slot_counter].size = context->sat_cache[address+2];
 			context->sprite_info_list[context->slot_counter++].index = context->sprite_index;
@@ -786,6 +790,10 @@
 			height = ((context->sat_cache[address+2] & 0x3) + 1) * height_mult;
 			//printf("Sprite %d | y: %d, height: %d\n", context->sprite_index, y, height);
 			if (y <= line && line < (y + height)) {
+				if (((uint8_t)context->slot_counter) == context->max_sprites_line) {
+					context->flags |= FLAG_SPRITE_OFLOW;
+					return;
+				}
 				//printf("Sprite %d at y: %d with height %d is on line %d\n", context->sprite_index, y, height, line);
 				context->sprite_info_list[context->slot_counter].size = context->sat_cache[address+2];
 				context->sprite_info_list[context->slot_counter++].index = context->sprite_index;
@@ -793,7 +801,6 @@
 			context->sprite_index = context->sat_cache[address+3] & 0x7F;
 		}
 	}
-	//TODO: Seems like the overflow flag should be set here if we run out of sprite info slots without hitting the end of the list
 }
 
 static void scan_sprite_table_mode4(vdp_context * context)
@@ -824,7 +831,7 @@
 			if (y <= line && line < (y + ysize)) {
 				if (!context->slot_counter) {
 					context->sprite_index = MAX_SPRITES_FRAME_H32;
-					context->flags |= FLAG_DOT_OFLOW;
+					context->flags |= FLAG_SPRITE_OFLOW;
 					return;
 				}
 				context->sprite_info_list[--(context->slot_counter)].size = size;
@@ -846,7 +853,7 @@
 				if (y <= line && line < (y + ysize)) {
 					if (!context->slot_counter) {
 						context->sprite_index = MAX_SPRITES_FRAME_H32;
-						context->flags |= FLAG_DOT_OFLOW;
+						context->flags |= FLAG_SPRITE_OFLOW;
 						return;
 					}
 					context->sprite_info_list[--(context->slot_counter)].size = size;
@@ -3199,9 +3206,6 @@
 	render_sprite_cells(context);
 	scan_sprite_table(context->vcounter, context);
 	//255
-	if (context->cur_slot >= 0 && context->sprite_draw_list[context->cur_slot].x_pos) {
-		context->flags |= FLAG_DOT_OFLOW;
-	}
 	scan_sprite_table(context->vcounter, context);
 	//0
 	scan_sprite_table(context->vcounter, context);//Just a guess
@@ -3419,9 +3423,6 @@
 		CHECK_LIMIT
 	SPRITE_RENDER_H40(254)
 	case 255:
-		if (context->cur_slot >= 0 && context->sprite_draw_list[context->cur_slot].x_pos) {
-			context->flags |= FLAG_DOT_OFLOW;
-		}
 		render_map_3(context);
 		scan_sprite_table(context->vcounter, context);//Just a guess
 		CHECK_LIMIT
@@ -3630,9 +3631,6 @@
 		CHECK_LIMIT
 	SPRITE_RENDER_H32(250)
 	case 251:
-		if (context->cur_slot >= 0 && context->sprite_draw_list[context->cur_slot].x_pos) {
-			context->flags |= FLAG_DOT_OFLOW;
-		}
 		render_map_1(context);
 		scan_sprite_table(context->vcounter, context);//Just a guess
 		CHECK_LIMIT
@@ -3969,7 +3967,7 @@
 	if (diff < size) {
 		context->sprite_info_list[context->sprite_draws++].index = context->sprite_index;
 		if (context->sprite_draws == 5) {
-			context->flags |= FLAG_DOT_OFLOW;
+			context->flags |= FLAG_SPRITE_OFLOW;
 		}
 	} else {
 		context->sprite_info_list[4].index = context->sprite_index;
@@ -5148,7 +5146,7 @@
 	if (context->flags2 & FLAG2_VINT_PENDING) {
 		value |= 0x80;
 	}
-	if (context->flags & FLAG_DOT_OFLOW) {
+	if (context->flags & FLAG_SPRITE_OFLOW) {
 		value |= 0x40;
 	}
 	if (context->flags2 & FLAG2_SPRITE_COLLIDE) {
@@ -5182,7 +5180,7 @@
 uint16_t vdp_control_port_read(vdp_context * context)
 {
 	uint16_t value = vdp_status(context);
-	context->flags &= ~(FLAG_DOT_OFLOW|FLAG_PENDING);
+	context->flags &= ~(FLAG_SPRITE_OFLOW|FLAG_PENDING);
 	context->flags2 &= ~(FLAG2_SPRITE_COLLIDE|FLAG2_BYTE_PENDING);
 	//printf("status read at cycle %d returned %X\n", context->cycles, value);
 	return value;
--- a/vdp.h	Sun Feb 02 19:12:50 2025 -0800
+++ b/vdp.h	Sun Feb 02 23:02:55 2025 -0800
@@ -52,7 +52,7 @@
 
 #define MCLKS_LINE 3420
 
-#define FLAG_DOT_OFLOW     0x01
+#define FLAG_SPRITE_OFLOW  0x01
 #define FLAG_CAN_MASK      0x02
 #define FLAG_MASKED        0x04
 #define FLAG_WINDOW        0x08