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];