chore(ppu): refactor behaviour w.r.t window enabling
This commit is contained in:
parent
da83032e24
commit
d9f1d661ae
122
src/ppu.rs
122
src/ppu.rs
|
@ -81,6 +81,12 @@ impl Ppu {
|
||||||
PpuMode::OamScan => {
|
PpuMode::OamScan => {
|
||||||
// Cycles 1 -> 80
|
// Cycles 1 -> 80
|
||||||
if self.dot >= 80 {
|
if self.dot >= 80 {
|
||||||
|
self.x_pos = 0;
|
||||||
|
self.scanline_start = true;
|
||||||
|
self.to_discard = 0;
|
||||||
|
self.fifo.back.clear();
|
||||||
|
self.fifo.obj.clear();
|
||||||
|
|
||||||
self.stat.set_mode(PpuMode::Drawing);
|
self.stat.set_mode(PpuMode::Drawing);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -105,21 +111,14 @@ impl Ppu {
|
||||||
|
|
||||||
// Increment Window line counter if scanline had any window pixels on it
|
// Increment Window line counter if scanline had any window pixels on it
|
||||||
// only increment once per scanline though
|
// only increment once per scanline though
|
||||||
if self.win_stat.should_draw() {
|
if self.win_stat.enabled {
|
||||||
self.fetch.back.window_line.increment();
|
self.fetch.back.wl_count += 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
self.x_pos = 0;
|
|
||||||
self.scanline_start = true;
|
|
||||||
self.to_discard = 0;
|
|
||||||
|
|
||||||
self.fetch.hblank_reset();
|
self.fetch.hblank_reset();
|
||||||
self.win_stat.hblank_reset();
|
self.win_stat.enabled = false;
|
||||||
|
|
||||||
self.obj_buffer.clear();
|
self.obj_buffer.clear();
|
||||||
|
|
||||||
self.fifo.back.clear();
|
|
||||||
self.fifo.obj.clear();
|
|
||||||
|
|
||||||
self.stat.set_mode(PpuMode::HBlank);
|
self.stat.set_mode(PpuMode::HBlank);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -144,9 +143,10 @@ impl Ppu {
|
||||||
self.int.set_vblank(true);
|
self.int.set_vblank(true);
|
||||||
|
|
||||||
// Reset Window Line Counter in Fetcher
|
// Reset Window Line Counter in Fetcher
|
||||||
self.fetch.vblank_reset();
|
self.fetch.back.wl_count = 0;
|
||||||
|
|
||||||
// Reset WY=LY coincidence flag
|
// Reset WY=LY coincidence flag
|
||||||
self.win_stat.vblank_reset();
|
self.win_stat.coincidence = false;
|
||||||
|
|
||||||
if self.stat.vblank_int() {
|
if self.stat.vblank_int() {
|
||||||
// Enable Vblank LCDStat Interrupt
|
// Enable Vblank LCDStat Interrupt
|
||||||
|
@ -203,9 +203,8 @@ impl Ppu {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
if !self.win_stat.coincidence() && self.scan_dot == 0 {
|
if !self.win_stat.coincidence && self.scan_dot == 0 {
|
||||||
self.win_stat
|
self.win_stat.coincidence = self.pos.line_y == self.pos.window_y;
|
||||||
.set_coincidence(self.pos.line_y == self.pos.window_y);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
let obj_height = self.ctrl.obj_size().size();
|
let obj_height = self.ctrl.obj_size().size();
|
||||||
|
@ -317,25 +316,12 @@ impl Ppu {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if self.ctrl.window_enabled()
|
|
||||||
&& !self.win_stat.should_draw()
|
|
||||||
&& self.win_stat.coincidence()
|
|
||||||
&& self.x_pos as i16 >= self.pos.window_x as i16 - 7
|
|
||||||
{
|
|
||||||
self.win_stat.set_should_draw(true);
|
|
||||||
self.fetch.back.reset();
|
|
||||||
self.fetch.x_pos = 0;
|
|
||||||
self.fifo.back.clear();
|
|
||||||
}
|
|
||||||
|
|
||||||
if self.fetch.back.is_enabled() {
|
if self.fetch.back.is_enabled() {
|
||||||
match self.fetch.back.state {
|
match self.fetch.back.state {
|
||||||
TileNumber => {
|
TileNumber => {
|
||||||
let x_pos = self.fetch.x_pos;
|
let x_pos = self.fetch.x_pos;
|
||||||
|
|
||||||
self.fetch
|
self.fetch.back.should_render_window(self.win_stat.enabled);
|
||||||
.back
|
|
||||||
.should_render_window(self.win_stat.should_draw());
|
|
||||||
|
|
||||||
let addr = self.fetch.bg_tile_num_addr(&self.ctrl, &self.pos, x_pos);
|
let addr = self.fetch.bg_tile_num_addr(&self.ctrl, &self.pos, x_pos);
|
||||||
|
|
||||||
|
@ -383,7 +369,7 @@ impl Ppu {
|
||||||
self.scanline_start = false;
|
self.scanline_start = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
if self.to_discard > 0 && !self.fifo.back.is_empty() {
|
if !self.win_stat.enabled && self.to_discard > 0 && !self.fifo.back.is_empty() {
|
||||||
let _ = self.fifo.back.pop_front();
|
let _ = self.fifo.back.pop_front();
|
||||||
self.to_discard -= 1;
|
self.to_discard -= 1;
|
||||||
|
|
||||||
|
@ -401,6 +387,17 @@ impl Ppu {
|
||||||
|
|
||||||
self.x_pos += 1;
|
self.x_pos += 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if self.ctrl.window_enabled()
|
||||||
|
&& !self.win_stat.enabled
|
||||||
|
&& self.win_stat.coincidence
|
||||||
|
&& self.x_pos as i16 >= self.pos.window_x as i16 - 7
|
||||||
|
{
|
||||||
|
self.win_stat.enabled = true;
|
||||||
|
self.fetch.back.reset();
|
||||||
|
self.fetch.x_pos = 0;
|
||||||
|
self.fifo.back.clear();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -653,10 +650,6 @@ impl PixelFetcher {
|
||||||
self.x_pos = 0;
|
self.x_pos = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
fn vblank_reset(&mut self) {
|
|
||||||
self.back.vblank_reset();
|
|
||||||
}
|
|
||||||
|
|
||||||
fn bg_tile_num_addr(&self, control: &LCDControl, pos: &ScreenPosition, x_pos: u8) -> u16 {
|
fn bg_tile_num_addr(&self, control: &LCDControl, pos: &ScreenPosition, x_pos: u8) -> u16 {
|
||||||
let line_y = pos.line_y;
|
let line_y = pos.line_y;
|
||||||
let scroll_y = pos.scroll_y;
|
let scroll_y = pos.scroll_y;
|
||||||
|
@ -676,7 +669,7 @@ impl PixelFetcher {
|
||||||
|
|
||||||
let scx_offset = if is_window { 0 } else { scroll_x / 8 };
|
let scx_offset = if is_window { 0 } else { scroll_x / 8 };
|
||||||
let y_offset = if is_window {
|
let y_offset = if is_window {
|
||||||
self.back.window_line.count() as u16 / 8
|
self.back.wl_count as u16 / 8
|
||||||
} else {
|
} else {
|
||||||
((line_y as u16 + scroll_y as u16) & 0xFF) / 8
|
((line_y as u16 + scroll_y as u16) & 0xFF) / 8
|
||||||
};
|
};
|
||||||
|
@ -700,7 +693,7 @@ impl PixelFetcher {
|
||||||
};
|
};
|
||||||
|
|
||||||
let offset = if is_window {
|
let offset = if is_window {
|
||||||
self.back.window_line.count() as u16 % 8
|
self.back.wl_count as u16 % 8
|
||||||
} else {
|
} else {
|
||||||
(line_y as u16 + scroll_y as u16) % 8
|
(line_y as u16 + scroll_y as u16) % 8
|
||||||
};
|
};
|
||||||
|
@ -762,7 +755,7 @@ trait Fetcher {
|
||||||
struct BackgroundFetcher {
|
struct BackgroundFetcher {
|
||||||
state: FetcherState,
|
state: FetcherState,
|
||||||
tile: TileBuilder,
|
tile: TileBuilder,
|
||||||
window_line: WindowLineCounter,
|
wl_count: u8,
|
||||||
is_window_tile: bool,
|
is_window_tile: bool,
|
||||||
enabled: bool,
|
enabled: bool,
|
||||||
}
|
}
|
||||||
|
@ -787,10 +780,6 @@ impl BackgroundFetcher {
|
||||||
fn is_enabled(&self) -> bool {
|
fn is_enabled(&self) -> bool {
|
||||||
self.enabled
|
self.enabled
|
||||||
}
|
}
|
||||||
|
|
||||||
fn vblank_reset(&mut self) {
|
|
||||||
self.window_line.vblank_reset();
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Fetcher for BackgroundFetcher {
|
impl Fetcher for BackgroundFetcher {
|
||||||
|
@ -818,7 +807,7 @@ impl Default for BackgroundFetcher {
|
||||||
state: Default::default(),
|
state: Default::default(),
|
||||||
tile: Default::default(),
|
tile: Default::default(),
|
||||||
is_window_tile: Default::default(),
|
is_window_tile: Default::default(),
|
||||||
window_line: Default::default(),
|
wl_count: Default::default(),
|
||||||
enabled: true,
|
enabled: true,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -846,25 +835,6 @@ impl Fetcher for ObjectFetcher {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Debug, Default)]
|
|
||||||
struct WindowLineCounter {
|
|
||||||
count: u8,
|
|
||||||
}
|
|
||||||
|
|
||||||
impl WindowLineCounter {
|
|
||||||
fn increment(&mut self) {
|
|
||||||
self.count += 1;
|
|
||||||
}
|
|
||||||
|
|
||||||
fn vblank_reset(&mut self) {
|
|
||||||
self.count = 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
fn count(&self) -> u8 {
|
|
||||||
self.count
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
#[derive(Debug, Clone, Copy)]
|
#[derive(Debug, Clone, Copy)]
|
||||||
enum FetcherState {
|
enum FetcherState {
|
||||||
TileNumber,
|
TileNumber,
|
||||||
|
@ -959,31 +929,5 @@ struct WindowStatus {
|
||||||
coincidence: bool,
|
coincidence: bool,
|
||||||
/// This will be true if the conditions which tell the PPU to start
|
/// This will be true if the conditions which tell the PPU to start
|
||||||
/// drawing from the window tile map is true
|
/// drawing from the window tile map is true
|
||||||
should_draw: bool,
|
enabled: bool,
|
||||||
}
|
|
||||||
|
|
||||||
impl WindowStatus {
|
|
||||||
fn should_draw(&self) -> bool {
|
|
||||||
self.should_draw
|
|
||||||
}
|
|
||||||
|
|
||||||
fn coincidence(&self) -> bool {
|
|
||||||
self.coincidence
|
|
||||||
}
|
|
||||||
|
|
||||||
fn set_should_draw(&mut self, value: bool) {
|
|
||||||
self.should_draw = value;
|
|
||||||
}
|
|
||||||
|
|
||||||
fn set_coincidence(&mut self, value: bool) {
|
|
||||||
self.coincidence = value;
|
|
||||||
}
|
|
||||||
|
|
||||||
fn hblank_reset(&mut self) {
|
|
||||||
self.should_draw = false;
|
|
||||||
}
|
|
||||||
|
|
||||||
fn vblank_reset(&mut self) {
|
|
||||||
self.coincidence = false;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue