comparison vdp.c @ 2204:dc4268a778bc

Implement Mode 4 sprite zooming
author Michael Pavone <pavone@retrodev.com>
date Mon, 22 Aug 2022 23:21:16 -0700
parents 2f8984ff5c85
children 90297f1fb3fe
comparison
equal deleted inserted replaced
2203:9826d50061a0 2204:dc4268a778bc
390 } 390 }
391 391
392 static void render_sprite_cells_mode4(vdp_context * context) 392 static void render_sprite_cells_mode4(vdp_context * context)
393 { 393 {
394 if (context->sprite_index >= context->sprite_draws) { 394 if (context->sprite_index >= context->sprite_draws) {
395 uint8_t zoom = context->type != VDP_GENESIS && (context->regs[REG_MODE_2] & BIT_SPRITE_ZM);
396 if (context->type == VDP_SMS && context->sprite_index < 4) {
397 zoom = 0;
398 }
395 sprite_draw * d = context->sprite_draw_list + context->sprite_index; 399 sprite_draw * d = context->sprite_draw_list + context->sprite_index;
396 uint32_t pixels = planar_to_chunky[context->fetch_tmp[0]] << 1; 400 uint32_t pixels = planar_to_chunky[context->fetch_tmp[0]] << 1;
397 pixels |= planar_to_chunky[context->fetch_tmp[1]]; 401 pixels |= planar_to_chunky[context->fetch_tmp[1]];
398 uint32_t address = mode4_address_map[(d->address + 2) & 0x3FFF]; 402 uint32_t address = mode4_address_map[(d->address + 2) & 0x3FFF];
399 pixels |= planar_to_chunky[context->vdpmem[address]] << 3; 403 pixels |= planar_to_chunky[context->vdpmem[address]] << 3;
408 ) { 412 ) {
409 context->flags2 |= FLAG2_SPRITE_COLLIDE; 413 context->flags2 |= FLAG2_SPRITE_COLLIDE;
410 } 414 }
411 } else { 415 } else {
412 context->linebuf[x] = pixels >> i & 0xF; 416 context->linebuf[x] = pixels >> i & 0xF;
417 }
418 if (zoom) {
419 x++;
420 if (context->linebuf[x] && (pixels >> i & 0xF)) {
421 if (
422 ((context->regs[REG_MODE_1] & BIT_SPRITE_8PX) && x > 8)
423 || ((!(context->regs[REG_MODE_1] & BIT_SPRITE_8PX)) && x < 256)
424 ) {
425 context->flags2 |= FLAG2_SPRITE_COLLIDE;
426 }
427 } else {
428 context->linebuf[x] = pixels >> i & 0xF;
429 }
413 } 430 }
414 } 431 }
415 context->sprite_index--; 432 context->sprite_index--;
416 } 433 }
417 } 434 }
681 line &= 0xFF; 698 line &= 0xFF;
682 699
683 uint32_t sat_address = mode4_address_map[(context->regs[REG_SAT] << 7 & 0x3F00) + context->sprite_index]; 700 uint32_t sat_address = mode4_address_map[(context->regs[REG_SAT] << 7 & 0x3F00) + context->sprite_index];
684 uint32_t y = context->vdpmem[sat_address+1]; 701 uint32_t y = context->vdpmem[sat_address+1];
685 uint32_t size = (context->regs[REG_MODE_2] & BIT_SPRITE_SZ) ? 16 : 8; 702 uint32_t size = (context->regs[REG_MODE_2] & BIT_SPRITE_SZ) ? 16 : 8;
703 uint32_t ysize = size;
704 uint8_t zoom = context->type != VDP_GENESIS && (context->regs[REG_MODE_2] & BIT_SPRITE_ZM);
705 if (context->type == VDP_SMS && context->slot_counter <= 4) {
706 zoom = 0;
707 }
708 if (zoom) {
709 ysize *= 2;
710 }
686 711
687 if (y == 0xd0) { 712 if (y == 0xd0) {
688 context->sprite_index = MAX_SPRITES_FRAME_H32; 713 context->sprite_index = MAX_SPRITES_FRAME_H32;
689 return; 714 return;
690 } else { 715 } else {
691 if (y <= line && line < (y + size)) { 716 if (y <= line && line < (y + ysize)) {
692 if (!context->slot_counter) { 717 if (!context->slot_counter) {
693 context->sprite_index = MAX_SPRITES_FRAME_H32; 718 context->sprite_index = MAX_SPRITES_FRAME_H32;
694 context->flags |= FLAG_DOT_OFLOW; 719 context->flags |= FLAG_DOT_OFLOW;
695 return; 720 return;
696 } 721 }
705 y = context->vdpmem[sat_address]; 730 y = context->vdpmem[sat_address];
706 if (y == 0xd0) { 731 if (y == 0xd0) {
707 context->sprite_index = MAX_SPRITES_FRAME_H32; 732 context->sprite_index = MAX_SPRITES_FRAME_H32;
708 return; 733 return;
709 } else { 734 } else {
710 if (y <= line && line < (y + size)) { 735 if (y <= line && line < (y + ysize)) {
711 if (!context->slot_counter) { 736 if (!context->slot_counter) {
712 context->sprite_index = MAX_SPRITES_FRAME_H32; 737 context->sprite_index = MAX_SPRITES_FRAME_H32;
713 context->flags |= FLAG_DOT_OFLOW; 738 context->flags |= FLAG_DOT_OFLOW;
714 return; 739 return;
715 } 740 }
786 { 811 {
787 if (context->cur_slot >= context->slot_counter) { 812 if (context->cur_slot >= context->slot_counter) {
788 uint32_t address = (context->regs[REG_SAT] << 7 & 0x3F00) + 0x80 + context->sprite_info_list[context->cur_slot].index * 2; 813 uint32_t address = (context->regs[REG_SAT] << 7 & 0x3F00) + 0x80 + context->sprite_info_list[context->cur_slot].index * 2;
789 address = mode4_address_map[address]; 814 address = mode4_address_map[address];
790 --context->sprite_draws; 815 --context->sprite_draws;
816 uint8_t zoom = context->type != VDP_GENESIS && (context->regs[REG_MODE_2] & BIT_SPRITE_ZM);
817 if (context->type == VDP_SMS && context->sprite_draws < 4) {
818 zoom = 0;
819 }
791 uint32_t tile_address = context->vdpmem[address] * 32 + (context->regs[REG_STILE_BASE] << 11 & 0x2000); 820 uint32_t tile_address = context->vdpmem[address] * 32 + (context->regs[REG_STILE_BASE] << 11 & 0x2000);
792 if (context->regs[REG_MODE_2] & BIT_SPRITE_SZ) { 821 if (context->regs[REG_MODE_2] & BIT_SPRITE_SZ) {
793 tile_address &= ~32; 822 tile_address &= ~32;
794 } 823 }
795 tile_address += (context->vcounter - context->sprite_info_list[context->cur_slot].y)* 4; 824 uint16_t y_diff = context->vcounter - context->sprite_info_list[context->cur_slot].y;
825 if (zoom) {
826 y_diff >>= 1;
827 }
828 tile_address += y_diff * 4;
796 context->sprite_draw_list[context->sprite_draws].x_pos = context->vdpmem[address + 1]; 829 context->sprite_draw_list[context->sprite_draws].x_pos = context->vdpmem[address + 1];
797 context->sprite_draw_list[context->sprite_draws].address = tile_address; 830 context->sprite_draw_list[context->sprite_draws].address = tile_address;
798 context->cur_slot--; 831 context->cur_slot--;
799 } 832 }
800 } 833 }