From 7aa213936ee2ed8bdf60732bfacc6667637c7cbb Mon Sep 17 00:00:00 2001 From: Corwin Kuiper Date: Sun, 30 May 2021 16:58:34 +0100 Subject: [PATCH] object attributes in terms of three separate parameters --- agb/src/display/object.rs | 76 +++++++++++++++++++-------------------- 1 file changed, 38 insertions(+), 38 deletions(-) diff --git a/agb/src/display/object.rs b/agb/src/display/object.rs index d7883191..a7f1ccab 100644 --- a/agb/src/display/object.rs +++ b/agb/src/display/object.rs @@ -1,15 +1,17 @@ use super::DISPLAY_CONTROL; use crate::memory_mapped::MemoryMapped1DArray; -const OBJECT_MEMORY_STANDARD: MemoryMapped1DArray = +const OBJECT_ATTRIBUTE_MEMORY: MemoryMapped1DArray = unsafe { MemoryMapped1DArray::new(0x0700_0000) }; #[non_exhaustive] -pub struct ObjectControl {} +pub struct ObjectControl { + object_count: u8, +} pub struct ObjectStandard { attributes: ObjectAttribute, - id: usize, + id: u8, } pub enum Mode { @@ -30,7 +32,7 @@ impl ObjectStandard { pub fn set_y(&mut self, y: u8) { self.attributes.set_y(y) } - pub fn set_tile_id(&mut self, id: u32) { + pub fn set_tile_id(&mut self, id: u16) { self.attributes.set_tile_id(id) } pub fn set_hflip(&mut self, hflip: bool) { @@ -45,80 +47,78 @@ impl ObjectStandard { } pub struct ObjectAttribute { - low: u32, - high: u32, + a0: u16, + a1: u16, + a2: u16, } impl ObjectAttribute { - unsafe fn commit(&self, index: usize) { - OBJECT_MEMORY_STANDARD.set(index * 2, self.low); - // preserve top set of bits - let high_bits = OBJECT_MEMORY_STANDARD.get(index * 2 + 1); - let new_high_bits = (high_bits & !((1 << 16) - 1)) | self.high; - OBJECT_MEMORY_STANDARD.set(index * 2 + 1, new_high_bits); + unsafe fn commit(&self, index: u8) { + OBJECT_ATTRIBUTE_MEMORY.set(index as usize * 4, self.a0); + OBJECT_ATTRIBUTE_MEMORY.set(index as usize * 4 + 1, self.a1); + OBJECT_ATTRIBUTE_MEMORY.set(index as usize * 4 + 2, self.a2); } pub fn set_hflip(&mut self, hflip: bool) { - let mask = (1 << 0xC) << 16; - let attr = self.low; + let mask = 1 << 0xC; + let attr = self.a1; let attr = attr & !mask; if hflip { - self.low = attr | mask + self.a1 = attr | mask } else { - self.low = attr + self.a1 = attr } } pub fn set_x(&mut self, x: u8) { - let mask = ((1 << 8) - 1) << 16; - let attr1 = self.low; + let mask = (1 << 8) - 1; + let attr1 = self.a1; let attr_without_x = attr1 & !mask; - let attr_with_new_x = attr_without_x | ((x as u32) << 16); - self.low = attr_with_new_x; + let attr_with_new_x = attr_without_x | x as u16; + self.a1 = attr_with_new_x; } pub fn set_y(&mut self, y: u8) { let mask = (1 << 8) - 1; - let attr0 = self.low; + let attr0 = self.a0; let attr_without_y = attr0 & !mask; - let attr_with_new_y = attr_without_y | y as u32; - self.low = attr_with_new_y; + let attr_with_new_y = attr_without_y | y as u16; + self.a0 = attr_with_new_y; } - pub fn set_tile_id(&mut self, id: u32) { + pub fn set_tile_id(&mut self, id: u16) { let mask = (1 << 9) - 1; assert!(id <= mask, "tile id is greater than 9 bits"); - let attr = self.high; + let attr = self.a2; let attr = attr & !mask; let attr = attr | id; - self.high = attr; + self.a2 = attr; } pub fn set_mode(&mut self, mode: Mode) { let mask = 0b11 << 0x8; - self.low = (self.low & !mask) | ((mode as u32) << 0x8); + self.a0 = (self.a0 & !mask) | ((mode as u16) << 0x8); } } impl ObjectAttribute { fn new() -> Self { - ObjectAttribute { low: 0, high: 0 } + ObjectAttribute { + a0: 0, + a1: 0, + a2: 0, + } } } impl ObjectControl { pub(crate) fn new() -> Self { - ObjectControl {} - } - - /// # Safety - /// Temporary, do not call if you currently hold an object - pub unsafe fn clear_objects(&mut self) { let mut o = ObjectAttribute::new(); o.set_mode(Mode::Hidden); for index in 0..128 { - o.commit(index); + unsafe { o.commit(index) }; } + ObjectControl { object_count: 0 } } pub fn enable(&mut self) { @@ -133,9 +133,9 @@ impl ObjectControl { DISPLAY_CONTROL.set(disp); } - /// # Safety - /// Temporary function, you must not get multiple objects with the same id - pub unsafe fn get_object(&self, id: usize) -> ObjectStandard { + pub fn get_object(&mut self) -> ObjectStandard { + let id = self.object_count; + self.object_count += 1; assert!(id < 128, "object id must be less than 128"); ObjectStandard { attributes: ObjectAttribute::new(),