69 lines
2.0 KiB
C++
69 lines
2.0 KiB
C++
auto PPU::Background::clip(int n) -> int {
|
|
//13-bit sign extend: --s---nnnnnnnnnn -> ssssssnnnnnnnnnn
|
|
return n & 0x2000 ? (n | ~1023) : (n & 1023);
|
|
}
|
|
|
|
auto PPU::Background::runMode7() -> void {
|
|
int a = (int16)ppu.io.m7a;
|
|
int b = (int16)ppu.io.m7b;
|
|
int c = (int16)ppu.io.m7c;
|
|
int d = (int16)ppu.io.m7d;
|
|
|
|
int hcenter = (int13)ppu.io.m7x;
|
|
int vcenter = (int13)ppu.io.m7y;
|
|
int hoffset = (int13)ppu.io.hoffsetMode7;
|
|
int voffset = (int13)ppu.io.voffsetMode7;
|
|
|
|
uint x = mosaic.hoffset;
|
|
uint y = ppu.vcounter();
|
|
if(ppu.bg1.mosaic.enable) y -= ppu.mosaic.voffset(); //BG2 vertical mosaic uses BG1 mosaic enable
|
|
|
|
if(!mosaic.enable) {
|
|
mosaic.hoffset += 1;
|
|
} else if(--mosaic.hcounter == 0) {
|
|
mosaic.hcounter = ppu.mosaic.size;
|
|
mosaic.hoffset += ppu.mosaic.size;
|
|
}
|
|
|
|
if(ppu.io.hflipMode7) x = 255 - x;
|
|
if(ppu.io.vflipMode7) y = 255 - y;
|
|
|
|
int originX = (a * clip(hoffset - hcenter) & ~63) + (b * clip(voffset - vcenter) & ~63) + (b * y & ~63) + (hcenter << 8);
|
|
int originY = (c * clip(hoffset - hcenter) & ~63) + (d * clip(voffset - vcenter) & ~63) + (d * y & ~63) + (vcenter << 8);
|
|
|
|
int pixelX = originX + a * x >> 8;
|
|
int pixelY = originY + c * x >> 8;
|
|
uint16 paletteAddress = (uint3)pixelY << 3 | (uint3)pixelX;
|
|
|
|
uint7 tileX = pixelX >> 3;
|
|
uint7 tileY = pixelY >> 3;
|
|
uint16 tileAddress = tileY << 7 | tileX;
|
|
|
|
bool outOfBounds = (pixelX | pixelY) & ~1023;
|
|
|
|
uint8 tile = ppu.io.repeatMode7 == 3 && outOfBounds ? 0 : ppu.vram[tileAddress] >> 0;
|
|
uint8 palette = ppu.io.repeatMode7 == 2 && outOfBounds ? 0 : ppu.vram[tile << 6 | paletteAddress] >> 8;
|
|
|
|
uint priority;
|
|
if(id == ID::BG1) {
|
|
priority = io.priority[0];
|
|
} else if(id == ID::BG2) {
|
|
priority = io.priority[palette >> 7];
|
|
palette &= 0x7f;
|
|
}
|
|
|
|
if(palette == 0) return;
|
|
|
|
if(io.aboveEnable) {
|
|
output.above.priority = priority;
|
|
output.above.palette = palette;
|
|
output.above.paletteGroup = 0;
|
|
}
|
|
|
|
if(io.belowEnable) {
|
|
output.below.priority = priority;
|
|
output.below.palette = palette;
|
|
output.below.paletteGroup = 0;
|
|
}
|
|
}
|