Bläddra i källkod

Background rendering completion; implement backdrop override

v2
Nathaniel Walizer 9 månader sedan
förälder
incheckning
1727e666d4
1 ändrade filer med 65 tillägg och 27 borttagningar
  1. +65
    -27
      src/ppu.c

+ 65
- 27
src/ppu.c Visa fil

@@ -61,7 +61,12 @@ void nes_ppu_render_line(nes_PPU* ppu, nes_PPU_Memory* mem) {
uint8_t* ptr = ppu->line_data;

if (!(mem->mask & ppu_Mask_Back)) {
memset(ptr, 0, nes_ppu_render_w);
// Emulate the happy part of the backdrop override quirk
int pal_idx = ((mem->addr & 0x3F00U) == 0x3F00U) ?
(mem->addr & 0x1FU) : 0;
// Don't use the rendering palette (masked transparency)
memset(ptr, mem->pal_bank[0x300 + pal_idx],
nes_ppu_render_w);
} else {
int back_bank = nes_PPU_Nametable_Bank_Index +
((mem->addr >> 10) & 3);
@@ -75,32 +80,33 @@ void nes_ppu_render_line(nes_PPU* ppu, nes_PPU_Memory* mem) {
const uint8_t* nametable = mem->bank[back_bank] + (y_coarse * 32) + x_coarse;
const uint8_t* attrs = mem->bank[back_bank] + 0x3C0U + ((y_coarse >> 2) << 3);

// Partial left column
ptr += 8 - mem->x;

// TODO: Omit if left column is masked?
{
const uint8_t* pal = mem->palette +
(((attrs[x_coarse >> 2] >>
( (x_coarse & 2) +
((y_coarse & 2) << 1))) & 3) << 2);
const int ch = *nametable;
const int bank = (ch >> 6) + bank_off;
const int addr_off = ((ch & 0x3F) << 4) + y_fine;
const uint8_t* data = mem->bank[bank] + addr_off;
const uint8_t pl0 = data[0];
const uint8_t pl1 = data[8];
const int pat0 = (pl0 & 0x55) | ((pl1 << 1) & 0xAA);
const int pat1 = ((pl0 >> 1) & 0x55) | (pl1 & 0xAA);
switch (mem->x) {
case 0: ptr[-8] = pal[(pat1 >> 6) & 3];
case 1: ptr[-7] = pal[(pat0 >> 6) & 3];
case 2: ptr[-6] = pal[(pat1 >> 4) & 3];
case 3: ptr[-5] = pal[(pat0 >> 4) & 3];
case 4: ptr[-4] = pal[(pat1 >> 2) & 3];
case 5: ptr[-3] = pal[(pat0 >> 2) & 3];
case 6: ptr[-2] = pal[(pat1 >> 0) & 3];
case 7: ptr[-1] = pal[(pat0 >> 0) & 3];
}
// Omit if left column is masked
if (mem->mask & ppu_Mask_Left_Back) {
const uint8_t* pal = mem->palette +
(((attrs[x_coarse >> 2] >>
( (x_coarse & 2) +
((y_coarse & 2) << 1))) & 3) << 2);
const int ch = *nametable;
const int bank = (ch >> 6) + bank_off;
const int addr_off = ((ch & 0x3F) << 4) + y_fine;
const uint8_t* data = mem->bank[bank] + addr_off;
const uint8_t pl0 = data[0];
const uint8_t pl1 = data[8];
const int pat0 = (pl0 & 0x55) | ((pl1 << 1) & 0xAA);
const int pat1 = ((pl0 >> 1) & 0x55) | (pl1 & 0xAA);
switch (mem->x) {
case 0: ptr[-8] = pal[(pat1 >> 6) & 3];
case 1: ptr[-7] = pal[(pat0 >> 6) & 3];
case 2: ptr[-6] = pal[(pat1 >> 4) & 3];
case 3: ptr[-5] = pal[(pat0 >> 4) & 3];
case 4: ptr[-4] = pal[(pat1 >> 2) & 3];
case 5: ptr[-3] = pal[(pat0 >> 2) & 3];
case 6: ptr[-2] = pal[(pat1 >> 0) & 3];
case 7: ptr[-1] = pal[(pat0 >> 0) & 3];
}
}

// TODO: Mapper ppu_bus
@@ -119,8 +125,6 @@ void nes_ppu_render_line(nes_PPU* ppu, nes_PPU_Memory* mem) {
const uint8_t* data = mem->bank[bank] + addr_off;
const uint8_t pl0 = data[0];
const uint8_t pl1 = data[8];
//const int pat0 = ((pl0 & 0x55) << 1) | ((pl1 & 0x55) << 2);
//const int pat1 = ((pl0 & 0xAA) << 0) | ((pl1 & 0xAA) << 1);
const int pat0 = (pl0 & 0x55) | ((pl1 << 1) & 0xAA);
const int pat1 = ((pl0 >> 1) & 0x55) | (pl1 & 0xAA);

@@ -135,12 +139,14 @@ void nes_ppu_render_line(nes_PPU* ppu, nes_PPU_Memory* mem) {
ptr += 8;
}

// Left Nametable
for (; x_coarse < 32; ++x_coarse) {
render_bg();
// TODO: Mapper ppu_bus
++nametable;
}

// Right Nametable
back_bank ^= 0b01;
nametable = mem->bank[back_bank] + (y_coarse * 32);
attrs = mem->bank[back_bank] + 0x3C0U + ((y_coarse >> 2) << 3);
@@ -150,6 +156,38 @@ void nes_ppu_render_line(nes_PPU* ppu, nes_PPU_Memory* mem) {
// TODO: Mapper ppu_bus
++nametable;
}

// Partial right column
{
const uint8_t* pal = mem->palette +
(((attrs[x_coarse >> 2] >>
( (x_coarse & 2) +
((y_coarse & 2) << 1))) & 3) << 2);
const int ch = *nametable;
const int bank = (ch >> 6) + bank_off;
const int addr_off = ((ch & 0x3F) << 4) + y_fine;
const uint8_t* data = mem->bank[bank] + addr_off;
const uint8_t pl0 = data[0];
const uint8_t pl1 = data[8];
const int pat0 = (pl0 & 0x55) | ((pl1 << 1) & 0xAA);
const int pat1 = ((pl0 >> 1) & 0x55) | (pl1 & 0xAA);
switch (mem->x) {
case 8: ptr[7] = pal[(pat0 >> 0) & 3];
case 7: ptr[6] = pal[(pat1 >> 0) & 3];
case 6: ptr[5] = pal[(pat0 >> 2) & 3];
case 5: ptr[4] = pal[(pat1 >> 2) & 3];
case 4: ptr[3] = pal[(pat0 >> 4) & 3];
case 3: ptr[2] = pal[(pat1 >> 4) & 3];
case 2: ptr[1] = pal[(pat0 >> 6) & 3];
case 1: ptr[0] = pal[(pat1 >> 6) & 3];
}
}
}

// TODO: Mapper ppu_bus

if (!(mem->mask & ppu_Mask_Left_Back)) {
memset(ppu->line_data, mem->palette[0], 8);
}

// TODO: Draw Sprites


Laddar…
Avbryt
Spara