fixed another 8x16 sprite bug, think all sprites in zelda display correctly now.

This commit is contained in:
Theron Spiegl 2020-01-12 12:56:46 -06:00
parent e6e36d9391
commit 4cccffadc3
2 changed files with 8 additions and 15 deletions

View File

@ -123,7 +123,6 @@ fn main() -> Result<(), String> {
/*
TODO:
- fix zelda hearts
- common mappers
- untangle CPU and PPU
- DMC audio channel, high- and low-pass filters, refactor envelope, fix static

View File

@ -203,20 +203,22 @@ impl super::Ppu {
let sprite_tile_index = self.secondary_oam[(4*i)+1] as usize; // byte 1 of sprite, sprite's location within pattern table
let sprite_attributes = self.secondary_oam[(4*i)+2]; // byte 2 of sprite, sprite's palette, priority, and flip attributes
let sprite_x_position = self.secondary_oam[(4*i)+3]; // byte 3 of sprite, sprite's horizontal position on screen
let flipped_vertically = sprite_attributes & (1<<7) != 0;
let flipped_horizontally = sprite_attributes & (1<<6) != 0;
// For 8x8 sprites, this is the tile number of this sprite within the pattern table selected in bit 3 of PPUCTRL ($2000).
if self.sprite_size == 8 {
address = self.sprite_pattern_table_base;
address += sprite_tile_index*16;
address += if sprite_attributes & (1<<7) == 0 {
self.scanline - sprite_y_position
address += if !flipped_vertically {
self.scanline - sprite_y_position // row-within-sprite offset is difference between current scanline and top of sprite
} else {
self.sprite_size as usize - 1 - (self.scanline - sprite_y_position)
};
// For 8x16 sprites, the PPU ignores the pattern table selection and selects a pattern table from bit 0 of this number.
} else {
address = if sprite_tile_index & 1 == 0 { 0x0 } else { 0x1000 };
address += (sprite_tile_index*16) & (0xFFFF - 1); // turn off bottom bit
let fine_y = if sprite_attributes & (1<<7) == 0 {
address += (sprite_tile_index & 0xFFFF-1) << 4; // turn off bottom bit BEFORE shifting
let fine_y = if !flipped_vertically {
self.scanline - sprite_y_position
} else {
self.sprite_size as usize - 1 - (self.scanline - sprite_y_position)
@ -228,24 +230,16 @@ impl super::Ppu {
address += fine_y;
}
}
// let fine_y: usize;
// Handle vertical and horizontal flips, then write to shift registers
// if sprite_attributes & (1<<7) == 0 { // if vertical flip bit not set
// fine_y = self.scanline - sprite_y_position; // row-within-sprite offset is difference between current scanline and top of sprite
// } else { // if flipped vertically
// fine_y = self.sprite_size as usize - 1 - (self.scanline - sprite_y_position);
// }
// address += fine_y;
let low_pattern_table_byte = self.read(address);
let high_pattern_table_byte = self.read(address + 8);
let mut shift_reg_vals = (0, 0);
for j in 0..8 {
let current_bits = (low_pattern_table_byte & (1 << j), high_pattern_table_byte & (1 << j));
if sprite_attributes & (1<<6) == 0 { // if horizontal flip bit not set
if !flipped_horizontally {
// just copy each bit in same order
shift_reg_vals.0 |= current_bits.0;
shift_reg_vals.1 |= current_bits.1;
} else { // if flipped horizontally
} else {
// get bit of pattern table byte, left shift it by 7 - bit position
shift_reg_vals.0 |= ((current_bits.0 != 0) as u8) << (7 - j);
shift_reg_vals.1 |= ((current_bits.1 != 0) as u8) << (7 - j);