diff --git a/agb/src/display/object/managed.rs b/agb/src/display/object/managed.rs index 861ffa53..9d99ae2b 100644 --- a/agb/src/display/object/managed.rs +++ b/agb/src/display/object/managed.rs @@ -7,7 +7,7 @@ use agb_fixnum::Vector2D; use alloc::vec::Vec; use slotmap::{new_key_type, SlotMap}; -use crate::{display::Priority, sync::Static}; +use crate::display::Priority; use super::{AffineMode, Sprite, SpriteVram, StaticSpriteLoader, UnmanagedOAM, UnmanagedObject}; diff --git a/agb/src/display/object/unmanaged/object.rs b/agb/src/display/object/unmanaged/object.rs index 9c28bd0a..ef50b9c9 100644 --- a/agb/src/display/object/unmanaged/object.rs +++ b/agb/src/display/object/unmanaged/object.rs @@ -102,13 +102,22 @@ pub struct UnmanagedObject { impl UnmanagedObject { #[must_use] pub fn new(sprite: SpriteVram) -> Self { - Self { + let sprite_location = sprite.location(); + let palette_location = sprite.palette_location(); + let (shape, size) = sprite.size().shape_size(); + + let mut sprite = Self { attributes: Attributes::default(), sprites: UnsafeCell::new(VramSprites { sprite, previous_sprite: None, }), - } + }; + + sprite.attributes.set_sprite(sprite_location, shape, size); + sprite.attributes.set_palette(palette_location); + + sprite } pub fn is_visible(&self) -> bool { @@ -170,16 +179,21 @@ impl UnmanagedObject { self } - pub fn set_sprite(&mut self, sprite: SpriteVram) -> &mut Self { - // SAFETY: This is called here and in OAMSlot set, neither of which call the other. - let sprites = unsafe { &mut *self.sprites.get() }; - + fn set_sprite_attributes(&mut self, sprite: &SpriteVram) -> &mut Self { let size = sprite.size(); let (shape, size) = size.shape_size(); self.attributes.set_sprite(sprite.location(), shape, size); self.attributes.set_palette(sprite.palette_location()); + self + } + + pub fn set_sprite(&mut self, sprite: SpriteVram) -> &mut Self { + self.set_sprite_attributes(&sprite); + + // SAFETY: This is called here and in OAMSlot set, neither of which call the other. + let sprites = unsafe { &mut *self.sprites.get() }; sprites.sprite = sprite; self diff --git a/examples/combo/Cargo.lock b/examples/combo/Cargo.lock index 68bc03c2..d44a3230 100644 --- a/examples/combo/Cargo.lock +++ b/examples/combo/Cargo.lock @@ -26,6 +26,7 @@ dependencies = [ "bitflags 2.0.2", "modular-bitfield", "rustc-hash", + "slotmap", ] [[package]] @@ -201,7 +202,7 @@ version = "0.7.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "6a62391ecb864cf12ed06b2af4eda2e609b97657950d6a8f06841b17726ab253" dependencies = [ - "hashbrown", + "hashbrown 0.11.2", "ttf-parser", ] @@ -234,6 +235,12 @@ dependencies = [ "ahash", ] +[[package]] +name = "hashbrown" +version = "0.12.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8a9ee70c43aaf417c914396645a0fa852624801b24ebb7ae78fe8272889ac888" + [[package]] name = "hound" version = "3.5.0" @@ -245,7 +252,6 @@ name = "hyperspace-roll" version = "0.1.0" dependencies = [ "agb", - "bare-metal", ] [[package]] @@ -263,6 +269,16 @@ dependencies = [ "png", ] +[[package]] +name = "indexmap" +version = "1.9.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "bd070e393353796e801d209ad339e89596eb4c8d430d18ede6a1cced8fafbd99" +dependencies = [ + "autocfg", + "hashbrown 0.12.3", +] + [[package]] name = "itoa" version = "1.0.6" @@ -296,6 +312,12 @@ dependencies = [ "cfg-if 1.0.0", ] +[[package]] +name = "memchr" +version = "2.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2dffe52ecf27772e601905b7522cb4ef790d2cc203488bbd0e2fe85fcb74566d" + [[package]] name = "miniz_oxide" version = "0.3.7" @@ -467,6 +489,24 @@ dependencies = [ "serde", ] +[[package]] +name = "serde_spanned" +version = "0.6.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0efd8caf556a6cebd3b285caf480045fcc1ac04f6bd786b09a6f11af30c4fcf4" +dependencies = [ + "serde", +] + +[[package]] +name = "slotmap" +version = "1.0.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e1e08e261d0e8f5c43123b7adf3e4ca1690d655377ac93a03b2c9d3e98de1342" +dependencies = [ + "version_check", +] + [[package]] name = "static_assertions" version = "1.1.0" @@ -533,11 +573,36 @@ dependencies = [ [[package]] name = "toml" -version = "0.5.11" +version = "0.7.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f4f7f0dd8d50a853a531c426359045b1998f04219d88799810762cd4ad314234" +checksum = "b403acf6f2bb0859c93c7f0d967cb4a75a7ac552100f9322faf64dc047669b21" dependencies = [ "serde", + "serde_spanned", + "toml_datetime", + "toml_edit", +] + +[[package]] +name = "toml_datetime" +version = "0.6.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3ab8ed2edee10b50132aed5f331333428b011c99402b5a534154ed15746f9622" +dependencies = [ + "serde", +] + +[[package]] +name = "toml_edit" +version = "0.19.8" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "239410c8609e8125456927e6707163a3b1fdb40561e4b803bc041f466ccfdc13" +dependencies = [ + "indexmap", + "serde", + "serde_spanned", + "toml_datetime", + "winnow", ] [[package]] @@ -564,6 +629,15 @@ version = "0.11.0+wasi-snapshot-preview1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "9c8d87e72b64a3b4db28d11ce29237c246188f4f51057d65a7eab63b7987e423" +[[package]] +name = "winnow" +version = "0.4.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ae8970b36c66498d8ff1d66685dc86b91b29db0c7739899012f63a63814b4b28" +dependencies = [ + "memchr", +] + [[package]] name = "xml-rs" version = "0.8.4" diff --git a/examples/hyperspace-roll/Cargo.lock b/examples/hyperspace-roll/Cargo.lock index da95b861..84a8548d 100644 --- a/examples/hyperspace-roll/Cargo.lock +++ b/examples/hyperspace-roll/Cargo.lock @@ -26,6 +26,7 @@ dependencies = [ "bitflags 2.0.2", "modular-bitfield", "rustc-hash", + "slotmap", ] [[package]] @@ -423,6 +424,18 @@ dependencies = [ ] [[package]] +<<<<<<< HEAD +======= +name = "slotmap" +version = "1.0.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e1e08e261d0e8f5c43123b7adf3e4ca1690d655377ac93a03b2c9d3e98de1342" +dependencies = [ + "version_check", +] + +[[package]] +>>>>>>> ff9ab890 (fix games) name = "static_assertions" version = "1.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" diff --git a/examples/hyperspace-roll/src/battle.rs b/examples/hyperspace-roll/src/battle.rs index 04f76fdd..cce4cd80 100644 --- a/examples/hyperspace-roll/src/battle.rs +++ b/examples/hyperspace-roll/src/battle.rs @@ -494,7 +494,7 @@ pub(crate) fn battle_screen( let obj = &agb.obj; - let mut select_box_obj = agb.obj.object(agb.obj.sprite(SELECT_BOX.sprite(0))); + let mut select_box_obj = agb.obj.add_object_static_sprite(SELECT_BOX.sprite(0)); select_box_obj.show(); let num_dice = player_dice.dice.len(); @@ -585,7 +585,10 @@ pub(crate) fn battle_screen( select_box_obj .set_y(120 - 4) .set_x(selected_die as u16 * 40 + 28 - 4) - .set_sprite(agb.obj.sprite(SELECT_BOX.animation_sprite(counter / 10))); + .set_sprite( + agb.obj + .get_vram_sprite(SELECT_BOX.animation_sprite(counter / 10)), + ); agb.star_background.update(); agb.sfx.frame(); diff --git a/examples/hyperspace-roll/src/battle/display.rs b/examples/hyperspace-roll/src/battle/display.rs index 1b33009f..973d7e79 100644 --- a/examples/hyperspace-roll/src/battle/display.rs +++ b/examples/hyperspace-roll/src/battle/display.rs @@ -1,4 +1,4 @@ -use agb::display::object::{Object, ObjectController}; +use agb::display::object::{OAMManager, Object}; use agb::rng; use alloc::vec; use alloc::vec::Vec; @@ -39,7 +39,7 @@ pub struct BattleScreenDisplay<'a> { const HEALTH_BAR_WIDTH: usize = 48; impl<'a> BattleScreenDisplay<'a> { - pub fn new(obj: &'a ObjectController, current_battle_state: &CurrentBattleState) -> Self { + pub fn new(obj: &'a OAMManager, current_battle_state: &CurrentBattleState) -> Self { let mut misc_sprites = vec![]; let player_x = 12; let player_y = 8; @@ -52,8 +52,8 @@ impl<'a> BattleScreenDisplay<'a> { Ship::PilotedShip }); - let mut player_obj = obj.object(obj.sprite(player_sprite)); - let mut enemy_obj = obj.object(obj.sprite(enemy_sprite)); + let mut player_obj = obj.add_object_static_sprite(player_sprite); + let mut enemy_obj = obj.add_object_static_sprite(enemy_sprite); player_obj.set_x(player_x).set_y(player_y).set_z(1).show(); enemy_obj.set_x(enemy_x).set_y(player_y).set_z(1).show(); @@ -66,7 +66,7 @@ impl<'a> BattleScreenDisplay<'a> { .faces_to_render() .enumerate() .map(|(i, (face, _))| { - let mut die_obj = obj.object(obj.sprite(FACE_SPRITES.sprite_for_face(face))); + let mut die_obj = obj.add_object_static_sprite(FACE_SPRITES.sprite_for_face(face)); die_obj.set_y(120).set_x(i as u16 * 40 + 28).show(); @@ -89,7 +89,7 @@ impl<'a> BattleScreenDisplay<'a> { let player_shield: Vec<_> = (0..5) .map(|i| { - let mut shield_obj = obj.object(obj.sprite(shield_sprite)); + let mut shield_obj = obj.add_object_static_sprite(shield_sprite); shield_obj .set_x(player_x + 18 + 11 * i) .set_y(player_y) @@ -101,7 +101,7 @@ impl<'a> BattleScreenDisplay<'a> { let enemy_shield: Vec<_> = (0..5) .map(|i| { - let mut shield_obj = obj.object(obj.sprite(shield_sprite)); + let mut shield_obj = obj.add_object_static_sprite(shield_sprite); shield_obj .set_x(enemy_x - 16 - 11 * i) .set_y(player_y) @@ -146,8 +146,8 @@ impl<'a> BattleScreenDisplay<'a> { let enemy_attack_display = (0..2) .map(|i| { - let mut attack_obj = obj.object( - obj.sprite(ENEMY_ATTACK_SPRITES.sprite_for_attack(EnemyAttackType::Attack)), + let mut attack_obj = obj.add_object_static_sprite( + ENEMY_ATTACK_SPRITES.sprite_for_attack(EnemyAttackType::Attack), ); let attack_obj_position = (120, 56 + 32 * i).into(); @@ -189,14 +189,14 @@ impl<'a> BattleScreenDisplay<'a> { pub fn update( &mut self, - obj: &'a ObjectController, + obj: &'a OAMManager, current_battle_state: &CurrentBattleState, ) -> Vec { for (i, player_shield) in self.objs.player_shield.iter_mut().enumerate() { if i < current_battle_state.player.shield_count as usize { player_shield .show() - .set_sprite(obj.sprite(SHIELD.sprite(0))); + .set_sprite(obj.get_vram_sprite(SHIELD.sprite(0))); } else { player_shield.hide(); } @@ -206,7 +206,7 @@ impl<'a> BattleScreenDisplay<'a> { if i < current_battle_state.enemy.shield_count as usize { player_shield .show() - .set_sprite(obj.sprite(SHIELD.sprite(0))); + .set_sprite(obj.get_vram_sprite(SHIELD.sprite(0))); } else { player_shield.hide(); } @@ -250,7 +250,7 @@ impl<'a> BattleScreenDisplay<'a> { .zip(current_battle_state.rolled_dice.faces_to_render()) .zip(self.objs.dice_cooldowns.iter_mut()) { - die_obj.set_sprite(obj.sprite(FACE_SPRITES.sprite_for_face(current_face))); + die_obj.set_sprite(obj.get_vram_sprite(FACE_SPRITES.sprite_for_face(current_face))); if let Some(cooldown) = cooldown { cooldown_healthbar @@ -279,7 +279,7 @@ impl<'a> BattleScreenDisplay<'a> { actions_to_apply } - pub fn add_action(&mut self, action: Action, obj: &'a ObjectController, sfx: &mut Sfx) { + pub fn add_action(&mut self, action: Action, obj: &'a OAMManager, sfx: &mut Sfx) { play_sound_for_action_start(&action, sfx); self.animations @@ -309,10 +309,10 @@ impl<'a> EnemyAttackDisplay<'a> { } } - pub fn update(&mut self, attack: &Option, obj: &'a ObjectController) { + pub fn update(&mut self, attack: &Option, obj: &'a OAMManager) { if let Some(attack) = attack { self.face.show().set_sprite( - obj.sprite(ENEMY_ATTACK_SPRITES.sprite_for_attack(attack.attack_type())), + obj.get_vram_sprite(ENEMY_ATTACK_SPRITES.sprite_for_attack(attack.attack_type())), ); self.cooldown .set_value((attack.cooldown * 48 / attack.max_cooldown) as usize, obj); @@ -350,27 +350,27 @@ enum AnimationUpdateState { } impl<'a> AnimationStateHolder<'a> { - fn for_action(a: Action, obj: &'a ObjectController) -> Self { + fn for_action(a: Action, obj: &'a OAMManager) -> Self { let state = match a { Action::PlayerActivateShield { amount, .. } => { AnimationState::PlayerActivateShield { amount, frame: 0 } } Action::PlayerShoot { .. } => AnimationState::PlayerShoot { - bullet: obj.object(obj.sprite(BULLET_SPRITE)), + bullet: obj.add_object_static_sprite(BULLET_SPRITE), x: 64, }, Action::PlayerDisrupt { .. } => AnimationState::PlayerDisrupt { - bullet: obj.object(obj.sprite(DISRUPT_BULLET)), + bullet: obj.add_object_static_sprite(DISRUPT_BULLET), x: 64, }, Action::PlayerHeal { .. } => AnimationState::PlayerHeal {}, Action::PlayerBurstShield { .. } => AnimationState::PlayerBurstShield { frame: 0 }, Action::PlayerSendBurstShield { .. } => AnimationState::PlayerSendBurstShield { - bullet: obj.object(obj.sprite(BURST_BULLET)), + bullet: obj.add_object_static_sprite(BURST_BULLET), x: 64, }, Action::EnemyShoot { .. } => AnimationState::EnemyShoot { - bullet: obj.object(obj.sprite(BULLET_SPRITE)), + bullet: obj.add_object_static_sprite(BULLET_SPRITE), x: 175, }, Action::EnemyShield { amount, .. } => AnimationState::EnemyShield { amount, frame: 0 }, @@ -383,7 +383,7 @@ impl<'a> AnimationStateHolder<'a> { fn update( &mut self, objs: &mut BattleScreenDisplayObjects<'a>, - obj: &'a ObjectController, + obj: &'a OAMManager, current_battle_state: &CurrentBattleState, ) -> AnimationUpdateState { match &mut self.state { @@ -414,7 +414,7 @@ impl<'a> AnimationStateHolder<'a> { for i in current_player_shields..*amount { objs.player_shield[i as usize] .show() - .set_sprite(obj.sprite(SHIELD.sprite(3 - *frame / 2))); + .set_sprite(obj.get_vram_sprite(SHIELD.sprite(3 - *frame / 2))); } } else { return AnimationUpdateState::RemoveWithAction(self.action.clone()); @@ -445,7 +445,7 @@ impl<'a> AnimationStateHolder<'a> { for i in current_enemy_shields..*amount { objs.enemy_shield[i as usize] .show() - .set_sprite(obj.sprite(SHIELD.sprite(3 - *frame / 2))); + .set_sprite(obj.get_vram_sprite(SHIELD.sprite(3 - *frame / 2))); } } else { return AnimationUpdateState::RemoveWithAction(self.action.clone()); @@ -468,7 +468,7 @@ impl<'a> AnimationStateHolder<'a> { AnimationState::PlayerBurstShield { frame } => { if *frame < 10 { for shield in objs.player_shield.iter_mut() { - shield.set_sprite(obj.sprite(SHIELD.sprite(*frame / 2))); + shield.set_sprite(obj.get_vram_sprite(SHIELD.sprite(*frame / 2))); } *frame += 1; @@ -476,7 +476,7 @@ impl<'a> AnimationStateHolder<'a> { AnimationUpdateState::Continue } else { for shield in objs.player_shield.iter_mut() { - shield.set_sprite(obj.sprite(SHIELD.sprite(0))); + shield.set_sprite(obj.get_vram_sprite(SHIELD.sprite(0))); } AnimationUpdateState::RemoveWithAction(self.action.clone()) diff --git a/examples/hyperspace-roll/src/customise.rs b/examples/hyperspace-roll/src/customise.rs index 407797af..5e02580d 100644 --- a/examples/hyperspace-roll/src/customise.rs +++ b/examples/hyperspace-roll/src/customise.rs @@ -1,6 +1,6 @@ use agb::{ display::{ - object::{Object, ObjectController}, + object::{OAMManager, Object}, tiled::{RegularMap, TiledMap}, HEIGHT, WIDTH, }, @@ -91,10 +91,10 @@ fn move_net_position_ud(idx: usize, direction: Tri) -> usize { } } -fn create_dice_display<'a>(gfx: &'a ObjectController, dice: &'_ PlayerDice) -> Vec> { +fn create_dice_display<'a>(gfx: &'a OAMManager, dice: &'_ PlayerDice) -> Vec> { let mut objects = Vec::new(); for (idx, dice) in dice.dice.iter().enumerate() { - let mut obj = gfx.object(gfx.sprite(FACE_SPRITES.sprite_for_face(dice.faces[1]))); + let mut obj = gfx.add_object_static_sprite(FACE_SPRITES.sprite_for_face(dice.faces[1])); obj.set_x((idx as i32 * 32 - 24 / 2 + 20) as u16); obj.set_y(16 - 24 / 2); @@ -105,10 +105,10 @@ fn create_dice_display<'a>(gfx: &'a ObjectController, dice: &'_ PlayerDice) -> V objects } -fn create_net<'a>(gfx: &'a ObjectController, die: &'_ Die, modified: &[usize]) -> Vec> { +fn create_net<'a>(gfx: &'a OAMManager, die: &'_ Die, modified: &[usize]) -> Vec> { let mut objects = Vec::new(); for (idx, &face) in die.faces.iter().enumerate() { - let mut obj = gfx.object(gfx.sprite(FACE_SPRITES.sprite_for_face(face))); + let mut obj = gfx.add_object_static_sprite(FACE_SPRITES.sprite_for_face(face)); let (x, y) = screen_position_for_index(idx); obj.set_x((x - 24 / 2) as u16); obj.set_y((y - 24 / 2) as u16); @@ -119,7 +119,7 @@ fn create_net<'a>(gfx: &'a ObjectController, die: &'_ Die, modified: &[usize]) - } for &m in modified.iter().chain(core::iter::once(&3)) { - let mut obj = gfx.object(gfx.sprite(MODIFIED_BOX)); + let mut obj = gfx.add_object_static_sprite(MODIFIED_BOX); let (x, y) = screen_position_for_index(m); obj.set_x((x - 32 / 2) as u16); obj.set_y((y - 32 / 2) as u16); @@ -139,10 +139,10 @@ fn upgrade_position(idx: usize) -> (u32, u32) { ) } -fn create_upgrade_objects<'a>(gfx: &'a ObjectController, upgrades: &[Face]) -> Vec> { +fn create_upgrade_objects<'a>(gfx: &'a OAMManager, upgrades: &[Face]) -> Vec> { let mut objects = Vec::new(); for (idx, &upgrade) in upgrades.iter().enumerate() { - let mut obj = gfx.object(gfx.sprite(FACE_SPRITES.sprite_for_face(upgrade))); + let mut obj = gfx.add_object_static_sprite(FACE_SPRITES.sprite_for_face(upgrade)); let (x, y) = upgrade_position(idx); obj.set_x((x - 24 / 2) as u16); obj.set_y((y - 24 / 2) as u16); @@ -180,13 +180,13 @@ pub(crate) fn customise_screen( let mut input = agb::input::ButtonController::new(); - let mut select_box = agb.obj.object(agb.obj.sprite(SELECT_BOX.sprite(0))); + let mut select_box = agb.obj.add_object_static_sprite(SELECT_BOX.sprite(0)); select_box.show(); - let mut selected_dice = agb.obj.object(agb.obj.sprite(SELECTED_BOX)); + let mut selected_dice = agb.obj.add_object_static_sprite(SELECTED_BOX); selected_dice.hide(); - let mut selected_face = agb.obj.object(agb.obj.sprite(SELECTED_BOX)); + let mut selected_face = agb.obj.add_object_static_sprite(SELECTED_BOX); selected_face.hide(); agb.sfx.frame(); @@ -338,7 +338,10 @@ pub(crate) fn customise_screen( break; } - select_box.set_sprite(agb.obj.sprite(SELECT_BOX.animation_sprite(counter / 10))); + select_box.set_sprite( + agb.obj + .get_vram_sprite(SELECT_BOX.animation_sprite(counter / 10)), + ); agb.star_background.update(); let _ = agb::rng::gen(); diff --git a/examples/hyperspace-roll/src/graphics.rs b/examples/hyperspace-roll/src/graphics.rs index 8a3f54ad..88bad3ee 100644 --- a/examples/hyperspace-roll/src/graphics.rs +++ b/examples/hyperspace-roll/src/graphics.rs @@ -1,5 +1,5 @@ use agb::{ - display::object::{Object, ObjectController, Sprite, Tag}, + display::object::{OAMManager, Object, Sprite, Tag}, fixnum::Vector2D, }; use alloc::vec::Vec; @@ -141,14 +141,12 @@ pub struct HealthBar<'a> { } impl<'a> HealthBar<'a> { - pub fn new(pos: Vector2D, max: usize, obj: &'a ObjectController) -> Self { + pub fn new(pos: Vector2D, max: usize, obj: &'a OAMManager) -> Self { assert_eq!(max % 8, 0); let sprites = (0..(max / 8)) .map(|i| { - let health_sprite = obj.sprite(SMALL_SPRITES.red_bar(0)); - - let mut health_object = obj.object(health_sprite); + let mut health_object = obj.add_object_static_sprite(SMALL_SPRITES.red_bar(0)); health_object .set_position(pos + (i as i32 * 8, 0).into()) .show(); @@ -159,16 +157,18 @@ impl<'a> HealthBar<'a> { Self { max, sprites } } - pub fn set_value(&mut self, new_value: usize, obj: &'a ObjectController) { + pub fn set_value(&mut self, new_value: usize, obj: &'a OAMManager) { assert!(new_value <= self.max); for (i, sprite) in self.sprites.iter_mut().enumerate() { if (i + 1) * 8 < new_value { - sprite.set_sprite(obj.sprite(SMALL_SPRITES.red_bar(0))); + sprite.set_sprite(obj.get_vram_sprite(SMALL_SPRITES.red_bar(0))); } else if i * 8 < new_value { - sprite.set_sprite(obj.sprite(SMALL_SPRITES.red_bar(8 - (new_value - i * 8)))); + sprite.set_sprite( + obj.get_vram_sprite(SMALL_SPRITES.red_bar(8 - (new_value - i * 8))), + ); } else { - sprite.set_sprite(obj.sprite(SMALL_SPRITES.red_bar(8))); + sprite.set_sprite(obj.get_vram_sprite(SMALL_SPRITES.red_bar(8))); } } } @@ -195,22 +195,22 @@ pub struct FractionDisplay<'a> { } impl<'a> FractionDisplay<'a> { - pub fn new(pos: Vector2D, digits: usize, obj: &'a ObjectController) -> Self { + pub fn new(pos: Vector2D, digits: usize, obj: &'a OAMManager) -> Self { let mut sprites = Vec::with_capacity(digits * 2 + 1); for i in 0..digits { - let mut left_digit = obj.object(obj.sprite(SMALL_SPRITES.number(0))); + let mut left_digit = obj.add_object_static_sprite(SMALL_SPRITES.number(0)); left_digit.set_position(pos + (i as i32 * 4, 0).into()); sprites.push(left_digit); - let mut right_digit = obj.object(obj.sprite(SMALL_SPRITES.number(0))); + let mut right_digit = obj.add_object_static_sprite(SMALL_SPRITES.number(0)); right_digit.set_position(pos + (i as i32 * 4 + digits as i32 * 4 + 7, 0).into()); sprites.push(right_digit); } - let mut slash = obj.object(obj.sprite(SMALL_SPRITES.slash())); + let mut slash = obj.add_object_static_sprite(SMALL_SPRITES.slash()); slash.set_position(pos + (digits as i32 * 4 + 1, 0).into()); sprites.push(slash); @@ -222,7 +222,7 @@ impl<'a> FractionDisplay<'a> { } } - pub fn set_value(&mut self, current: usize, max: usize, obj: &'a ObjectController) { + pub fn set_value(&mut self, current: usize, max: usize, obj: &'a OAMManager) { if self.current_current == current && self.current_max == max { return; } @@ -235,12 +235,13 @@ impl<'a> FractionDisplay<'a> { current /= 10; let current_value_sprite = &mut self.sprites[(self.digits - i) * 2 - 2]; current_value_sprite - .set_sprite(obj.sprite(SMALL_SPRITES.number(current_value_digit as u32))); + .set_sprite(obj.get_vram_sprite(SMALL_SPRITES.number(current_value_digit as u32))); let max_value_digit = max % 10; max /= 10; let max_value_sprite = &mut self.sprites[(self.digits - i) * 2 - 1]; - max_value_sprite.set_sprite(obj.sprite(SMALL_SPRITES.number(max_value_digit as u32))); + max_value_sprite + .set_sprite(obj.get_vram_sprite(SMALL_SPRITES.number(max_value_digit as u32))); } } } @@ -260,7 +261,7 @@ impl<'a> NumberDisplay<'a> { } } - pub fn set_value(&mut self, new_value: Option, obj: &'a ObjectController) { + pub fn set_value(&mut self, new_value: Option, obj: &'a OAMManager) { if self.value == new_value { return; } @@ -271,7 +272,7 @@ impl<'a> NumberDisplay<'a> { if let Some(mut new_value) = new_value { if new_value == 0 { - let mut zero_object = obj.object(obj.sprite(SMALL_SPRITES.number(0))); + let mut zero_object = obj.add_object_static_sprite(SMALL_SPRITES.number(0)); zero_object.show().set_position(self.position); self.objects.push(zero_object); @@ -284,7 +285,7 @@ impl<'a> NumberDisplay<'a> { new_value /= 10; let mut current_value_obj = - obj.object(obj.sprite(SMALL_SPRITES.number(current_value_digit))); + obj.add_object_static_sprite(SMALL_SPRITES.number(current_value_digit)); current_value_obj .show() diff --git a/examples/hyperspace-roll/src/lib.rs b/examples/hyperspace-roll/src/lib.rs index 793eed6c..ff0bc020 100644 --- a/examples/hyperspace-roll/src/lib.rs +++ b/examples/hyperspace-roll/src/lib.rs @@ -12,7 +12,7 @@ #![cfg_attr(test, reexport_test_harness_main = "test_main")] #![cfg_attr(test, test_runner(agb::test_runner::test_runner))] -use agb::display::object::ObjectController; +use agb::display::object::OAMManager; use agb::display::tiled::{TileFormat, TiledMap, VRamManager}; use agb::display::Priority; use agb::interrupt::VBlank; @@ -90,7 +90,7 @@ pub struct PlayerDice { } struct Agb<'a> { - obj: ObjectController<'a>, + obj: OAMManager<'a>, vblank: VBlank, star_background: StarBackground<'a>, vram: VRamManager, @@ -104,7 +104,7 @@ pub fn main(mut gba: agb::Gba) -> ! { save::save_high_score(&mut gba.save, 0).expect("Could not reset high score"); } - let gfx = gba.display.object.get(); + let gfx = gba.display.object.get_managed(); let vblank = agb::interrupt::VBlank::get(); let (tiled, mut vram) = gba.display.video.tiled0(); diff --git a/examples/the-hat-chooses-the-wizard/Cargo.lock b/examples/the-hat-chooses-the-wizard/Cargo.lock index 44a85826..1ebec2ad 100644 --- a/examples/the-hat-chooses-the-wizard/Cargo.lock +++ b/examples/the-hat-chooses-the-wizard/Cargo.lock @@ -26,6 +26,7 @@ dependencies = [ "bitflags 2.0.2", "modular-bitfield", "rustc-hash", + "slotmap", ] [[package]] @@ -438,6 +439,15 @@ dependencies = [ "serde", ] +[[package]] +name = "slotmap" +version = "1.0.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e1e08e261d0e8f5c43123b7adf3e4ca1690d655377ac93a03b2c9d3e98de1342" +dependencies = [ + "version_check", +] + [[package]] name = "static_assertions" version = "1.1.0" diff --git a/examples/the-hat-chooses-the-wizard/src/enemies.rs b/examples/the-hat-chooses-the-wizard/src/enemies.rs index 223f067d..9acef75a 100644 --- a/examples/the-hat-chooses-the-wizard/src/enemies.rs +++ b/examples/the-hat-chooses-the-wizard/src/enemies.rs @@ -2,7 +2,7 @@ use crate::TAG_MAP; use super::{sfx::SfxPlayer, Entity, FixedNumberType, HatState, Level}; use agb::{ - display::object::{ObjectController, Tag}, + display::object::{OAMManager, Tag}, fixnum::Vector2D, }; @@ -35,11 +35,11 @@ pub enum EnemyUpdateState { } impl<'a> Enemy<'a> { - pub fn new_slime(object: &'a ObjectController, start_pos: Vector2D) -> Self { + pub fn new_slime(object: &'a OAMManager, start_pos: Vector2D) -> Self { Enemy::Slime(Slime::new(object, start_pos + (0, 1).into())) } - pub fn new_snail(object: &'a ObjectController, start_pos: Vector2D) -> Self { + pub fn new_snail(object: &'a OAMManager, start_pos: Vector2D) -> Self { Enemy::Snail(Snail::new(object, start_pos)) } @@ -52,7 +52,7 @@ impl<'a> Enemy<'a> { pub fn update( &mut self, - controller: &'a ObjectController, + controller: &'a OAMManager, level: &Level, player_pos: Vector2D, hat_state: HatState, @@ -94,7 +94,7 @@ struct EnemyInfo<'a> { impl<'a> EnemyInfo<'a> { fn new( - object: &'a ObjectController, + object: &'a OAMManager, start_pos: Vector2D, collision: Vector2D, ) -> Self { @@ -135,7 +135,7 @@ pub struct Slime<'a> { } impl<'a> Slime<'a> { - fn new(object: &'a ObjectController, start_pos: Vector2D) -> Self { + fn new(object: &'a OAMManager, start_pos: Vector2D) -> Self { let slime = Slime { enemy_info: EnemyInfo::new(object, start_pos, (14u16, 14u16).into()), state: SlimeState::Idle, @@ -146,7 +146,7 @@ impl<'a> Slime<'a> { fn update( &mut self, - controller: &'a ObjectController, + controller: &'a OAMManager, level: &Level, player_pos: Vector2D, hat_state: HatState, @@ -161,7 +161,7 @@ impl<'a> Slime<'a> { let offset = (timer / 16) as usize; let frame = SLIME_IDLE.animation_sprite(offset); - let sprite = controller.sprite(frame); + let sprite = controller.get_vram_sprite(frame); self.enemy_info.entity.sprite.set_sprite(sprite); @@ -201,7 +201,7 @@ impl<'a> Slime<'a> { self.state = SlimeState::Idle; } else { let frame = SLIME_JUMP.animation_sprite(offset); - let sprite = controller.sprite(frame); + let sprite = controller.get_vram_sprite(frame); self.enemy_info.entity.sprite.set_sprite(sprite); } @@ -227,7 +227,7 @@ impl<'a> Slime<'a> { } let frame = SLIME_SPLAT.animation_sprite(offset); - let sprite = controller.sprite(frame); + let sprite = controller.get_vram_sprite(frame); self.enemy_info.entity.sprite.set_sprite(sprite); } @@ -257,7 +257,7 @@ pub struct Snail<'a> { } impl<'a> Snail<'a> { - fn new(object: &'a ObjectController, start_pos: Vector2D) -> Self { + fn new(object: &'a OAMManager, start_pos: Vector2D) -> Self { let snail = Snail { enemy_info: EnemyInfo::new(object, start_pos, (16u16, 16u16).into()), state: SnailState::Idle(0), @@ -272,7 +272,7 @@ impl<'a> Snail<'a> { fn update( &mut self, - controller: &'a ObjectController, + controller: &'a OAMManager, level: &Level, player_pos: Vector2D, hat_state: HatState, @@ -298,7 +298,7 @@ impl<'a> Snail<'a> { } let frame = SNAIL_IDLE.animation_sprite(0); - let sprite = controller.sprite(frame); + let sprite = controller.get_vram_sprite(frame); self.enemy_info.entity.sprite.set_sprite(sprite); if player_has_collided { @@ -318,7 +318,7 @@ impl<'a> Snail<'a> { self.enemy_info.entity.velocity = (0, 0).into(); let frame = SNAIL_EMERGE.animation_sprite(offset); - let sprite = controller.sprite(frame); + let sprite = controller.get_vram_sprite(frame); self.enemy_info.entity.sprite.set_sprite(sprite); @@ -340,7 +340,7 @@ impl<'a> Snail<'a> { let offset = (timer - time) as usize / 8; let frame = SNAIL_MOVE.animation_sprite(offset); - let sprite = controller.sprite(frame); + let sprite = controller.get_vram_sprite(frame); self.enemy_info.entity.sprite.set_sprite(sprite); @@ -374,7 +374,7 @@ impl<'a> Snail<'a> { } let frame = SNAIL_EMERGE.animation_sprite(offset); - let sprite = controller.sprite(frame); + let sprite = controller.get_vram_sprite(frame); self.enemy_info.entity.sprite.set_sprite(sprite); self.enemy_info.entity.velocity = (0, 0).into(); @@ -403,7 +403,7 @@ impl<'a> Snail<'a> { return UpdateState::Remove; }; - let sprite = controller.sprite(frame); + let sprite = controller.get_vram_sprite(frame); self.enemy_info.entity.sprite.set_sprite(sprite); self.enemy_info.entity.velocity = (0, 0).into(); diff --git a/examples/the-hat-chooses-the-wizard/src/lib.rs b/examples/the-hat-chooses-the-wizard/src/lib.rs index cfd98e30..57117e3d 100644 --- a/examples/the-hat-chooses-the-wizard/src/lib.rs +++ b/examples/the-hat-chooses-the-wizard/src/lib.rs @@ -8,7 +8,7 @@ extern crate alloc; use agb::{ display::{ - object::{Graphics, Object, ObjectController, Tag, TagMap}, + object::{Graphics, OAMManager, Object, Tag, TagMap}, tiled::{ InfiniteScrolledMap, PartialUpdateStatus, RegularBackgroundSize, TileFormat, TileSet, TileSetting, TiledMap, VRamManager, @@ -124,12 +124,11 @@ pub struct Entity<'a> { } impl<'a> Entity<'a> { - pub fn new(object: &'a ObjectController, collision_mask: Vector2D) -> Self { - let dummy_sprite = object.sprite(WALKING.sprite(0)); - let mut sprite = object.object(dummy_sprite); - sprite.set_priority(Priority::P1); + pub fn new(object: &'a OAMManager, collision_mask: Vector2D) -> Self { + let mut dummy_object = object.add_object_static_sprite(WALKING.sprite(0)); + dummy_object.set_priority(Priority::P1); Entity { - sprite, + sprite: dummy_object, collision_mask, position: (0, 0).into(), velocity: (0, 0).into(), @@ -348,15 +347,15 @@ fn ping_pong(i: i32, n: i32) -> i32 { } impl<'a> Player<'a> { - fn new(controller: &'a ObjectController, start_position: Vector2D) -> Self { + fn new(controller: &'a OAMManager, start_position: Vector2D) -> Self { let mut wizard = Entity::new(controller, (6_u16, 14_u16).into()); let mut hat = Entity::new(controller, (6_u16, 6_u16).into()); wizard .sprite - .set_sprite(controller.sprite(HAT_SPIN_1.sprite(0))); + .set_sprite(controller.get_vram_sprite(HAT_SPIN_1.sprite(0))); hat.sprite - .set_sprite(controller.sprite(HAT_SPIN_1.sprite(0))); + .set_sprite(controller.get_vram_sprite(HAT_SPIN_1.sprite(0))); wizard.sprite.show(); hat.sprite.show(); @@ -382,7 +381,7 @@ impl<'a> Player<'a> { fn update_frame( &mut self, input: &ButtonController, - controller: &'a ObjectController, + controller: &'a OAMManager, timer: i32, level: &Level, enemies: &[enemies::Enemy], @@ -461,7 +460,7 @@ impl<'a> Player<'a> { self.wizard_frame = offset as u8; let frame = WALKING.animation_sprite(offset); - let sprite = controller.sprite(frame); + let sprite = controller.get_vram_sprite(frame); self.wizard.sprite.set_sprite(sprite); } @@ -471,7 +470,7 @@ impl<'a> Player<'a> { self.wizard_frame = 5; let frame = JUMPING.animation_sprite(0); - let sprite = controller.sprite(frame); + let sprite = controller.get_vram_sprite(frame); self.wizard.sprite.set_sprite(sprite); } else if self.wizard.velocity.y > FixedNumberType::new(1) / 16 { @@ -486,7 +485,7 @@ impl<'a> Player<'a> { self.wizard_frame = 0; let frame = FALLING.animation_sprite(offset); - let sprite = controller.sprite(frame); + let sprite = controller.get_vram_sprite(frame); self.wizard.sprite.set_sprite(sprite); } @@ -513,13 +512,13 @@ impl<'a> Player<'a> { self.wizard.sprite.set_hflip(true); self.hat .sprite - .set_sprite(controller.sprite(hat_base_tile.sprite(5))); + .set_sprite(controller.get_vram_sprite(hat_base_tile.sprite(5))); } agb::input::Tri::Positive => { self.wizard.sprite.set_hflip(false); self.hat .sprite - .set_sprite(controller.sprite(hat_base_tile.sprite(0))); + .set_sprite(controller.get_vram_sprite(hat_base_tile.sprite(0))); } _ => {} } @@ -545,7 +544,7 @@ impl<'a> Player<'a> { let hat_sprite_offset = (timer / hat_sprite_divider) as usize; self.hat.sprite.set_sprite( - controller.sprite(hat_base_tile.animation_sprite(hat_sprite_offset)), + controller.get_vram_sprite(hat_base_tile.animation_sprite(hat_sprite_offset)), ); if self.hat_slow_counter < 30 && self.hat.velocity.magnitude() < 2.into() { @@ -578,7 +577,7 @@ impl<'a> Player<'a> { } HatState::WizardTowards => { self.hat.sprite.set_sprite( - controller.sprite(hat_base_tile.animation_sprite(timer as usize / 2)), + controller.get_vram_sprite(hat_base_tile.animation_sprite(timer as usize / 2)), ); let distance_vector = self.hat.position - self.wizard.position + hat_resting_position; @@ -616,7 +615,7 @@ enum UpdateState { impl<'a, 'b> PlayingLevel<'a, 'b> { fn open_level( level: &'a Level, - object_control: &'a ObjectController, + object_control: &'a OAMManager, background: &'a mut InfiniteScrolledMap<'b>, foreground: &'a mut InfiniteScrolledMap<'b>, input: ButtonController, @@ -677,11 +676,11 @@ impl<'a, 'b> PlayingLevel<'a, 'b> { self.player.wizard.sprite.set_priority(Priority::P0); } - fn dead_update(&mut self, controller: &'a ObjectController) -> bool { + fn dead_update(&mut self, controller: &'a OAMManager) -> bool { self.timer += 1; let frame = PLAYER_DEATH.animation_sprite(self.timer as usize / 8); - let sprite = controller.sprite(frame); + let sprite = controller.get_vram_sprite(frame); self.player.wizard.velocity += (0.into(), FixedNumberType::new(1) / 32).into(); self.player.wizard.position += self.player.wizard.velocity; @@ -696,7 +695,7 @@ impl<'a, 'b> PlayingLevel<'a, 'b> { &mut self, sfx_player: &mut SfxPlayer, vram: &mut VRamManager, - controller: &'a ObjectController, + controller: &'a OAMManager, ) -> UpdateState { self.timer += 1; self.input.update(); @@ -828,7 +827,7 @@ pub fn main(mut agb: agb::Gba) -> ! { vram.set_background_palettes(tile_sheet::PALETTES); - let object = agb.display.object.get(); + let object = agb.display.object.get_managed(); let vblank = agb::interrupt::VBlank::get(); let mut current_level = 0; diff --git a/examples/the-purple-night/Cargo.lock b/examples/the-purple-night/Cargo.lock index 47cd52a5..d90f423c 100644 --- a/examples/the-purple-night/Cargo.lock +++ b/examples/the-purple-night/Cargo.lock @@ -26,6 +26,7 @@ dependencies = [ "bitflags 2.0.2", "modular-bitfield", "rustc-hash", + "slotmap", ] [[package]] @@ -457,6 +458,15 @@ dependencies = [ "serde", ] +[[package]] +name = "slotmap" +version = "1.0.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e1e08e261d0e8f5c43123b7adf3e4ca1690d655377ac93a03b2c9d3e98de1342" +dependencies = [ + "version_check", +] + [[package]] name = "static_assertions" version = "1.1.0" diff --git a/examples/the-purple-night/src/lib.rs b/examples/the-purple-night/src/lib.rs index 4325f879..9d08bf28 100644 --- a/examples/the-purple-night/src/lib.rs +++ b/examples/the-purple-night/src/lib.rs @@ -14,7 +14,7 @@ use alloc::{boxed::Box, vec::Vec}; use agb::{ display::{ - object::{Graphics, Object, ObjectController, Sprite, Tag, TagMap}, + object::{Graphics, OAMManager, Object, Sprite, Tag, TagMap}, tiled::{ InfiniteScrolledMap, RegularBackgroundSize, TileFormat, TileSet, TileSetting, VRamManager, @@ -164,9 +164,8 @@ struct Entity<'a> { } impl<'a> Entity<'a> { - fn new(object_controller: &'a ObjectController, collision_mask: Rect) -> Self { - let s = object_controller.sprite(LONG_SWORD_IDLE.sprite(0)); - let mut sprite = object_controller.object(s); + fn new(object_controller: &'a OAMManager, collision_mask: Rect) -> Self { + let mut sprite = object_controller.add_object_static_sprite(LONG_SWORD_IDLE.sprite(0)); sprite.set_priority(Priority::P1); Entity { sprite, @@ -533,12 +532,12 @@ struct Player<'a> { } impl<'a> Player<'a> { - fn new(object_controller: &'a ObjectController<'a>) -> Player { + fn new(object_controller: &'a OAMManager<'a>) -> Player { let mut entity = Entity::new( object_controller, Rect::new((0_u16, 0_u16).into(), (4_u16, 12_u16).into()), ); - let s = object_controller.sprite(LONG_SWORD_IDLE.sprite(0)); + let s = object_controller.get_vram_sprite(LONG_SWORD_IDLE.sprite(0)); entity.sprite.set_sprite(s); entity.sprite.show(); entity.position = (144, 0).into(); @@ -559,7 +558,7 @@ impl<'a> Player<'a> { fn update( &mut self, - controller: &'a ObjectController, + controller: &'a OAMManager, buttons: &ButtonController, level: &Level, sfx: &mut sfx::Sfx, @@ -590,12 +589,12 @@ impl<'a> Player<'a> { self.entity.sprite.set_hflip(self.facing == Tri::Negative); self.entity.velocity.x += self.sword.ground_walk_force() * x as i32; if self.entity.velocity.x.abs() > Number::new(1) / 10 { - let sprite = - controller.sprite(self.sword.walk_animation(self.sprite_offset)); + let sprite = controller + .get_vram_sprite(self.sword.walk_animation(self.sprite_offset)); self.entity.sprite.set_sprite(sprite); } else { - let sprite = - controller.sprite(self.sword.idle_animation(self.sprite_offset)); + let sprite = controller + .get_vram_sprite(self.sword.idle_animation(self.sprite_offset)); self.entity.sprite.set_sprite(sprite); } @@ -615,7 +614,8 @@ impl<'a> Player<'a> { let frame = self.sword.attack_frame(*a); self.fudge_factor.x = self.sword.fudge(frame) * self.facing as i32; let tag = self.sword.attack_tag(); - let sprite = controller.sprite(tag.animation_sprite(frame as usize)); + let sprite = + controller.get_vram_sprite(tag.animation_sprite(frame as usize)); self.entity.sprite.set_sprite(sprite); hurtbox = self.sword.ground_attack_hurtbox(frame); @@ -629,7 +629,8 @@ impl<'a> Player<'a> { let frame = self.sword.hold_frame(); self.fudge_factor.x = self.sword.fudge(frame) * self.facing as i32; let tag = self.sword.attack_tag(); - let sprite = controller.sprite(tag.animation_sprite(frame as usize)); + let sprite = + controller.get_vram_sprite(tag.animation_sprite(frame as usize)); self.entity.sprite.set_sprite(sprite); if *a == 0 { self.attack_timer = AttackTimer::Idle; @@ -654,7 +655,8 @@ impl<'a> Player<'a> { 2 }; let tag = self.sword.jump_tag(); - let sprite = controller.sprite(tag.animation_sprite(frame as usize)); + let sprite = + controller.get_vram_sprite(tag.animation_sprite(frame as usize)); self.entity.sprite.set_sprite(sprite); if x != Tri::Zero { @@ -676,7 +678,8 @@ impl<'a> Player<'a> { *a -= 1; let frame = self.sword.jump_attack_frame(*a); let tag = self.sword.jump_attack_tag(); - let sprite = controller.sprite(tag.animation_sprite(frame as usize)); + let sprite = + controller.get_vram_sprite(tag.animation_sprite(frame as usize)); self.entity.sprite.set_sprite(sprite); hurtbox = self.sword.air_attack_hurtbox(frame); @@ -811,7 +814,7 @@ impl BatData { fn update<'a>( &mut self, - controller: &'a ObjectController, + controller: &'a OAMManager, entity: &mut Entity<'a>, player: &Player, level: &Level, @@ -839,7 +842,7 @@ impl BatData { } let sprite = BAT_IDLE.sprite(self.sprite_offset as usize / 8); - let sprite = controller.sprite(sprite); + let sprite = controller.get_vram_sprite(sprite); entity.sprite.set_sprite(sprite); @@ -874,7 +877,7 @@ impl BatData { } let sprite = BAT_IDLE.sprite(self.sprite_offset as usize / 2); - let sprite = controller.sprite(sprite); + let sprite = controller.get_vram_sprite(sprite); entity.sprite.set_sprite(sprite); @@ -901,7 +904,7 @@ impl BatData { BatState::Dead => { const BAT_DEAD: &Tag = TAG_MAP.get("bat dead"); let sprite = BAT_DEAD.sprite(0); - let sprite = controller.sprite(sprite); + let sprite = controller.get_vram_sprite(sprite); entity.sprite.set_sprite(sprite); @@ -944,7 +947,7 @@ impl SlimeData { fn update<'a>( &mut self, - controller: &'a ObjectController, + controller: &'a OAMManager, entity: &mut Entity<'a>, player: &Player, level: &Level, @@ -969,7 +972,7 @@ impl SlimeData { const IDLE: &Tag = TAG_MAP.get("slime idle"); let sprite = IDLE.sprite(self.sprite_offset as usize / 16); - let sprite = controller.sprite(sprite); + let sprite = controller.get_vram_sprite(sprite); entity.sprite.set_sprite(sprite); @@ -1009,7 +1012,7 @@ impl SlimeData { const CHASE: &Tag = TAG_MAP.get("Slime jump"); let sprite = CHASE.sprite(frame as usize); - let sprite = controller.sprite(sprite); + let sprite = controller.get_vram_sprite(sprite); entity.sprite.set_sprite(sprite); @@ -1039,7 +1042,7 @@ impl SlimeData { if *count < 5 * 4 { const DEATH: &Tag = TAG_MAP.get("Slime death"); let sprite = DEATH.sprite(*count as usize / 4); - let sprite = controller.sprite(sprite); + let sprite = controller.get_vram_sprite(sprite); entity.sprite.set_sprite(sprite); *count += 1; @@ -1073,7 +1076,7 @@ impl MiniFlameData { fn update<'a>( &mut self, - controller: &'a ObjectController, + controller: &'a OAMManager, entity: &mut Entity<'a>, player: &Player, _level: &Level, @@ -1107,7 +1110,7 @@ impl MiniFlameData { } } else { let sprite = ANGRY.animation_sprite(self.sprite_offset as usize / 8); - let sprite = controller.sprite(sprite); + let sprite = controller.get_vram_sprite(sprite); entity.sprite.set_sprite(sprite); entity.velocity = (0.into(), Number::new(-1) / Number::new(4)).into(); @@ -1155,7 +1158,7 @@ impl MiniFlameData { } let sprite = ANGRY.animation_sprite(self.sprite_offset as usize / 2); - let sprite = controller.sprite(sprite); + let sprite = controller.get_vram_sprite(sprite); entity.sprite.set_sprite(sprite); } MiniFlameState::Dead => { @@ -1167,7 +1170,7 @@ impl MiniFlameData { const DEATH: &Tag = TAG_MAP.get("angry boss dead"); let sprite = DEATH.animation_sprite(self.sprite_offset as usize / 12); - let sprite = controller.sprite(sprite); + let sprite = controller.get_vram_sprite(sprite); entity.sprite.set_sprite(sprite); self.sprite_offset += 1; @@ -1202,7 +1205,7 @@ impl EmuData { fn update<'a>( &mut self, - controller: &'a ObjectController, + controller: &'a OAMManager, entity: &mut Entity<'a>, player: &Player, level: &Level, @@ -1228,7 +1231,7 @@ impl EmuData { const IDLE: &Tag = TAG_MAP.get("emu - idle"); let sprite = IDLE.sprite(self.sprite_offset as usize / 16); - let sprite = controller.sprite(sprite); + let sprite = controller.get_vram_sprite(sprite); entity.sprite.set_sprite(sprite); if (entity.position.y - player.entity.position.y).abs() < 10.into() { @@ -1275,7 +1278,7 @@ impl EmuData { const WALK: &Tag = TAG_MAP.get("emu-walk"); let sprite = WALK.sprite(self.sprite_offset as usize / 2); - let sprite = controller.sprite(sprite); + let sprite = controller.get_vram_sprite(sprite); entity.sprite.set_sprite(sprite); let gravity: Number = 1.into(); @@ -1330,7 +1333,7 @@ impl EmuData { const DEATH: &Tag = TAG_MAP.get("emu - die"); let sprite = DEATH.animation_sprite(self.sprite_offset as usize / 4); - let sprite = controller.sprite(sprite); + let sprite = controller.get_vram_sprite(sprite); entity.sprite.set_sprite(sprite); self.sprite_offset += 1; @@ -1375,7 +1378,7 @@ impl EnemyData { fn update<'a>( &mut self, - controller: &'a ObjectController, + controller: &'a OAMManager, entity: &mut Entity<'a>, player: &Player, level: &Level, @@ -1396,11 +1399,11 @@ struct Enemy<'a> { } impl<'a> Enemy<'a> { - fn new(object_controller: &'a ObjectController, enemy_data: EnemyData) -> Self { + fn new(object_controller: &'a OAMManager, enemy_data: EnemyData) -> Self { let mut entity = Entity::new(object_controller, enemy_data.collision_mask()); let sprite = enemy_data.sprite(); - let sprite = object_controller.sprite(sprite); + let sprite = object_controller.get_vram_sprite(sprite); entity.sprite.set_sprite(sprite); entity.sprite.show(); @@ -1410,7 +1413,7 @@ impl<'a> Enemy<'a> { fn update( &mut self, - controller: &'a ObjectController, + controller: &'a OAMManager, player: &Player, level: &Level, sfx: &mut sfx::Sfx, @@ -1441,7 +1444,7 @@ impl ParticleData { fn update<'a>( &mut self, - controller: &'a ObjectController, + controller: &'a OAMManager, entity: &mut Entity<'a>, player: &Player, _level: &Level, @@ -1454,7 +1457,7 @@ impl ParticleData { const DUST: &Tag = TAG_MAP.get("dust"); let sprite = DUST.sprite(*frame as usize / 3); - let sprite = controller.sprite(sprite); + let sprite = controller.get_vram_sprite(sprite); entity.sprite.set_sprite(sprite); @@ -1468,7 +1471,7 @@ impl ParticleData { const HEALTH: &Tag = TAG_MAP.get("Heath"); let sprite = HEALTH.animation_sprite(*frame as usize / 3); - let sprite = controller.sprite(sprite); + let sprite = controller.get_vram_sprite(sprite); entity.sprite.set_sprite(sprite); @@ -1494,7 +1497,7 @@ impl ParticleData { ParticleData::BossHealer(frame, target) => { const HEALTH: &Tag = TAG_MAP.get("Heath"); let sprite = HEALTH.animation_sprite(*frame as usize / 3); - let sprite = controller.sprite(sprite); + let sprite = controller.get_vram_sprite(sprite); entity.sprite.set_sprite(sprite); @@ -1529,7 +1532,7 @@ struct Particle<'a> { impl<'a> Particle<'a> { fn new( - object_controller: &'a ObjectController, + object_controller: &'a OAMManager, particle_data: ParticleData, position: Vector2D, ) -> Self { @@ -1548,7 +1551,7 @@ impl<'a> Particle<'a> { fn update( &mut self, - controller: &'a ObjectController, + controller: &'a OAMManager, player: &Player, level: &Level, ) -> UpdateInstruction { @@ -1575,7 +1578,7 @@ impl<'a> BossState<'a> { fn update( &mut self, enemies: &mut Arena>, - object_controller: &'a ObjectController, + object_controller: &'a OAMManager, player: &Player, sfx: &mut sfx::Sfx, ) -> BossInstruction { @@ -1610,7 +1613,7 @@ struct FollowingBoss<'a> { } impl<'a> FollowingBoss<'a> { - fn new(object_controller: &'a ObjectController, position: Vector2D) -> Self { + fn new(object_controller: &'a OAMManager, position: Vector2D) -> Self { let mut entity = Entity::new( object_controller, Rect::new((0_u16, 0_u16).into(), (0_u16, 0_u16).into()), @@ -1625,7 +1628,7 @@ impl<'a> FollowingBoss<'a> { gone: false, } } - fn update(&mut self, controller: &'a ObjectController, player: &Player) { + fn update(&mut self, controller: &'a OAMManager, player: &Player) { let difference = player.entity.position - self.entity.position; self.timer += 1; @@ -1658,7 +1661,7 @@ impl<'a> FollowingBoss<'a> { const BOSS: &Tag = TAG_MAP.get("happy boss"); let sprite = BOSS.animation_sprite(frame as usize); - let sprite = controller.sprite(sprite); + let sprite = controller.get_vram_sprite(sprite); self.entity.sprite.set_sprite(sprite); @@ -1694,7 +1697,7 @@ enum BossInstruction { } impl<'a> Boss<'a> { - fn new(object_controller: &'a ObjectController, screen_coords: Vector2D) -> Self { + fn new(object_controller: &'a OAMManager, screen_coords: Vector2D) -> Self { let mut entity = Entity::new( object_controller, Rect::new((0_u16, 0_u16).into(), (28_u16, 28_u16).into()), @@ -1713,7 +1716,7 @@ impl<'a> Boss<'a> { fn update( &mut self, enemies: &mut Arena>, - object_controller: &'a ObjectController, + object_controller: &'a OAMManager, player: &Player, sfx: &mut sfx::Sfx, ) -> BossInstruction { @@ -1794,7 +1797,7 @@ impl<'a> Boss<'a> { const BOSS: &Tag = TAG_MAP.get("Boss"); let sprite = BOSS.animation_sprite(frame as usize); - let sprite = object_controller.sprite(sprite); + let sprite = object_controller.get_vram_sprite(sprite); self.entity.sprite.set_sprite(sprite); @@ -1817,7 +1820,7 @@ impl<'a> Boss<'a> { self.entity .commit_with_size(offset + shake, (32, 32).into()); } - fn explode(&self, enemies: &mut Arena>, object_controller: &'a ObjectController) { + fn explode(&self, enemies: &mut Arena>, object_controller: &'a OAMManager) { for _ in 0..(6 - self.health) { let x_offset: Number = Number::from_raw(rng::gen()).rem_euclid(2.into()) - 1; let y_offset: Number = Number::from_raw(rng::gen()).rem_euclid(2.into()) - 1; @@ -1891,7 +1894,7 @@ impl<'a> Game<'a> { fn advance_frame( &mut self, - object_controller: &'a ObjectController, + object_controller: &'a OAMManager, vram: &mut VRamManager, sfx: &mut sfx::Sfx, ) -> GameStatus { @@ -2105,7 +2108,7 @@ impl<'a> Game<'a> { } } - fn load_enemies(&mut self, object_controller: &'a ObjectController) { + fn load_enemies(&mut self, object_controller: &'a OAMManager) { if self.slime_load < self.level.slime_spawns.len() { for (idx, slime_spawn) in self .level @@ -2175,7 +2178,7 @@ impl<'a> Game<'a> { vram.set_background_palettes(&modified_palettes); } - fn new(object: &'a ObjectController, level: Level<'a>, start_at_boss: bool) -> Self { + fn new(object: &'a OAMManager, level: Level<'a>, start_at_boss: bool) -> Self { let mut player = Player::new(object); let mut offset = (8, 8).into(); if start_at_boss { @@ -2222,7 +2225,7 @@ fn game_with_level(gba: &mut agb::Gba) { let tileset = TileSet::new(background::background.tiles, TileFormat::FourBpp); - let object = gba.display.object.get(); + let object = gba.display.object.get_managed(); let backdrop = InfiniteScrolledMap::new( background.background(