| @@ -224,11 +224,10 @@ static void render_background_line(const nes_ppu* ppu, int line, | |||||
| ); | ); | ||||
| } | } | ||||
| static int render_sprite(nes_ppu* ppu, int index, | |||||
| static void render_sprite(nes_ppu* ppu, int index, | |||||
| const uint8_t* pal, Render_Mode mode, | const uint8_t* pal, Render_Mode mode, | ||||
| void* loc, int pitch, | void* loc, int pitch, | ||||
| const void* back_loc, int back_pitch) { | const void* back_loc, int back_pitch) { | ||||
| int hit_pos = -1; | |||||
| uint8_t* sprite = &ppu->chr_mem[index * 16U]; | uint8_t* sprite = &ppu->chr_mem[index * 16U]; | ||||
| uint8_t* dst_line = (uint8_t*)loc; | uint8_t* dst_line = (uint8_t*)loc; | ||||
| const uint8_t* back_line = (uint8_t*)back_loc; | const uint8_t* back_line = (uint8_t*)back_loc; | ||||
| @@ -254,15 +253,6 @@ static int render_sprite(nes_ppu* ppu, int index, | |||||
| int pal_idx = ( ((hi & 0x80) >> 6) | | int pal_idx = ( ((hi & 0x80) >> 6) | | ||||
| ((lo & 0x80) >> 7)); | ((lo & 0x80) >> 7)); | ||||
| int nes_pal_idx = (pal_idx ? pal[pal_idx] : 0xFFU); | int nes_pal_idx = (pal_idx ? pal[pal_idx] : 0xFFU); | ||||
| /* | |||||
| if ( hit_pos < 0 && | |||||
| (ppu->mask & ppu_Mask_Back) && | |||||
| (mode & Render_Mode_Collide) && | |||||
| nes_pal_idx != 0xFFU && | |||||
| *back != 0xFFU ) { | |||||
| hit_pos = (8 - x) + (8 * (8 - y)); | |||||
| } | |||||
| */ | |||||
| if ((mode & Render_Mode_Behind) && *back != 0xFFU) { | if ((mode & Render_Mode_Behind) && *back != 0xFFU) { | ||||
| nes_pal_idx = 0xFFU; | nes_pal_idx = 0xFFU; | ||||
| } | } | ||||
| @@ -276,7 +266,6 @@ static int render_sprite(nes_ppu* ppu, int index, | |||||
| back_line += back_pitch; | back_line += back_pitch; | ||||
| ++sprite; | ++sprite; | ||||
| } | } | ||||
| return hit_pos; | |||||
| } | } | ||||
| typedef struct { | typedef struct { | ||||
| @@ -382,13 +371,8 @@ static void render_sprites(nes_ppu* ppu, | |||||
| if (sprite->attr & oam_Attr_Flip_Y) { | if (sprite->attr & oam_Attr_Flip_Y) { | ||||
| mode |= Render_Mode_Flip_Y; | mode |= Render_Mode_Flip_Y; | ||||
| } | } | ||||
| int hit_pos = render_sprite(ppu, index, pal, mode, | |||||
| dst, pitch, | |||||
| dst_back, back_pitch); | |||||
| if (hit_pos >= 0) { | |||||
| ppu->hit_line = y + (hit_pos / 8); | |||||
| ppu->hit_dot = sprite->x + (hit_pos % 8); | |||||
| } | |||||
| render_sprite(ppu, index, pal, mode, dst, pitch, | |||||
| dst_back, back_pitch); | |||||
| SDL_Rect target_rect = { | SDL_Rect target_rect = { | ||||
| .x = sprite->x, | .x = sprite->x, | ||||
| @@ -405,27 +389,29 @@ static void update_sprite_hit(nes_ppu* ppu, | |||||
| const void* back_line, | const void* back_line, | ||||
| int back_pitch) { | int back_pitch) { | ||||
| const oam_sprite* sprite = (oam_sprite*)ppu->oam; | const oam_sprite* sprite = (oam_sprite*)ppu->oam; | ||||
| int line = (ppu->scanline - nes_ppu_prerender) / 8U; | |||||
| int block_line = (ppu->scanline - nes_ppu_prerender) / 8U; | |||||
| int x_fine = ppu->scroll_x % 8; | int x_fine = ppu->scroll_x % 8; | ||||
| int index = sprite->index; | int index = sprite->index; | ||||
| if (ppu->control & ppu_Control_Sprite_Bank) { | if (ppu->control & ppu_Control_Sprite_Bank) { | ||||
| index += 0x100U; | index += 0x100U; | ||||
| } | } | ||||
| const uint8_t* chr = &ppu->chr_mem[index * 16U]; | const uint8_t* chr = &ppu->chr_mem[index * 16U]; | ||||
| int render_line = ppu->scanline - nes_ppu_prerender; | |||||
| if ( ppu->hit_dot == 0 && | |||||
| (sprite->y + 1) + 7 >= render_line && | |||||
| (sprite->y + 1) - 7 <= render_line) { | |||||
| int render_line = block_line * 8U; | |||||
| int start_y = (sprite->y + 1) - render_line; | |||||
| int end_y = start_y + 8; | |||||
| if (start_y < 8 && end_y > 0) { | |||||
| if (start_y < 0) start_y = 0; | |||||
| if (end_y > 8) end_y = 8; | |||||
| int hit = -1; | int hit = -1; | ||||
| const uint8_t* back = (uint8_t*)back_line + x_fine; | const uint8_t* back = (uint8_t*)back_line + x_fine; | ||||
| back += 8U * line * back_pitch; | |||||
| for (int y = 0; y < 8; ++y) { | |||||
| back += (render_line + start_y) * back_pitch; | |||||
| for (int y = start_y; y < end_y; ++y) { | |||||
| hit = eval_sprite_line( | hit = eval_sprite_line( | ||||
| ppu, ppu->scanline + y, | |||||
| ppu, render_line + y, | |||||
| sprite, chr, back | sprite, chr, back | ||||
| ); | ); | ||||
| if (hit >= 0) { | if (hit >= 0) { | ||||
| ppu->hit_line = ppu->scanline + y; | |||||
| ppu->hit_line = y + render_line; | |||||
| ppu->hit_dot = hit; | ppu->hit_dot = hit; | ||||
| break; | break; | ||||
| } | } | ||||