chore(ppu): refactor FetcherState
This commit is contained in:
parent
552cfd4a18
commit
c5fa41b20d
79
src/ppu.rs
79
src/ppu.rs
|
@ -237,34 +237,33 @@ impl Ppu {
|
||||||
fn draw(&mut self) {
|
fn draw(&mut self) {
|
||||||
use FetcherState::*;
|
use FetcherState::*;
|
||||||
|
|
||||||
let mut iter = self.obj_buffer.iter_mut();
|
let mut obj_attr = &mut None;
|
||||||
let default = &mut None;
|
|
||||||
|
|
||||||
let obj_attr = loop {
|
for maybe_attr in &mut self.obj_buffer.inner {
|
||||||
match iter.next() {
|
match maybe_attr {
|
||||||
Some(attr_opt) => {
|
Some(attr) if self.ctrl.obj_enabled() => {
|
||||||
if let Some(attr) = attr_opt {
|
|
||||||
if attr.x <= (self.x_pos + 8) {
|
if attr.x <= (self.x_pos + 8) {
|
||||||
self.fetch.back.reset();
|
self.fetch.back.reset();
|
||||||
self.fetch.back.enabled = false;
|
self.fetch.back.enabled = false;
|
||||||
self.fifo.pause();
|
self.fifo.pause();
|
||||||
|
|
||||||
break attr_opt;
|
obj_attr = maybe_attr;
|
||||||
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
_ => break,
|
||||||
}
|
}
|
||||||
None => break default,
|
|
||||||
}
|
}
|
||||||
};
|
|
||||||
|
|
||||||
if let Some(attr) = obj_attr {
|
if let Some(attr) = obj_attr {
|
||||||
match self.fetch.obj.state {
|
match self.fetch.obj.state {
|
||||||
TileNumber => {
|
TileNumberA => self.fetch.obj.state = TileNumberB,
|
||||||
|
TileNumberB => {
|
||||||
self.fetch.obj.tile.with_id(attr.tile_index);
|
self.fetch.obj.tile.with_id(attr.tile_index);
|
||||||
self.fetch.obj.next(SleepOne);
|
self.fetch.obj.state = TileLowA;
|
||||||
}
|
}
|
||||||
SleepOne => self.fetch.obj.next(TileLow),
|
TileLowA => self.fetch.obj.state = TileLowB,
|
||||||
TileLow => {
|
TileLowB => {
|
||||||
let obj_size = self.ctrl.obj_size();
|
let obj_size = self.ctrl.obj_size();
|
||||||
|
|
||||||
let addr = PixelFetcher::get_obj_addr(attr, &self.pos, obj_size);
|
let addr = PixelFetcher::get_obj_addr(attr, &self.pos, obj_size);
|
||||||
|
@ -272,10 +271,10 @@ impl Ppu {
|
||||||
let byte = self.read_byte(addr);
|
let byte = self.read_byte(addr);
|
||||||
self.fetch.obj.tile.with_low(byte);
|
self.fetch.obj.tile.with_low(byte);
|
||||||
|
|
||||||
self.fetch.obj.next(SleepTwo);
|
self.fetch.obj.state = TileHighA;
|
||||||
}
|
}
|
||||||
SleepTwo => self.fetch.obj.next(TileHigh),
|
TileHighA => self.fetch.obj.state = TileHighB,
|
||||||
TileHigh => {
|
TileHighB => {
|
||||||
let obj_size = self.ctrl.obj_size();
|
let obj_size = self.ctrl.obj_size();
|
||||||
|
|
||||||
let addr = PixelFetcher::get_obj_addr(attr, &self.pos, obj_size);
|
let addr = PixelFetcher::get_obj_addr(attr, &self.pos, obj_size);
|
||||||
|
@ -283,10 +282,9 @@ impl Ppu {
|
||||||
let byte = self.read_byte(addr + 1);
|
let byte = self.read_byte(addr + 1);
|
||||||
self.fetch.obj.tile.with_high(byte);
|
self.fetch.obj.tile.with_high(byte);
|
||||||
|
|
||||||
self.fetch.obj.next(SleepThree);
|
self.fetch.obj.state = ToFifoA;
|
||||||
}
|
}
|
||||||
SleepThree => self.fetch.obj.next(ToFifoOne),
|
ToFifoA => {
|
||||||
ToFifoOne => {
|
|
||||||
// Load into Fifo
|
// Load into Fifo
|
||||||
let (high, low) = self
|
let (high, low) = self
|
||||||
.fetch
|
.fetch
|
||||||
|
@ -322,14 +320,12 @@ impl Ppu {
|
||||||
self.fifo.resume();
|
self.fifo.resume();
|
||||||
let _ = std::mem::take(obj_attr);
|
let _ = std::mem::take(obj_attr);
|
||||||
|
|
||||||
self.fetch.obj.next(ToFifoTwo);
|
self.fetch.obj.state = ToFifoB;
|
||||||
}
|
}
|
||||||
ToFifoTwo => self.fetch.obj.reset(),
|
ToFifoB => self.fetch.obj.reset(),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
use NewFetcherState::*;
|
|
||||||
|
|
||||||
if self.fetch.back.enabled {
|
if self.fetch.back.enabled {
|
||||||
match self.fetch.back.state {
|
match self.fetch.back.state {
|
||||||
TileNumberA => self.fetch.back.state = TileNumberB,
|
TileNumberA => self.fetch.back.state = TileNumberB,
|
||||||
|
@ -442,7 +438,7 @@ impl Ppu {
|
||||||
|
|
||||||
match self.fifo.back.pop_front() {
|
match self.fifo.back.pop_front() {
|
||||||
Some(bg_pixel) => match self.fifo.obj.pop_front() {
|
Some(bg_pixel) => match self.fifo.obj.pop_front() {
|
||||||
Some(obj_pixel) if self.ctrl.obj_enabled() => match obj_pixel.priority {
|
Some(obj_pixel) => match obj_pixel.priority {
|
||||||
Object | BackgroundAndWindow if obj_pixel.shade_id == 0 => {
|
Object | BackgroundAndWindow if obj_pixel.shade_id == 0 => {
|
||||||
Some(self.bg_pixel(bg_pixel.shade_id))
|
Some(self.bg_pixel(bg_pixel.shade_id))
|
||||||
}
|
}
|
||||||
|
@ -714,14 +710,13 @@ impl PixelFetcher {
|
||||||
}
|
}
|
||||||
|
|
||||||
trait Fetcher {
|
trait Fetcher {
|
||||||
fn next(&mut self, state: FetcherState);
|
|
||||||
fn reset(&mut self);
|
fn reset(&mut self);
|
||||||
fn hblank_reset(&mut self);
|
fn hblank_reset(&mut self);
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Debug)]
|
#[derive(Debug)]
|
||||||
struct BackgroundFetcher {
|
struct BackgroundFetcher {
|
||||||
state: NewFetcherState,
|
state: FetcherState,
|
||||||
tile: TileBuilder,
|
tile: TileBuilder,
|
||||||
wl_count: u8,
|
wl_count: u8,
|
||||||
draw_window: bool,
|
draw_window: bool,
|
||||||
|
@ -780,12 +775,8 @@ impl BackgroundFetcher {
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Fetcher for BackgroundFetcher {
|
impl Fetcher for BackgroundFetcher {
|
||||||
fn next(&mut self, state: FetcherState) {
|
|
||||||
todo!();
|
|
||||||
}
|
|
||||||
|
|
||||||
fn reset(&mut self) {
|
fn reset(&mut self) {
|
||||||
self.state = NewFetcherState::TileNumberA;
|
self.state = Default::default();
|
||||||
self.tile = Default::default();
|
self.tile = Default::default();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -801,7 +792,7 @@ impl Fetcher for BackgroundFetcher {
|
||||||
impl Default for BackgroundFetcher {
|
impl Default for BackgroundFetcher {
|
||||||
fn default() -> Self {
|
fn default() -> Self {
|
||||||
Self {
|
Self {
|
||||||
state: NewFetcherState::TileNumberA,
|
state: Default::default(),
|
||||||
tile: Default::default(),
|
tile: Default::default(),
|
||||||
draw_window: Default::default(),
|
draw_window: Default::default(),
|
||||||
wl_count: Default::default(),
|
wl_count: Default::default(),
|
||||||
|
@ -820,19 +811,15 @@ struct ObjectFetcher {
|
||||||
impl Default for ObjectFetcher {
|
impl Default for ObjectFetcher {
|
||||||
fn default() -> Self {
|
fn default() -> Self {
|
||||||
Self {
|
Self {
|
||||||
state: FetcherState::TileNumber,
|
state: Default::default(),
|
||||||
tile: Default::default(),
|
tile: Default::default(),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Fetcher for ObjectFetcher {
|
impl Fetcher for ObjectFetcher {
|
||||||
fn next(&mut self, state: FetcherState) {
|
|
||||||
self.state = state
|
|
||||||
}
|
|
||||||
|
|
||||||
fn reset(&mut self) {
|
fn reset(&mut self) {
|
||||||
self.state = FetcherState::TileNumber;
|
self.state = Default::default();
|
||||||
self.tile = Default::default();
|
self.tile = Default::default();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -842,7 +829,7 @@ impl Fetcher for ObjectFetcher {
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Debug, Clone, Copy)]
|
#[derive(Debug, Clone, Copy)]
|
||||||
enum NewFetcherState {
|
enum FetcherState {
|
||||||
TileNumberA,
|
TileNumberA,
|
||||||
TileNumberB,
|
TileNumberB,
|
||||||
TileLowA,
|
TileLowA,
|
||||||
|
@ -853,16 +840,10 @@ enum NewFetcherState {
|
||||||
ToFifoB,
|
ToFifoB,
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Debug, Clone, Copy)]
|
impl Default for FetcherState {
|
||||||
enum FetcherState {
|
fn default() -> Self {
|
||||||
TileNumber,
|
Self::TileNumberA
|
||||||
SleepOne,
|
}
|
||||||
TileLow,
|
|
||||||
SleepTwo,
|
|
||||||
TileHigh,
|
|
||||||
SleepThree,
|
|
||||||
ToFifoOne,
|
|
||||||
ToFifoTwo,
|
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Debug, Default)]
|
#[derive(Debug, Default)]
|
||||||
|
|
Loading…
Reference in New Issue