Mercurial > repos > blastem
comparison vdp.c @ 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 | 61645edbe30f |
comparison
equal
deleted
inserted
replaced
2510:0a22c1901492 | 2511:e51b1fc0e37f |
---|---|
792 } | 792 } |
793 | 793 |
794 static void scan_sprite_table_mode4(vdp_context * context) | 794 static void scan_sprite_table_mode4(vdp_context * context) |
795 { | 795 { |
796 if (context->sprite_index < MAX_SPRITES_FRAME_H32) { | 796 if (context->sprite_index < MAX_SPRITES_FRAME_H32) { |
797 uint32_t line = context->vcounter; | 797 int16_t line = context->vcounter; |
798 line &= 0xFF; | 798 line &= 0xFF; |
799 if (line > context->inactive_start) { | |
800 line -= 0x100; | |
801 } | |
799 | 802 |
800 uint32_t sat_address = mode4_address_map[(context->regs[REG_SAT] << 7 & 0x3F00) + context->sprite_index]; | 803 uint32_t sat_address = mode4_address_map[(context->regs[REG_SAT] << 7 & 0x3F00) + context->sprite_index]; |
801 uint32_t y = context->vdpmem[sat_address+1]; | 804 int16_t y = context->vdpmem[sat_address+1]; |
802 uint32_t size = (context->regs[REG_MODE_2] & BIT_SPRITE_SZ) ? 16 : 8; | 805 uint32_t size = (context->regs[REG_MODE_2] & BIT_SPRITE_SZ) ? 16 : 8; |
803 uint32_t ysize = size; | 806 int16_t ysize = size; |
804 uint8_t zoom = context->type != VDP_GENESIS && (context->regs[REG_MODE_2] & BIT_SPRITE_ZM); | 807 uint8_t zoom = context->type != VDP_GENESIS && (context->regs[REG_MODE_2] & BIT_SPRITE_ZM); |
805 if (zoom) { | 808 if (zoom) { |
806 ysize *= 2; | 809 ysize *= 2; |
807 } | 810 } |
808 | 811 |
809 if (y == 0xd0) { | 812 if (y == 0xd0) { |
810 context->sprite_index = MAX_SPRITES_FRAME_H32; | 813 context->sprite_index = MAX_SPRITES_FRAME_H32; |
811 return; | 814 return; |
812 } else { | 815 } else { |
816 if (y > context->inactive_start) { | |
817 y -= 0x100; | |
818 } | |
813 if (y <= line && line < (y + ysize)) { | 819 if (y <= line && line < (y + ysize)) { |
814 if (!context->slot_counter) { | 820 if (!context->slot_counter) { |
815 context->sprite_index = MAX_SPRITES_FRAME_H32; | 821 context->sprite_index = MAX_SPRITES_FRAME_H32; |
816 context->flags |= FLAG_DOT_OFLOW; | 822 context->flags |= FLAG_DOT_OFLOW; |
817 return; | 823 return; |
827 y = context->vdpmem[sat_address]; | 833 y = context->vdpmem[sat_address]; |
828 if (y == 0xd0) { | 834 if (y == 0xd0) { |
829 context->sprite_index = MAX_SPRITES_FRAME_H32; | 835 context->sprite_index = MAX_SPRITES_FRAME_H32; |
830 return; | 836 return; |
831 } else { | 837 } else { |
838 if (y > context->inactive_start) { | |
839 y -= 0x100; | |
840 } | |
832 if (y <= line && line < (y + ysize)) { | 841 if (y <= line && line < (y + ysize)) { |
833 if (!context->slot_counter) { | 842 if (!context->slot_counter) { |
834 context->sprite_index = MAX_SPRITES_FRAME_H32; | 843 context->sprite_index = MAX_SPRITES_FRAME_H32; |
835 context->flags |= FLAG_DOT_OFLOW; | 844 context->flags |= FLAG_DOT_OFLOW; |
836 return; | 845 return; |
917 uint8_t zoom = context->type != VDP_GENESIS && (context->regs[REG_MODE_2] & BIT_SPRITE_ZM); | 926 uint8_t zoom = context->type != VDP_GENESIS && (context->regs[REG_MODE_2] & BIT_SPRITE_ZM); |
918 uint32_t tile_address = context->vdpmem[address] * 32 + (context->regs[REG_STILE_BASE] << 11 & 0x2000); | 927 uint32_t tile_address = context->vdpmem[address] * 32 + (context->regs[REG_STILE_BASE] << 11 & 0x2000); |
919 if (context->regs[REG_MODE_2] & BIT_SPRITE_SZ) { | 928 if (context->regs[REG_MODE_2] & BIT_SPRITE_SZ) { |
920 tile_address &= ~32; | 929 tile_address &= ~32; |
921 } | 930 } |
922 uint16_t y_diff = context->vcounter - context->sprite_info_list[context->cur_slot].y; | 931 int16_t line = context->vcounter & 0xFF; |
932 if (context->vcounter > context->inactive_start) { | |
933 line -= 0x100; | |
934 } | |
935 uint16_t y_diff = line - context->sprite_info_list[context->cur_slot].y; | |
923 if (zoom) { | 936 if (zoom) { |
924 y_diff >>= 1; | 937 y_diff >>= 1; |
925 } | 938 } |
926 tile_address += y_diff * 4; | 939 tile_address += y_diff * 4; |
927 context->sprite_draw_list[context->sprite_draws].x_pos = context->vdpmem[address + 1]; | 940 context->sprite_draw_list[context->sprite_draws].x_pos = context->vdpmem[address + 1]; |