better handling of sprites

This commit is contained in:
Corwin 2022-04-04 20:29:00 +01:00
parent 3e3039a7f6
commit a4979ac847
4 changed files with 32 additions and 20 deletions

View file

@ -20,7 +20,7 @@ enum State {
} }
struct Character<'a> { struct Character<'a> {
object: Object<'a, 'a>, object: Object<'a>,
position: Vector2D, position: Vector2D,
velocity: Vector2D, velocity: Vector2D,
} }

View file

@ -354,10 +354,8 @@ impl Attributes {
} }
} }
pub struct Object<'a, 'b> { pub struct Object<'a> {
sprite: SpriteBorrow<'a>, loan: Loan<'a>,
previous_sprite: SpriteBorrow<'a>,
loan: Loan<'b>,
} }
struct SpriteControllerInner { struct SpriteControllerInner {
@ -378,9 +376,10 @@ impl Drop for Loan<'_> {
} }
} }
#[derive(PartialEq, Eq)]
struct ObjectInner { struct ObjectInner {
attrs: Attributes, attrs: Attributes,
sprite: SpriteBorrow<'static>,
previous_sprite: SpriteBorrow<'static>,
z: i32, z: i32,
} }
@ -433,8 +432,12 @@ impl ObjectController {
let s = unsafe { get_object_controller() }; let s = unsafe { get_object_controller() };
for (i, &z) in s.z_order.iter().enumerate() { for (i, &z) in s.z_order.iter().enumerate() {
if let Some(o) = &s.shadow_oam[z as usize] { if let Some(o) = &mut s.shadow_oam[z as usize] {
o.attrs.commit(i); o.attrs.commit(i);
let mut a = o.sprite.clone();
core::mem::swap(&mut o.previous_sprite, &mut a);
a.drop(&mut s.sprite_controller);
} else { } else {
unsafe { unsafe {
(OBJECT_ATTRIBUTE_MEMORY as *mut u16) (OBJECT_ATTRIBUTE_MEMORY as *mut u16)
@ -464,11 +467,11 @@ impl ObjectController {
} }
} }
pub fn object<'a, 'b>(&'a self, sprite: SpriteBorrow<'b>) -> Object<'b, 'a> { pub fn object<'a>(&'a self, sprite: SpriteBorrow<'a>) -> Object<'a> {
self.try_get_object(sprite).expect("No object available") self.try_get_object(sprite).expect("No object available")
} }
pub fn try_get_object<'a, 'b>(&'a self, sprite: SpriteBorrow<'b>) -> Option<Object<'b, 'a>> { pub fn try_get_object<'a>(&'a self, sprite: SpriteBorrow<'a>) -> Option<Object<'a>> {
let s = unsafe { get_object_controller() }; let s = unsafe { get_object_controller() };
let mut attrs = Attributes::new(); let mut attrs = Attributes::new();
@ -482,7 +485,14 @@ impl ObjectController {
let index = s.free_object.pop()?; let index = s.free_object.pop()?;
s.shadow_oam[index as usize] = Some(ObjectInner { attrs, z: 0 }); let new_sprite: SpriteBorrow<'static> = unsafe { core::mem::transmute(sprite) };
s.shadow_oam[index as usize] = Some(ObjectInner {
attrs,
z: 0,
previous_sprite: new_sprite.clone(),
sprite: new_sprite,
});
let loan = Loan { let loan = Loan {
index: index as u8, index: index as u8,
@ -491,11 +501,7 @@ impl ObjectController {
s.update_z_ordering(); s.update_z_ordering();
Some(Object { Some(Object { loan })
previous_sprite: sprite.clone(),
sprite,
loan,
})
} }
pub fn sprite(&self, sprite: &'static Sprite) -> SpriteBorrow { pub fn sprite(&self, sprite: &'static Sprite) -> SpriteBorrow {
@ -509,7 +515,7 @@ impl ObjectController {
} }
} }
impl<'a, 'b> Object<'a, 'b> { impl<'a> Object<'a> {
#[inline(always)] #[inline(always)]
fn object_inner(&mut self) -> &mut ObjectInner { fn object_inner(&mut self) -> &mut ObjectInner {
let s = unsafe { get_object_controller() }; let s = unsafe { get_object_controller() };
@ -534,8 +540,7 @@ impl<'a, 'b> Object<'a, 'b> {
self.attrs().a0.set_shape(shape_size.0); self.attrs().a0.set_shape(shape_size.0);
self.attrs().a1a.set_size(shape_size.1); self.attrs().a1a.set_size(shape_size.1);
self.attrs().a1s.set_size(shape_size.1); self.attrs().a1s.set_size(shape_size.1);
self.previous_sprite = self.sprite.clone(); self.object_inner().sprite = unsafe { core::mem::transmute(sprite) };
self.sprite = sprite;
} }
pub fn show(&mut self) -> &mut Self { pub fn show(&mut self) -> &mut Self {
@ -754,6 +759,13 @@ impl<'a> Drop for SpriteBorrow<'a> {
} }
} }
impl<'a> SpriteBorrow<'a> {
fn drop(self, s: &mut SpriteControllerInner) {
s.return_sprite(self.id.sprite());
core::mem::forget(self);
}
}
impl<'a> Clone for SpriteBorrow<'a> { impl<'a> Clone for SpriteBorrow<'a> {
fn clone(&self) -> Self { fn clone(&self) -> Self {
let s = unsafe { get_object_controller() }; let s = unsafe { get_object_controller() };

View file

@ -111,7 +111,7 @@ const HAT_SPIN_3: &Tag = TAG_MAP.get("HatSpin3");
type FixedNumberType = FixedNum<10>; type FixedNumberType = FixedNum<10>;
pub struct Entity<'a> { pub struct Entity<'a> {
sprite: Object<'a, 'a>, sprite: Object<'a>,
position: Vector2D<FixedNumberType>, position: Vector2D<FixedNumberType>,
velocity: Vector2D<FixedNumberType>, velocity: Vector2D<FixedNumberType>,
collision_mask: Vector2D<u16>, collision_mask: Vector2D<u16>,

View file

@ -152,7 +152,7 @@ impl<'a> Level<'a> {
} }
struct Entity<'a> { struct Entity<'a> {
sprite: Object<'a, 'a>, sprite: Object<'a>,
position: Vector2D<Number>, position: Vector2D<Number>,
velocity: Vector2D<Number>, velocity: Vector2D<Number>,
collision_mask: Rect<u16>, collision_mask: Rect<u16>,