# HG changeset patch # User Michael Pavone # Date 1738566175 28800 # Node ID 0da40b1978fd2535af8e4ddd3042e1c4737b2b0c # Parent 639561060a2840af665f76ba140d47778f60bf66 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 diff -r 639561060a28 -r 0da40b1978fd vdp.c --- 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; diff -r 639561060a28 -r 0da40b1978fd vdp.h --- 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