From a4979ac8473c194900857ae6f6f90cbfc30f6e91 Mon Sep 17 00:00:00 2001 From: Corwin Date: Mon, 4 Apr 2022 20:29:00 +0100 Subject: [PATCH] better handling of sprites --- agb/examples/chicken.rs | 2 +- agb/src/display/object.rs | 46 ++++++++++++------- .../the-hat-chooses-the-wizard/src/main.rs | 2 +- examples/the-purple-night/src/main.rs | 2 +- 4 files changed, 32 insertions(+), 20 deletions(-) diff --git a/agb/examples/chicken.rs b/agb/examples/chicken.rs index d9879ac1..3a9bbe13 100644 --- a/agb/examples/chicken.rs +++ b/agb/examples/chicken.rs @@ -20,7 +20,7 @@ enum State { } struct Character<'a> { - object: Object<'a, 'a>, + object: Object<'a>, position: Vector2D, velocity: Vector2D, } diff --git a/agb/src/display/object.rs b/agb/src/display/object.rs index e9b2da41..d32095fe 100644 --- a/agb/src/display/object.rs +++ b/agb/src/display/object.rs @@ -354,10 +354,8 @@ impl Attributes { } } -pub struct Object<'a, 'b> { - sprite: SpriteBorrow<'a>, - previous_sprite: SpriteBorrow<'a>, - loan: Loan<'b>, +pub struct Object<'a> { + loan: Loan<'a>, } struct SpriteControllerInner { @@ -378,9 +376,10 @@ impl Drop for Loan<'_> { } } -#[derive(PartialEq, Eq)] struct ObjectInner { attrs: Attributes, + sprite: SpriteBorrow<'static>, + previous_sprite: SpriteBorrow<'static>, z: i32, } @@ -433,8 +432,12 @@ impl ObjectController { let s = unsafe { get_object_controller() }; 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); + + let mut a = o.sprite.clone(); + core::mem::swap(&mut o.previous_sprite, &mut a); + a.drop(&mut s.sprite_controller); } else { unsafe { (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") } - pub fn try_get_object<'a, 'b>(&'a self, sprite: SpriteBorrow<'b>) -> Option> { + pub fn try_get_object<'a>(&'a self, sprite: SpriteBorrow<'a>) -> Option> { let s = unsafe { get_object_controller() }; let mut attrs = Attributes::new(); @@ -482,7 +485,14 @@ impl ObjectController { 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 { index: index as u8, @@ -491,11 +501,7 @@ impl ObjectController { s.update_z_ordering(); - Some(Object { - previous_sprite: sprite.clone(), - sprite, - loan, - }) + Some(Object { loan }) } 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)] fn object_inner(&mut self) -> &mut ObjectInner { 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().a1a.set_size(shape_size.1); self.attrs().a1s.set_size(shape_size.1); - self.previous_sprite = self.sprite.clone(); - self.sprite = sprite; + self.object_inner().sprite = unsafe { core::mem::transmute(sprite) }; } 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> { fn clone(&self) -> Self { let s = unsafe { get_object_controller() }; diff --git a/examples/the-hat-chooses-the-wizard/src/main.rs b/examples/the-hat-chooses-the-wizard/src/main.rs index 00a35e65..1a3a0edc 100644 --- a/examples/the-hat-chooses-the-wizard/src/main.rs +++ b/examples/the-hat-chooses-the-wizard/src/main.rs @@ -111,7 +111,7 @@ const HAT_SPIN_3: &Tag = TAG_MAP.get("HatSpin3"); type FixedNumberType = FixedNum<10>; pub struct Entity<'a> { - sprite: Object<'a, 'a>, + sprite: Object<'a>, position: Vector2D, velocity: Vector2D, collision_mask: Vector2D, diff --git a/examples/the-purple-night/src/main.rs b/examples/the-purple-night/src/main.rs index e095b5be..fa0dc996 100644 --- a/examples/the-purple-night/src/main.rs +++ b/examples/the-purple-night/src/main.rs @@ -152,7 +152,7 @@ impl<'a> Level<'a> { } struct Entity<'a> { - sprite: Object<'a, 'a>, + sprite: Object<'a>, position: Vector2D, velocity: Vector2D, collision_mask: Rect,