Mercurial > repos > simple16
diff src/vdp.c @ 22:407725d9a02f
Implemented sprite drawing. Added small sprite example.
author | Michael Pavone <pavone@retrodev.com> |
---|---|
date | Wed, 30 Mar 2016 19:55:48 -0700 |
parents | 91ded3b12d96 |
children | a085f17b79e9 |
line wrap: on
line diff
--- a/src/vdp.c Tue Mar 29 19:59:26 2016 -0700 +++ b/src/vdp.c Wed Mar 30 19:55:48 2016 -0700 @@ -41,6 +41,9 @@ context->readbuffer = context->linebuffers + 328; } context->draw_dest = 0; + //enable sprite scanning + context->status |= VDP_STATUS_SPRITE_SCAN; + context->current_draw = 0; } if (context->draw_counter) { context->draw_counter--; @@ -70,9 +73,67 @@ context->draw_counter = 2; //TODO: handle horizontal flip } - //TODO: Scan sprite table + if (context->status & VDP_STATUS_SPRITE_SCAN) { + context->status |= VDP_STATUS_SRAM; + uint16_t pos = context->sram[context->hcounter]; + uint16_t y = pos & 0xFF; + uint16_t x = pos >> 8; + uint16_t atts = context->sram[context->hcounter+1]; + x |= atts << 2 & 0x100; + if (x | y) { + uint16_t size = atts & 0x400 ? 16 : 8; + if (context->vcounter >= y && context->vcounter < y + size) { + uint16_t address = (atts & 0x3F) * 16; + if (atts & 0x1000) { + address += (size-1) * 2 - (context->vcounter - y) * 2; + } else { + address += (context->vcounter - y) * 2; + } + context->sprite_draws[context->current_draw].source = address; + context->sprite_draws[context->current_draw].x = x; + context->sprite_draws[context->current_draw].hflip = (atts & 0x800) != 0; + context->sprite_draws[context->current_draw].palpriority = 0x80 | (atts >> 9 & 0x50); + context->current_draw++; + if (size == 16) { + context->sprite_draws[context->current_draw].source = address + 32; + context->sprite_draws[context->current_draw].x = x + 8; + context->sprite_draws[context->current_draw].hflip = (atts & 0x800) != 0; + context->sprite_draws[context->current_draw].palpriority = 0x80 | (atts >> 9 & 0x50); + } + context->current_draw++; + if (context->current_draw == 40) { + //no more rendering capacity + context->status &= ~VDP_STATUS_SPRITE_SCAN; + context->current_draw = 0; + } + } + } else { + //hit sprite list terminator + context->status &= ~VDP_STATUS_SPRITE_SCAN; + context->current_draw = 0; + } + } } else { - //TODO: Render sprites + sprite_draw *draw = context->sprite_draws + (context->current_draw >> 1); + if (draw->palpriority) { + context->status |= VDP_STATUS_VRAM; + uint16_t pixels = context->vram[draw->source + (context->current_draw & 1)]; + uint16_t x = draw->x - 16 + (context->hscroll & 7); + for (int i = 0; i < 4; i++, x++) + { + //TODO: handle horizontal flip + uint8_t pixel = (pixels >> ((3-i) * 4)) & 0xF; + if (pixel && x < 328 && ((draw->palpriority & 0x40) || !(context->drawbuffer[x] & 0x40))) { + context->drawbuffer[x] = pixel | draw->palpriority; + } + } + if (context->current_draw & 1) { + draw->palpriority = 0; + } else { + draw->x += 4; + } + } + context->current_draw++; } } //Draw to framebuffer