diff --git a/agb/src/display/object/managed.rs b/agb/src/display/object/managed.rs index 58000a7e..569019d1 100644 --- a/agb/src/display/object/managed.rs +++ b/agb/src/display/object/managed.rs @@ -167,8 +167,6 @@ impl OAMManager<'_> { } pub fn commit(&self) { - let mut count = 0; - let mut unmanaged = UnmanagedOAM::new(); // do interactions with OAM @@ -179,9 +177,7 @@ impl OAMManager<'_> { .zip(unmanaged.iter()) { slot.set(object); - count += 1; } - unmanaged.clear_from(count); // finished OAM interactions diff --git a/agb/src/display/object/unmanaged/object.rs b/agb/src/display/object/unmanaged/object.rs index ef50b9c9..efca61a1 100644 --- a/agb/src/display/object/unmanaged/object.rs +++ b/agb/src/display/object/unmanaged/object.rs @@ -1,4 +1,7 @@ -use core::{cell::UnsafeCell, marker::PhantomData}; +use core::{ + cell::{Cell, UnsafeCell}, + marker::PhantomData, +}; use agb_fixnum::Vector2D; @@ -11,16 +14,17 @@ use super::attributes::{AffineMode, Attributes}; pub struct UnmanagedOAM<'gba> { phantom: PhantomData<&'gba ()>, + up_to: Cell, } pub struct OAMIterator<'oam> { - phantom: PhantomData<&'oam ()>, index: usize, + up_to: &'oam Cell, } pub struct OAMSlot<'oam> { - phantom: PhantomData<&'oam ()>, slot: usize, + up_to: &'oam Cell, } impl OAMSlot<'_> { @@ -31,6 +35,8 @@ impl OAMSlot<'_> { let sprites = unsafe { &mut *object.sprites.get() }; sprites.previous_sprite = Some(sprites.sprite.clone()); + + self.up_to.set(self.slot as i32); } fn set_bytes(&mut self, bytes: [u8; 6]) { @@ -52,39 +58,42 @@ impl<'oam> Iterator for OAMIterator<'oam> { None } else { Some(OAMSlot { - phantom: PhantomData, slot: idx, + up_to: self.up_to, }) } } } +impl Drop for OAMIterator<'_> { + fn drop(&mut self) { + let last_written = self.up_to.get(); + + let number_writen = (last_written + 1) as usize; + + for idx in number_writen..128 { + unsafe { + let ptr = (OBJECT_ATTRIBUTE_MEMORY as *mut u16).add(idx * 4); + ptr.write_volatile(0b10 << 8); + } + } + } +} + impl UnmanagedOAM<'_> { pub fn iter(&mut self) -> OAMIterator<'_> { OAMIterator { - phantom: PhantomData, index: 0, + up_to: &mut self.up_to, } } pub(crate) fn new() -> Self { Self { + up_to: Cell::new(0), phantom: PhantomData, } } - - pub fn clear_from(&self, from: usize) { - if from >= 128 { - return; - } - - for i in from..128 { - unsafe { - let ptr = (OBJECT_ATTRIBUTE_MEMORY as *mut u16).add(i * 4); - ptr.write_volatile(0b10 << 8); - } - } - } } #[derive(Debug)]