Explorar el Código

Fix sprite priority (visible in SMB3 powerups and Piranha Plants)

master
Nathaniel Walizer hace 11 meses
padre
commit
5d352fc5c5
Se han modificado 2 ficheros con 42 adiciones y 29 borrados
  1. +1
    -1
      Makefile
  2. +41
    -28
      src/sdl_render.c

+ 1
- 1
Makefile Ver fichero

@@ -4,7 +4,7 @@ PFLAGS = -g
#PFLAGS = -O3
#PFLAGS += -DDEBUG_MAPPER
#PFLAGS += -DDEBUG_RENDER
#PFLAGS += -DDEBUG_PPU -DDEBUG_VRAM
#PFLAGS += -DDEBUG_PPU -DDEBUG_VRAM -DDEBUG_OAM
#PFLAGS += -DE6502_DEBUG
CFLAGS = $(PFLAGS) -Wall -Werror -Wshadow -Wunused -I..
LDFLAGS = $(PFLAGS)


+ 41
- 28
src/sdl_render.c Ver fichero

@@ -195,13 +195,18 @@ static void sdl_render_done(nes_Renderer* rend) {

static inline void render_sprite_line(
const nes_ppu* ppu, int index, int y, const uint8_t* pal,
uint8_t* dst, int start, int end) {
uint8_t* dst, int start, int end, const uint8_t* back) {
uint8_t* sprite = chr_mem(ppu, index * 16U);
uint8_t lo = sprite[0U + y] << start;
uint8_t hi = sprite[8U + y] << start;
for (int x = start; x < end; ++x) {
int pal_idx = (((hi & 0x80) >> 6) | ((lo & 0x80) >> 7));
if (pal_idx) *dst = pal[pal_idx];
if (back && *back != 0xFFU) {
*dst = *back;
} else {
int pal_idx = (((hi & 0x80) >> 6) | ((lo & 0x80) >> 7));
if (pal_idx) *dst = pal[pal_idx];
}
if (back) ++back;
dst++;
hi <<= 1;
lo <<= 1;
@@ -210,13 +215,18 @@ static inline void render_sprite_line(

static inline void render_sprite_line_flip(
const nes_ppu* ppu, int index, int y, const uint8_t* pal,
uint8_t* dst, int start, int end) {
uint8_t* dst, int start, int end, const uint8_t* back) {
uint8_t* sprite = chr_mem(ppu, index * 16U);
uint8_t lo = sprite[0U + y] >> start;
uint8_t hi = sprite[8U + y] >> start;
for (int x = start; x < end; ++x) {
int pal_idx = (((hi & 1) << 1) | (lo & 1));
if (pal_idx) *dst = pal[pal_idx];
if (back && *back != 0xFFU) {
*dst = *back;
} else {
int pal_idx = (((hi & 1) << 1) | (lo & 1));
if (pal_idx) *dst = pal[pal_idx];
}
if (back) ++back;
dst++;
hi >>= 1;
lo >>= 1;
@@ -413,16 +423,12 @@ static void render_sprite(nes_ppu* ppu, int index,
*/

static void render_line_sprites(nes_ppu* ppu, uint8_t* dst_line,
int scanline, int background,
int scanline, const uint8_t* back,
const oam_sprite* sprites,
int n_sprites) {
for (int i_sprite = n_sprites - 1; i_sprite >= 0; --i_sprite) {
const oam_sprite* sprite = &sprites[i_sprite];

if ((sprite->attr & oam_Attr_Background) ^ background) {
continue;
}

int index = sprite->index;
int bank = (ppu->control & ppu_Control_Sprite_Bank) ?
0x100 : 0;
@@ -455,13 +461,19 @@ static void render_line_sprites(nes_ppu* ppu, uint8_t* dst_line,
start = 8 - sprite->x;
}
if (sprite->attr & oam_Attr_Flip_X) {
render_sprite_line_flip(ppu, index, y, pal,
dst_line + sprite->x + start,
start, end);
render_sprite_line_flip(
ppu, index, y, pal,
dst_line + sprite->x + start, start, end,
(sprite->attr & oam_Attr_Background) ?
(back + sprite->x + start) : NULL
);
} else {
render_sprite_line(ppu, index, y, pal,
dst_line + sprite->x + start,
start, end);
render_sprite_line(
ppu, index, y, pal,
dst_line + sprite->x + start, start, end,
(sprite->attr & oam_Attr_Background) ?
(back + sprite->x + start) : NULL
);
}
}
}
@@ -734,6 +746,16 @@ static int select_line_sprites(const nes_ppu* ppu, int scanline,
return n_sprites;
}

static void dump_line_sprites(const nes_ppu* ppu, int line,
const oam_sprite* sprites, int n) {
while (n-- > 0) {
PPU_LOG("PPU: Line %3d: Sprite $%02x @ %3d, %3d (%02x)\n",
line, sprites->index, sprites->x, sprites->y,
sprites->attr);
++sprites;
}
}

static void render_scanline(nes_ppu* ppu, int line,
sdl_render_data* data) {

@@ -769,27 +791,18 @@ static void render_scanline(nes_ppu* ppu, int line,
uint8_t* foreground = data->foreground->pixels;
uint8_t* background = data->background->pixels;


// We check for hits if EITHER layer is enabled.
render_bg_scanline(ppu, background);
if (ppu->hit_line <= 0) {
update_scanline_hit(ppu, background, line);
}


if (line >= 0) {
oam_sprite line_sprites[8] = {0};
int n_sprites = select_line_sprites(ppu, line,
line_sprites, 8);

if (ppu->mask & ppu_Mask_Sprite) {
memset(foreground, 0xFFU, nes_ppu_render_w);
render_line_sprites(ppu, foreground, line,
oam_Attr_Background,
line_sprites, n_sprites);
SDL_BlitSurface(data->foreground, &src_rect,
data->target, &dst_rect);
}
dump_line_sprites(ppu, line, line_sprites, n_sprites);

if (ppu->mask & ppu_Mask_Back) {
SDL_BlitSurface(data->background, &src_rect,
@@ -798,7 +811,7 @@ static void render_scanline(nes_ppu* ppu, int line,

if (ppu->mask & ppu_Mask_Sprite) {
memset(foreground, 0xFFU, nes_ppu_render_w);
render_line_sprites(ppu, foreground, line, 0,
render_line_sprites(ppu, foreground, line, background,
line_sprites, n_sprites);
SDL_BlitSurface(data->foreground, &src_rect,
data->target, &dst_rect);


Cargando…
Cancelar
Guardar