changeset 2511:e51b1fc0e37f

Fix rendering of sprites that are partially off the top of the screen in Mode 4
author Michael Pavone <pavone@retrodev.com>
date Tue, 27 Aug 2024 22:10:04 -0700
parents 0a22c1901492
children 9df8dec435b7
files vdp.c
diffstat 1 files changed, 17 insertions(+), 4 deletions(-) [+]
line wrap: on
line diff
--- a/vdp.c	Tue Aug 27 21:27:21 2024 -0700
+++ b/vdp.c	Tue Aug 27 22:10:04 2024 -0700
@@ -794,13 +794,16 @@
 static void scan_sprite_table_mode4(vdp_context * context)
 {
 	if (context->sprite_index < MAX_SPRITES_FRAME_H32) {
-		uint32_t line = context->vcounter;
+		int16_t line = context->vcounter;
 		line &= 0xFF;
+		if (line > context->inactive_start) {
+			line -= 0x100;
+		}
 
 		uint32_t sat_address = mode4_address_map[(context->regs[REG_SAT] << 7 & 0x3F00) + context->sprite_index];
-		uint32_t y = context->vdpmem[sat_address+1];
+		int16_t y = context->vdpmem[sat_address+1];
 		uint32_t size = (context->regs[REG_MODE_2] & BIT_SPRITE_SZ) ? 16 : 8;
-		uint32_t ysize = size;
+		int16_t ysize = size;
 		uint8_t zoom = context->type != VDP_GENESIS && (context->regs[REG_MODE_2] & BIT_SPRITE_ZM);
 		if (zoom) {
 			ysize *= 2;
@@ -810,6 +813,9 @@
 			context->sprite_index = MAX_SPRITES_FRAME_H32;
 			return;
 		} else {
+			if (y > context->inactive_start) {
+				y -= 0x100;
+			}
 			if (y <= line && line < (y + ysize)) {
 				if (!context->slot_counter) {
 					context->sprite_index = MAX_SPRITES_FRAME_H32;
@@ -829,6 +835,9 @@
 				context->sprite_index = MAX_SPRITES_FRAME_H32;
 				return;
 			} else {
+				if (y > context->inactive_start) {
+					y -= 0x100;
+				}
 				if (y <= line && line < (y + ysize)) {
 					if (!context->slot_counter) {
 						context->sprite_index = MAX_SPRITES_FRAME_H32;
@@ -919,7 +928,11 @@
 		if (context->regs[REG_MODE_2] & BIT_SPRITE_SZ) {
 			tile_address &= ~32;
 		}
-		uint16_t y_diff = context->vcounter - context->sprite_info_list[context->cur_slot].y;
+		int16_t line = context->vcounter & 0xFF;
+		if (context->vcounter > context->inactive_start) {
+			line -= 0x100;
+		}
+		uint16_t y_diff = line - context->sprite_info_list[context->cur_slot].y;
 		if (zoom) {
 			y_diff >>= 1;
 		}