mirror of
https://github.com/italicsjenga/agb.git
synced 2024-12-24 00:31:34 +11:00
object attributes in terms of three separate parameters
This commit is contained in:
parent
c3b81a4585
commit
7aa213936e
|
@ -1,15 +1,17 @@
|
||||||
use super::DISPLAY_CONTROL;
|
use super::DISPLAY_CONTROL;
|
||||||
use crate::memory_mapped::MemoryMapped1DArray;
|
use crate::memory_mapped::MemoryMapped1DArray;
|
||||||
|
|
||||||
const OBJECT_MEMORY_STANDARD: MemoryMapped1DArray<u32, 256> =
|
const OBJECT_ATTRIBUTE_MEMORY: MemoryMapped1DArray<u16, 512> =
|
||||||
unsafe { MemoryMapped1DArray::new(0x0700_0000) };
|
unsafe { MemoryMapped1DArray::new(0x0700_0000) };
|
||||||
|
|
||||||
#[non_exhaustive]
|
#[non_exhaustive]
|
||||||
pub struct ObjectControl {}
|
pub struct ObjectControl {
|
||||||
|
object_count: u8,
|
||||||
|
}
|
||||||
|
|
||||||
pub struct ObjectStandard {
|
pub struct ObjectStandard {
|
||||||
attributes: ObjectAttribute,
|
attributes: ObjectAttribute,
|
||||||
id: usize,
|
id: u8,
|
||||||
}
|
}
|
||||||
|
|
||||||
pub enum Mode {
|
pub enum Mode {
|
||||||
|
@ -30,7 +32,7 @@ impl ObjectStandard {
|
||||||
pub fn set_y(&mut self, y: u8) {
|
pub fn set_y(&mut self, y: u8) {
|
||||||
self.attributes.set_y(y)
|
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)
|
self.attributes.set_tile_id(id)
|
||||||
}
|
}
|
||||||
pub fn set_hflip(&mut self, hflip: bool) {
|
pub fn set_hflip(&mut self, hflip: bool) {
|
||||||
|
@ -45,80 +47,78 @@ impl ObjectStandard {
|
||||||
}
|
}
|
||||||
|
|
||||||
pub struct ObjectAttribute {
|
pub struct ObjectAttribute {
|
||||||
low: u32,
|
a0: u16,
|
||||||
high: u32,
|
a1: u16,
|
||||||
|
a2: u16,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl ObjectAttribute {
|
impl ObjectAttribute {
|
||||||
unsafe fn commit(&self, index: usize) {
|
unsafe fn commit(&self, index: u8) {
|
||||||
OBJECT_MEMORY_STANDARD.set(index * 2, self.low);
|
OBJECT_ATTRIBUTE_MEMORY.set(index as usize * 4, self.a0);
|
||||||
// preserve top set of bits
|
OBJECT_ATTRIBUTE_MEMORY.set(index as usize * 4 + 1, self.a1);
|
||||||
let high_bits = OBJECT_MEMORY_STANDARD.get(index * 2 + 1);
|
OBJECT_ATTRIBUTE_MEMORY.set(index as usize * 4 + 2, self.a2);
|
||||||
let new_high_bits = (high_bits & !((1 << 16) - 1)) | self.high;
|
|
||||||
OBJECT_MEMORY_STANDARD.set(index * 2 + 1, new_high_bits);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn set_hflip(&mut self, hflip: bool) {
|
pub fn set_hflip(&mut self, hflip: bool) {
|
||||||
let mask = (1 << 0xC) << 16;
|
let mask = 1 << 0xC;
|
||||||
let attr = self.low;
|
let attr = self.a1;
|
||||||
let attr = attr & !mask;
|
let attr = attr & !mask;
|
||||||
if hflip {
|
if hflip {
|
||||||
self.low = attr | mask
|
self.a1 = attr | mask
|
||||||
} else {
|
} else {
|
||||||
self.low = attr
|
self.a1 = attr
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn set_x(&mut self, x: u8) {
|
pub fn set_x(&mut self, x: u8) {
|
||||||
let mask = ((1 << 8) - 1) << 16;
|
let mask = (1 << 8) - 1;
|
||||||
let attr1 = self.low;
|
let attr1 = self.a1;
|
||||||
let attr_without_x = attr1 & !mask;
|
let attr_without_x = attr1 & !mask;
|
||||||
let attr_with_new_x = attr_without_x | ((x as u32) << 16);
|
let attr_with_new_x = attr_without_x | x as u16;
|
||||||
self.low = attr_with_new_x;
|
self.a1 = attr_with_new_x;
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn set_y(&mut self, y: u8) {
|
pub fn set_y(&mut self, y: u8) {
|
||||||
let mask = (1 << 8) - 1;
|
let mask = (1 << 8) - 1;
|
||||||
let attr0 = self.low;
|
let attr0 = self.a0;
|
||||||
let attr_without_y = attr0 & !mask;
|
let attr_without_y = attr0 & !mask;
|
||||||
let attr_with_new_y = attr_without_y | y as u32;
|
let attr_with_new_y = attr_without_y | y as u16;
|
||||||
self.low = attr_with_new_y;
|
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;
|
let mask = (1 << 9) - 1;
|
||||||
assert!(id <= mask, "tile id is greater than 9 bits");
|
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 & !mask;
|
||||||
let attr = attr | id;
|
let attr = attr | id;
|
||||||
self.high = attr;
|
self.a2 = attr;
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn set_mode(&mut self, mode: Mode) {
|
pub fn set_mode(&mut self, mode: Mode) {
|
||||||
let mask = 0b11 << 0x8;
|
let mask = 0b11 << 0x8;
|
||||||
self.low = (self.low & !mask) | ((mode as u32) << 0x8);
|
self.a0 = (self.a0 & !mask) | ((mode as u16) << 0x8);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl ObjectAttribute {
|
impl ObjectAttribute {
|
||||||
fn new() -> Self {
|
fn new() -> Self {
|
||||||
ObjectAttribute { low: 0, high: 0 }
|
ObjectAttribute {
|
||||||
|
a0: 0,
|
||||||
|
a1: 0,
|
||||||
|
a2: 0,
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl ObjectControl {
|
impl ObjectControl {
|
||||||
pub(crate) fn new() -> Self {
|
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();
|
let mut o = ObjectAttribute::new();
|
||||||
o.set_mode(Mode::Hidden);
|
o.set_mode(Mode::Hidden);
|
||||||
for index in 0..128 {
|
for index in 0..128 {
|
||||||
o.commit(index);
|
unsafe { o.commit(index) };
|
||||||
}
|
}
|
||||||
|
ObjectControl { object_count: 0 }
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn enable(&mut self) {
|
pub fn enable(&mut self) {
|
||||||
|
@ -133,9 +133,9 @@ impl ObjectControl {
|
||||||
DISPLAY_CONTROL.set(disp);
|
DISPLAY_CONTROL.set(disp);
|
||||||
}
|
}
|
||||||
|
|
||||||
/// # Safety
|
pub fn get_object(&mut self) -> ObjectStandard {
|
||||||
/// Temporary function, you must not get multiple objects with the same id
|
let id = self.object_count;
|
||||||
pub unsafe fn get_object(&self, id: usize) -> ObjectStandard {
|
self.object_count += 1;
|
||||||
assert!(id < 128, "object id must be less than 128");
|
assert!(id < 128, "object id must be less than 128");
|
||||||
ObjectStandard {
|
ObjectStandard {
|
||||||
attributes: ObjectAttribute::new(),
|
attributes: ObjectAttribute::new(),
|
||||||
|
|
Loading…
Reference in a new issue