use super::{palette, Ppu};
use crate::ppu::palette::Color;
use crate::ppu::scanline_pos::ScanlinePos;
use crate::ppu::vram_read_buffer::VramReadBuffer;
use arrayvec::ArrayVec;
impl Default for Ppu {
fn default() -> Self {
Self {
regs: Default::default(),
oam: Default::default(),
palette: palette::Ram::new(),
read_buffer: Default::default(),
scanline_pos: ScanlinePos::start_frame(),
sprites_for_scanline: ArrayVec::new(),
sprites_start_col: ArrayVec::new(),
sprites_at_current_pixel: ArrayVec::new(),
screen_colors: ArrayVec::new(),
vram_read_buffer: VramReadBuffer::new(),
cycle_accurate_sprites_enabled: false,
bg_tile: None,
#[cfg(test)]
cycles_since_reset: 0,
nmi_signal: false,
sprite_addr: 0,
sprites_for_next_scanline: Default::default(),
sprite_zero_pos: u8::MAX,
#[cfg(feature = "show_name_table_change")]
last_event: Default::default(),
}
}
}
impl Ppu {
pub fn new() -> Self {
Self::default()
}
pub fn reset(&mut self) {
self.regs.reset();
#[cfg(test)]
{
self.cycles_since_reset = 0;
}
}
pub fn screen_colors(&self) -> &[Color] {
self.screen_colors.as_slice()
}
}
#[cfg(test)]
mod test {
use super::*;
use crate::{FrameEvent, PpuCartMemorySpace};
const CYCLES_PER_SCANLINE: usize = 341;
const SCANLINES_PER_FRAME: usize = 262;
struct MockCart;
impl PpuCartMemorySpace for MockCart {
fn read(&mut self, _addr: u16) -> u8 {
0xFF
}
fn write(&mut self, _data: u8, _addr: u16) {}
}
#[test]
fn ppu_cycle_count() {
let mut ppu = Ppu::new();
let mut cart = MockCart;
while ppu.run_cycle(&mut cart) != FrameEvent::EndOfFrame {}
while ppu.run_cycle(&mut cart) != FrameEvent::EndOfFrame {}
assert_eq!(
ppu.cycles_since_reset,
CYCLES_PER_SCANLINE * SCANLINES_PER_FRAME * 2 - 1
);
}
}