Mercurial > repos > blastem
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 } |