浏览代码

Add mirroring support to sprite rendering

master
父节点
当前提交
3b3f8bd6f6
共有 1 个文件被更改,包括 38 次插入10 次删除
  1. +38
    -10
      src/sdl_render.c

+ 38
- 10
src/sdl_render.c 查看文件

@@ -150,10 +150,12 @@ static void sdl_render_done(nes_Renderer* rend) {
}

typedef enum {
Render_Mode_Sprite = 0b000,
Render_Mode_Background = 0b001,
Render_Mode_Behind = 0b010,
Render_Mode_Collide = 0b100,
Render_Mode_Sprite = 0b00000,
Render_Mode_Background = 0b00001,
Render_Mode_Behind = 0b00010,
Render_Mode_Collide = 0b00100,
Render_Mode_Flip_X = 0b01000,
Render_Mode_Flip_Y = 0b10000,
} Render_Mode;


@@ -165,13 +167,23 @@ static int render_sprite(nes_ppu* ppu, int index,
uint8_t* sprite = &ppu->chr_mem[index * 16U];
uint8_t* dst_line = (uint8_t*)loc;
const uint8_t* back_line = (uint8_t*)back_loc;
if (mode & Render_Mode_Flip_X) {
dst_line += 7;
back_line += 7;
}
if (mode & Render_Mode_Flip_Y) {
dst_line += (7 * pitch);
back_line += (7 * back_pitch);
}

for (int y = 8; y > 0; --y) {
uint8_t lo = sprite[0U];
uint8_t hi = sprite[8U];
uint8_t* dst = dst_line;
const uint8_t* back = back_line;
for (int x = 8; x > 0; --x) {
int pal_idx = ((hi & 0x80) >> 6) | ((lo & 0x80) >> 7);
int pal_idx = ( ((hi & 0x80) >> 6) |
((lo & 0x80) >> 7));
int nes_pal_idx = (pal_idx ? pal[pal_idx] : 0xFFU);
if ( hit_pos < 0 &&
(ppu->mask & ppu_Mask_Back) &&
@@ -183,13 +195,24 @@ static int render_sprite(nes_ppu* ppu, int index,
if ((mode & Render_Mode_Behind) && *back != 0xFFU) {
nes_pal_idx = 0xFFU;
}
*dst++ = nes_pal_idx;
++back;
*dst = nes_pal_idx;
if (mode & Render_Mode_Flip_X) {
dst--;
back--;
} else {
dst++;
back++;
}
hi <<= 1;
lo <<= 1;
}
dst_line += pitch;
back_line += back_pitch;
if (mode & Render_Mode_Flip_Y) {
dst_line -= pitch;
back_line -= back_pitch;
} else {
dst_line += pitch;
back_line += back_pitch;
}
++sprite;
}
return hit_pos;
@@ -273,13 +296,18 @@ static void render_sprites(nes_ppu* ppu,
const uint8_t* dst_back = back_offset + back_origin;
// TODO: Support 8x16 sprites
int index = bank + sprite->index;
// TODO: Support mirroring
int pal_idx = (sprite->attr & oam_Attr_Pal_Mask);
const uint8_t* pal = &ppu->palette[16 + (pal_idx * 4)];
Render_Mode mode = (sprite->attr & oam_Attr_Background) ?
Render_Mode_Behind :
Render_Mode_Sprite;
if (i_sprite == 0) mode |= Render_Mode_Collide;
if (sprite->attr & oam_Attr_Flip_X) {
mode |= Render_Mode_Flip_X;
}
if (sprite->attr & oam_Attr_Flip_Y) {
mode |= Render_Mode_Flip_Y;
}
int hit_pos = render_sprite(ppu, index, pal, mode,
dst, pitch,
dst_back, back_pitch);


正在加载...
取消
保存