chore(ppu): reimplement the object buffer
This commit is contained in:
parent
f92f4a17e0
commit
d457761c3b
67
src/ppu.rs
67
src/ppu.rs
|
@ -12,7 +12,7 @@ const PPU_START_ADDRESS: usize = 0x8000;
|
||||||
// OAM Scan
|
// OAM Scan
|
||||||
const OBJECT_LIMIT: usize = 10;
|
const OBJECT_LIMIT: usize = 10;
|
||||||
|
|
||||||
// // White and Black
|
// // White
|
||||||
// const WHITE: [u8; 4] = 0xFFFFFFFFu32.to_be_bytes();
|
// const WHITE: [u8; 4] = 0xFFFFFFFFu32.to_be_bytes();
|
||||||
// const LIGHT_GRAY: [u8; 4] = 0xB6B6B6FFu32.to_be_bytes();
|
// const LIGHT_GRAY: [u8; 4] = 0xB6B6B6FFu32.to_be_bytes();
|
||||||
// const DARK_GRAY: [u8; 4] = 0x676767FFu32.to_be_bytes();
|
// const DARK_GRAY: [u8; 4] = 0x676767FFu32.to_be_bytes();
|
||||||
|
@ -151,7 +151,7 @@ impl Ppu {
|
||||||
}
|
}
|
||||||
|
|
||||||
fn scan_oam(&mut self, cycle: u32) {
|
fn scan_oam(&mut self, cycle: u32) {
|
||||||
if cycle % 2 != 0 {
|
if cycle % 2 == 0 {
|
||||||
// This is run 50% of the time, or 40 times
|
// This is run 50% of the time, or 40 times
|
||||||
// which is the number of sprites in OAM
|
// which is the number of sprites in OAM
|
||||||
|
|
||||||
|
@ -276,9 +276,7 @@ impl Ppu {
|
||||||
self.fetcher.bg.resume();
|
self.fetcher.bg.resume();
|
||||||
self.fifo.resume();
|
self.fifo.resume();
|
||||||
|
|
||||||
self.obj_buffer
|
self.obj_buffer.remove(&attr);
|
||||||
.remove(&attr)
|
|
||||||
.expect("Failed to remove Sprite Attribute from Buffer");
|
|
||||||
}
|
}
|
||||||
} else if self.fetcher.obj.fifo_count == 2 {
|
} else if self.fetcher.obj.fifo_count == 2 {
|
||||||
self.fetcher.obj.reset();
|
self.fetcher.obj.reset();
|
||||||
|
@ -962,67 +960,49 @@ impl From<ObjectPaletteId> for u8 {
|
||||||
|
|
||||||
#[derive(Debug, Clone, Copy)]
|
#[derive(Debug, Clone, Copy)]
|
||||||
struct ObjectBuffer {
|
struct ObjectBuffer {
|
||||||
buf: [ObjectAttribute; 10],
|
buf: [Option<ObjectAttribute>; 10],
|
||||||
len: usize,
|
|
||||||
}
|
}
|
||||||
|
|
||||||
impl ObjectBuffer {
|
impl ObjectBuffer {
|
||||||
pub fn full(&self) -> bool {
|
pub fn full(&self) -> bool {
|
||||||
self.len == self.buf.len()
|
!self.buf.iter().any(|maybe_attr| maybe_attr.is_none())
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn clear(&mut self) {
|
pub fn clear(&mut self) {
|
||||||
self.buf = [Default::default(); 10];
|
self.buf = [Default::default(); 10];
|
||||||
self.len = 0;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn add(&mut self, attr: ObjectAttribute) {
|
pub fn add(&mut self, attr: ObjectAttribute) {
|
||||||
self.buf[self.len] = attr;
|
// TODO: Maybe this doesn't need to be O(n)?
|
||||||
self.len += 1;
|
for maybe_attr in self.buf.iter_mut() {
|
||||||
|
if maybe_attr.is_none() {
|
||||||
|
*maybe_attr = Some(attr);
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn len(&self) -> usize {
|
pub fn len(&self) -> usize {
|
||||||
self.len
|
self.buf
|
||||||
|
.iter()
|
||||||
|
.filter(|maybe_attr| maybe_attr.is_some())
|
||||||
|
.count()
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn get(&self, index: usize) -> Option<&ObjectAttribute> {
|
pub fn get(&self, index: usize) -> Option<&ObjectAttribute> {
|
||||||
if index < self.len {
|
self.buf[index].as_ref()
|
||||||
Some(&self.buf[index])
|
|
||||||
} else {
|
|
||||||
None
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn position(&self, attr: &ObjectAttribute) -> Option<usize> {
|
pub fn position(&self, attr: &ObjectAttribute) -> Option<usize> {
|
||||||
let mut index = None;
|
self.buf.iter().position(|maybe_attr| match maybe_attr {
|
||||||
|
Some(other_attr) => attr == other_attr,
|
||||||
for i in 0..self.len {
|
None => false,
|
||||||
if self.buf[i] == *attr {
|
})
|
||||||
index = Some(i);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
index
|
pub fn remove(&mut self, attr: &ObjectAttribute) {
|
||||||
|
if let Some(i) = self.position(attr) {
|
||||||
|
self.buf[i] = None;
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn remove(&mut self, attr: &ObjectAttribute) -> Result<(), Box<dyn std::error::Error>> {
|
|
||||||
// TODO: Make this not bad code
|
|
||||||
let mut copy: ObjectBuffer = Default::default();
|
|
||||||
|
|
||||||
let i = self
|
|
||||||
.position(attr)
|
|
||||||
.ok_or_else(|| format!("Could not find {:?} in Sprite Buffer", attr))?;
|
|
||||||
|
|
||||||
for j in 0..self.len {
|
|
||||||
if j != i {
|
|
||||||
copy.add(self.buf[j])
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
self.buf = copy.buf;
|
|
||||||
self.len = copy.len;
|
|
||||||
|
|
||||||
Ok(())
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1030,7 +1010,6 @@ impl Default for ObjectBuffer {
|
||||||
fn default() -> Self {
|
fn default() -> Self {
|
||||||
Self {
|
Self {
|
||||||
buf: [Default::default(); OBJECT_LIMIT],
|
buf: [Default::default(); OBJECT_LIMIT],
|
||||||
len: 0,
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue