# HG changeset patch # User Michael Pavone # Date 1724821804 25200 # Node ID e51b1fc0e37f357c91eaf84dd01e676ed97b6462 # Parent 0a22c1901492acf34082b52e891bb4c5be947cee Fix rendering of sprites that are partially off the top of the screen in Mode 4 diff -r 0a22c1901492 -r e51b1fc0e37f vdp.c --- 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; }