2024-08-20 16:21:52 -05:00
|
|
|
class Render {
|
|
|
|
static func render(_ ppu: NesPPU, frame: Frame) {
|
|
|
|
let bank = ppu.ctrl.backgroundPatternAddr()
|
|
|
|
|
2024-08-21 09:13:15 -05:00
|
|
|
for i in 0..<0x03c0 { // FIXME: For now, just use first nametable
|
2024-08-20 16:21:52 -05:00
|
|
|
let tileAddr = UInt16(ppu.vram[i])
|
|
|
|
//print(ppu.vram)
|
2024-08-21 09:13:15 -05:00
|
|
|
let tileLoc = (col: i % 32, row: i / 32)
|
2024-08-20 16:21:52 -05:00
|
|
|
let tile = ppu.chrRom[(bank + Int(tileAddr) * 16)...(bank + Int(tileAddr) * 16 + 15)]
|
2024-08-21 09:13:15 -05:00
|
|
|
let palette = getBgPallete(ppu, tileLoc: tileLoc)
|
2024-08-20 16:21:52 -05:00
|
|
|
|
|
|
|
for y in 0...7 {
|
|
|
|
var upper = tile[tile.startIndex + y]
|
|
|
|
var lower = tile[tile.startIndex + y + 8]
|
|
|
|
|
|
|
|
for x in (0...7).reversed() {
|
2024-08-21 09:13:15 -05:00
|
|
|
let value = (1 & lower) << 1 | (1 & upper)
|
2024-08-20 16:21:52 -05:00
|
|
|
upper = upper >> 1
|
|
|
|
lower = lower >> 1
|
|
|
|
let rgb = switch value {
|
|
|
|
case 0:
|
2024-08-21 09:13:15 -05:00
|
|
|
NESColor.SYSTEM_PALLETE[Int(ppu.paletteTable[0])]
|
2024-08-20 16:21:52 -05:00
|
|
|
case 1:
|
2024-08-21 09:13:15 -05:00
|
|
|
NESColor.SYSTEM_PALLETE[Int(palette[1])]
|
2024-08-20 16:21:52 -05:00
|
|
|
case 2:
|
2024-08-21 09:13:15 -05:00
|
|
|
NESColor.SYSTEM_PALLETE[Int(palette[2])]
|
2024-08-20 16:21:52 -05:00
|
|
|
case 3:
|
2024-08-21 09:13:15 -05:00
|
|
|
NESColor.SYSTEM_PALLETE[Int(palette[3])]
|
2024-08-20 16:21:52 -05:00
|
|
|
default:
|
|
|
|
fatalError("Invalid Pallete Color type")
|
|
|
|
}
|
2024-08-21 09:13:15 -05:00
|
|
|
frame.setPixel((tileLoc.col * 8 + x, tileLoc.row * 8 + y), rgb)
|
2024-08-20 16:21:52 -05:00
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
2024-08-21 09:13:15 -05:00
|
|
|
|
|
|
|
static func getBgPallete(_ ppu: NesPPU, tileLoc: (col: Int, row: Int)) -> [UInt8] {
|
|
|
|
let attrTableIndex = tileLoc.row / 4 * 8 + tileLoc.col / 4
|
|
|
|
let attrByte = ppu.vram[0x3c0 + attrTableIndex] // FIXME: still using hardcoded first nametable
|
|
|
|
|
|
|
|
let palleteIndex = switch (tileLoc.col % 4 / 2, tileLoc.row % 4 / 2) {
|
|
|
|
case (0,0):
|
|
|
|
attrByte & 0b11
|
|
|
|
case (1,0):
|
|
|
|
(attrByte >> 2) & 0b11
|
|
|
|
case (0,1):
|
|
|
|
(attrByte >> 4) & 0b11
|
|
|
|
case (1,1):
|
|
|
|
(attrByte >> 6) & 0b11
|
|
|
|
default:
|
|
|
|
fatalError("Invalid titleLoc. This should never happen!")
|
|
|
|
}
|
|
|
|
|
|
|
|
let palleteStartIndex = 1 + Int(palleteIndex) * 4
|
|
|
|
return [ppu.paletteTable[0], ppu.paletteTable[palleteStartIndex], ppu.paletteTable[palleteStartIndex + 1], ppu.paletteTable[palleteStartIndex + 2]]
|
|
|
|
}
|
2024-08-20 16:21:52 -05:00
|
|
|
}
|