fix(ppu): incremental improvements to accuracy of ppu fetcher

This commit is contained in:
Rekai Nyangadzayi Musuka 2021-10-20 05:21:49 -03:00
parent d9f1d661ae
commit 9b3ab73bb1
1 changed files with 31 additions and 24 deletions

View File

@ -83,6 +83,7 @@ impl Ppu {
if self.dot >= 80 { if self.dot >= 80 {
self.x_pos = 0; self.x_pos = 0;
self.scanline_start = true; self.scanline_start = true;
self.fetch.back.scanline_first = true;
self.to_discard = 0; self.to_discard = 0;
self.fifo.back.clear(); self.fifo.back.clear();
self.fifo.obj.clear(); self.fifo.obj.clear();
@ -318,6 +319,7 @@ impl Ppu {
if self.fetch.back.is_enabled() { if self.fetch.back.is_enabled() {
match self.fetch.back.state { match self.fetch.back.state {
SleepOne => self.fetch.back.next(TileNumber),
TileNumber => { TileNumber => {
let x_pos = self.fetch.x_pos; let x_pos = self.fetch.x_pos;
@ -328,35 +330,36 @@ impl Ppu {
let id = self.read_byte(addr); let id = self.read_byte(addr);
self.fetch.back.tile.with_id(id); self.fetch.back.tile.with_id(id);
// Move on to the Next state in 2 T-cycles self.fetch.back.next(TileLow);
self.fetch.back.next(SleepOne);
} }
SleepOne => self.fetch.back.next(TileLow), SleepTwo => self.fetch.back.next(TileLow),
TileLow => { TileLow => {
let addr = self.fetch.bg_byte_addr(&self.ctrl, &self.pos); let addr = self.fetch.bg_byte_addr(&self.ctrl, &self.pos);
let low = self.read_byte(addr); let low = self.read_byte(addr);
self.fetch.back.tile.with_low_byte(low); self.fetch.back.tile.with_low_byte(low);
self.fetch.back.next(SleepTwo); self.fetch.back.next(SleepThree);
} }
SleepTwo => self.fetch.back.next(TileHigh), SleepThree => self.fetch.back.next(TileHigh),
TileHigh => { TileHigh => {
let addr = self.fetch.bg_byte_addr(&self.ctrl, &self.pos); let addr = self.fetch.bg_byte_addr(&self.ctrl, &self.pos);
let high = self.read_byte(addr + 1); let high = self.read_byte(addr + 1);
self.fetch.back.tile.with_high_byte(high); self.fetch.back.tile.with_high_byte(high);
self.fetch.back.next(SleepThree); if self.fetch.back.scanline_first {
self.fetch.back.reset();
self.fetch.back.scanline_first = false;
} else {
self.fetch.back.next(ToFifoOne);
} }
SleepThree => self.fetch.back.next(ToFifoOne),
ToFifoOne => {
self.fetch.back.next(ToFifoTwo);
} }
ToFifoTwo => { ToFifoOne | ToFifoTwo => {
if let Ok(()) = self.fetch.send_to_fifo(&mut self.fifo) { if let Ok(()) = self.fetch.send_to_fifo(&mut self.fifo) {
self.fetch.x_pos += 1; self.fetch.x_pos += 1;
self.fetch.back.next(TileNumber); self.fetch.back.next(SleepOne);
self.fetch.back.tile = Default::default(); self.fetch.back.tile = Default::default();
} }
} }
@ -758,6 +761,7 @@ struct BackgroundFetcher {
wl_count: u8, wl_count: u8,
is_window_tile: bool, is_window_tile: bool,
enabled: bool, enabled: bool,
scanline_first: bool,
} }
impl BackgroundFetcher { impl BackgroundFetcher {
@ -788,7 +792,7 @@ impl Fetcher for BackgroundFetcher {
} }
fn reset(&mut self) { fn reset(&mut self) {
self.state = Default::default(); self.state = FetcherState::SleepOne;
self.tile = Default::default(); self.tile = Default::default();
} }
@ -804,34 +808,43 @@ impl Fetcher for BackgroundFetcher {
impl Default for BackgroundFetcher { impl Default for BackgroundFetcher {
fn default() -> Self { fn default() -> Self {
Self { Self {
state: Default::default(), state: FetcherState::SleepOne,
tile: Default::default(), tile: Default::default(),
is_window_tile: Default::default(), is_window_tile: Default::default(),
wl_count: Default::default(), wl_count: Default::default(),
enabled: true, enabled: true,
scanline_first: true,
} }
} }
} }
#[derive(Debug, Default)] #[derive(Debug)]
struct ObjectFetcher { struct ObjectFetcher {
state: FetcherState, state: FetcherState,
tile: TileBuilder, tile: TileBuilder,
} }
impl Default for ObjectFetcher {
fn default() -> Self {
Self {
state: FetcherState::TileNumber,
tile: Default::default(),
}
}
}
impl Fetcher for ObjectFetcher { impl Fetcher for ObjectFetcher {
fn next(&mut self, state: FetcherState) { fn next(&mut self, state: FetcherState) {
self.state = state self.state = state
} }
fn reset(&mut self) { fn reset(&mut self) {
self.state = Default::default(); self.state = FetcherState::TileNumber;
self.tile = Default::default(); self.tile = Default::default();
} }
fn hblank_reset(&mut self) { fn hblank_reset(&mut self) {
self.state = Default::default(); self.reset()
self.tile = Default::default();
} }
} }
@ -847,12 +860,6 @@ enum FetcherState {
ToFifoTwo, ToFifoTwo,
} }
impl Default for FetcherState {
fn default() -> Self {
Self::TileNumber
}
}
#[derive(Debug, Default)] #[derive(Debug, Default)]
struct BgPixelProperty { struct BgPixelProperty {
shade_id: u8, shade_id: u8,