mirror of https://github.com/bsnes-emu/bsnes.git
69 lines
1.7 KiB
C++
69 lines
1.7 KiB
C++
auto VDP::Sprite::scanline() -> void {
|
|
state.x = 0;
|
|
state.y = vdp.io.vcounter;
|
|
objects.reset();
|
|
|
|
uint limit = vdp.io.spriteTile ? 15 : 7;
|
|
uint14 attributeAddress = vdp.io.spriteAttributeTableAddress << 8;
|
|
for(uint index : range(64)) {
|
|
uint8 y = vdp.vram[attributeAddress + index];
|
|
uint8 x = vdp.vram[attributeAddress + 0x80 + (index << 1)];
|
|
uint8 pattern = vdp.vram[attributeAddress + 0x81 + (index << 1)];
|
|
if(vdp.vlines() == 192 && y == 0xd0) break;
|
|
|
|
if(vdp.io.spriteShift) x -= 8;
|
|
y += 1;
|
|
if(state.y < y) continue;
|
|
if(state.y > y + limit) continue;
|
|
|
|
if(limit == 15) pattern.bit(0) = 0;
|
|
|
|
objects.append({x, y, pattern});
|
|
if(objects.size() == 8) {
|
|
vdp.io.spriteOverflow = 1;
|
|
break;
|
|
}
|
|
}
|
|
}
|
|
|
|
auto VDP::Sprite::run() -> void {
|
|
output.color = 0;
|
|
|
|
if(state.y >= vdp.vlines()) return;
|
|
|
|
uint limit = vdp.io.spriteTile ? 15 : 7;
|
|
for(auto& o : objects) {
|
|
if(state.x < o.x) continue;
|
|
if(state.x > o.x + 7) continue;
|
|
|
|
uint x = state.x - o.x;
|
|
uint y = state.y - o.y;
|
|
|
|
uint14 address = vdp.io.spritePatternTableAddress << 13;
|
|
address += o.pattern << 5;
|
|
address += (y & limit) << 2;
|
|
|
|
auto index = 7 - (x & 7);
|
|
uint4 color;
|
|
color.bit(0) = vdp.vram[address + 0].bit(index);
|
|
color.bit(1) = vdp.vram[address + 1].bit(index);
|
|
color.bit(2) = vdp.vram[address + 2].bit(index);
|
|
color.bit(3) = vdp.vram[address + 3].bit(index);
|
|
if(color == 0) continue;
|
|
|
|
if(output.color) {
|
|
vdp.io.spriteCollision = true;
|
|
break;
|
|
}
|
|
|
|
output.color = color;
|
|
}
|
|
|
|
state.x++;
|
|
}
|
|
|
|
auto VDP::Sprite::power() -> void {
|
|
memory::fill(&state, sizeof(State));
|
|
memory::fill(&output, sizeof(Output));
|
|
}
|