mirror of
https://github.com/italicsjenga/agb.git
synced 2024-12-24 00:31:34 +11:00
add documentation for object functions and structs
This commit is contained in:
parent
b023807bc0
commit
ba80dbefd1
|
@ -4,28 +4,35 @@ use crate::memory_mapped::MemoryMapped1DArray;
|
||||||
const OBJECT_ATTRIBUTE_MEMORY: MemoryMapped1DArray<u16, 512> =
|
const OBJECT_ATTRIBUTE_MEMORY: MemoryMapped1DArray<u16, 512> =
|
||||||
unsafe { MemoryMapped1DArray::new(0x0700_0000) };
|
unsafe { MemoryMapped1DArray::new(0x0700_0000) };
|
||||||
|
|
||||||
#[non_exhaustive]
|
/// Handles distributing objects and matricies along with operations that effect all objects.
|
||||||
pub struct ObjectControl {
|
pub struct ObjectControl {
|
||||||
object_count: u8,
|
object_count: u8,
|
||||||
affine_count: u8,
|
affine_count: u8,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// The standard object, without rotation.
|
||||||
pub struct ObjectStandard {
|
pub struct ObjectStandard {
|
||||||
attributes: ObjectAttribute,
|
attributes: ObjectAttribute,
|
||||||
id: u8,
|
id: u8,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// The affine object, with potential for using a transformation matrix to alter
|
||||||
|
/// how the sprite is rendered to screen.
|
||||||
pub struct ObjectAffine {
|
pub struct ObjectAffine {
|
||||||
attributes: ObjectAttribute,
|
attributes: ObjectAttribute,
|
||||||
id: u8,
|
id: u8,
|
||||||
aff_id: Option<u8>,
|
aff_id: Option<u8>,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Refers to an affine matrix in the OAM. Includes both an index and the
|
||||||
|
/// components of the affine matrix.
|
||||||
pub struct AffineMatrix {
|
pub struct AffineMatrix {
|
||||||
pub attributes: AffineMatrixAttributes,
|
pub attributes: AffineMatrixAttributes,
|
||||||
id: u8,
|
id: u8,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// The components of the affine matrix. The components are fixed point 8:8.
|
||||||
|
/// TODO is a type that can handle fixed point arithmetic.
|
||||||
pub struct AffineMatrixAttributes {
|
pub struct AffineMatrixAttributes {
|
||||||
pub p_a: i16,
|
pub p_a: i16,
|
||||||
pub p_b: i16,
|
pub p_b: i16,
|
||||||
|
@ -33,7 +40,7 @@ pub struct AffineMatrixAttributes {
|
||||||
pub p_d: i16,
|
pub p_d: i16,
|
||||||
}
|
}
|
||||||
|
|
||||||
pub enum Mode {
|
enum Mode {
|
||||||
Normal = 0,
|
Normal = 0,
|
||||||
Affine = 1,
|
Affine = 1,
|
||||||
Hidden = 2,
|
Hidden = 2,
|
||||||
|
@ -41,54 +48,71 @@ pub enum Mode {
|
||||||
}
|
}
|
||||||
|
|
||||||
impl ObjectStandard {
|
impl ObjectStandard {
|
||||||
|
/// Commits the object to OAM such that the updated version is displayed on
|
||||||
|
/// screen. Recommend to do this during VBlank.
|
||||||
pub fn commit(&self) {
|
pub fn commit(&self) {
|
||||||
unsafe { self.attributes.commit(self.id) }
|
unsafe { self.attributes.commit(self.id) }
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Sets the x coordinate of the sprite on screen.
|
||||||
pub fn set_x(&mut self, x: u8) {
|
pub fn set_x(&mut self, x: u8) {
|
||||||
self.attributes.set_x(x)
|
self.attributes.set_x(x)
|
||||||
}
|
}
|
||||||
|
/// Sets the y coordinate of the sprite on screen.
|
||||||
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)
|
||||||
}
|
}
|
||||||
|
/// Sets the index of the tile to use as the sprite. Potentially a temporary function.
|
||||||
pub fn set_tile_id(&mut self, id: u16) {
|
pub fn set_tile_id(&mut self, id: u16) {
|
||||||
self.attributes.set_tile_id(id)
|
self.attributes.set_tile_id(id)
|
||||||
}
|
}
|
||||||
|
/// Sets whether the sprite is horizontally mirrored or not.
|
||||||
pub fn set_hflip(&mut self, hflip: bool) {
|
pub fn set_hflip(&mut self, hflip: bool) {
|
||||||
self.attributes.set_hflip(hflip)
|
self.attributes.set_hflip(hflip)
|
||||||
}
|
}
|
||||||
|
/// Show the object on screen.
|
||||||
pub fn show(&mut self) {
|
pub fn show(&mut self) {
|
||||||
self.attributes.set_mode(Mode::Normal)
|
self.attributes.set_mode(Mode::Normal)
|
||||||
}
|
}
|
||||||
|
/// Hide the object and do not render.
|
||||||
pub fn hide(&mut self) {
|
pub fn hide(&mut self) {
|
||||||
self.attributes.set_mode(Mode::Hidden)
|
self.attributes.set_mode(Mode::Hidden)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl ObjectAffine {
|
impl ObjectAffine {
|
||||||
|
/// Commits the object to OAM such that the updated version is displayed on
|
||||||
|
/// screen. Recommend to do this during VBlank.
|
||||||
pub fn commit(&self) {
|
pub fn commit(&self) {
|
||||||
unsafe { self.attributes.commit(self.id) }
|
unsafe { self.attributes.commit(self.id) }
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Sets the x coordinate of the sprite on screen.
|
||||||
pub fn set_x(&mut self, x: u8) {
|
pub fn set_x(&mut self, x: u8) {
|
||||||
self.attributes.set_x(x)
|
self.attributes.set_x(x)
|
||||||
}
|
}
|
||||||
|
/// Sets the y coordinate of the sprite on screen.
|
||||||
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)
|
||||||
}
|
}
|
||||||
|
/// Sets the index of the tile to use as the sprite. Potentially a temporary function.
|
||||||
pub fn set_tile_id(&mut self, id: u16) {
|
pub fn set_tile_id(&mut self, id: u16) {
|
||||||
self.attributes.set_tile_id(id)
|
self.attributes.set_tile_id(id)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Show the object on screen. Panics if affine matrix has not been set.
|
||||||
pub fn show(&mut self) {
|
pub fn show(&mut self) {
|
||||||
if self.aff_id.is_none() {
|
if self.aff_id.is_none() {
|
||||||
panic!("affine matrix should be set")
|
panic!("affine matrix should be set")
|
||||||
}
|
}
|
||||||
self.attributes.set_mode(Mode::Affine)
|
self.attributes.set_mode(Mode::Affine)
|
||||||
}
|
}
|
||||||
|
/// Hide the object and do not render the sprite.
|
||||||
pub fn hide(&mut self) {
|
pub fn hide(&mut self) {
|
||||||
self.attributes.set_mode(Mode::Hidden)
|
self.attributes.set_mode(Mode::Hidden)
|
||||||
}
|
}
|
||||||
|
/// Sets the affine matrix to use. Changing the affine matrix will change
|
||||||
|
/// how the sprite is rendered.
|
||||||
pub fn set_affine_mat(&mut self, aff: &AffineMatrix) {
|
pub fn set_affine_mat(&mut self, aff: &AffineMatrix) {
|
||||||
self.attributes.set_affine(aff.id);
|
self.attributes.set_affine(aff.id);
|
||||||
self.aff_id = Some(aff.id);
|
self.aff_id = Some(aff.id);
|
||||||
|
@ -100,7 +124,7 @@ fn set_bits(current: u16, value: u16, length: u16, shift: u16) -> u16 {
|
||||||
(current & !(mask << shift)) | ((value & mask) << shift)
|
(current & !(mask << shift)) | ((value & mask) << shift)
|
||||||
}
|
}
|
||||||
|
|
||||||
pub struct ObjectAttribute {
|
struct ObjectAttribute {
|
||||||
a0: u16,
|
a0: u16,
|
||||||
a1: u16,
|
a1: u16,
|
||||||
a2: u16,
|
a2: u16,
|
||||||
|
@ -113,33 +137,34 @@ impl ObjectAttribute {
|
||||||
OBJECT_ATTRIBUTE_MEMORY.set(index as usize * 4 + 2, self.a2);
|
OBJECT_ATTRIBUTE_MEMORY.set(index as usize * 4 + 2, self.a2);
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn set_hflip(&mut self, hflip: bool) {
|
fn set_hflip(&mut self, hflip: bool) {
|
||||||
self.a1 = set_bits(self.a1, hflip as u16, 1, 0xC);
|
self.a1 = set_bits(self.a1, hflip as u16, 1, 0xC);
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn set_x(&mut self, x: u8) {
|
fn set_x(&mut self, x: u8) {
|
||||||
self.a1 = set_bits(self.a1, x as u16, 8, 0);
|
self.a1 = set_bits(self.a1, x as u16, 8, 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn set_y(&mut self, y: u8) {
|
fn set_y(&mut self, y: u8) {
|
||||||
self.a0 = set_bits(self.a0, y as u16, 8, 0)
|
self.a0 = set_bits(self.a0, y as u16, 8, 0)
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn set_tile_id(&mut self, id: u16) {
|
fn set_tile_id(&mut self, id: u16) {
|
||||||
self.a2 = set_bits(self.a2, id, 9, 0);
|
self.a2 = set_bits(self.a2, id, 9, 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn set_mode(&mut self, mode: Mode) {
|
fn set_mode(&mut self, mode: Mode) {
|
||||||
self.a0 = set_bits(self.a0, mode as u16, 2, 8);
|
self.a0 = set_bits(self.a0, mode as u16, 2, 8);
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn set_affine(&mut self, aff_id: u8) {
|
fn set_affine(&mut self, aff_id: u8) {
|
||||||
self.a1 = set_bits(self.a1, aff_id as u16, 5, 8);
|
self.a1 = set_bits(self.a1, aff_id as u16, 5, 8);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl AffineMatrix {
|
impl AffineMatrix {
|
||||||
#[allow(clippy::identity_op)]
|
#[allow(clippy::identity_op)]
|
||||||
|
/// Commits matrix to OAM, will cause any objects using this matrix to be updated.
|
||||||
pub fn commit(&self) {
|
pub fn commit(&self) {
|
||||||
let id = self.id as usize;
|
let id = self.id as usize;
|
||||||
OBJECT_ATTRIBUTE_MEMORY.set((id + 0) * 4 + 3, self.attributes.p_a as u16);
|
OBJECT_ATTRIBUTE_MEMORY.set((id + 0) * 4 + 3, self.attributes.p_a as u16);
|
||||||
|
@ -172,18 +197,24 @@ impl ObjectControl {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Enable objects on the GBA.
|
||||||
pub fn enable(&mut self) {
|
pub fn enable(&mut self) {
|
||||||
let disp = DISPLAY_CONTROL.get();
|
let disp = DISPLAY_CONTROL.get();
|
||||||
let disp = disp | (1 << 0x0C);
|
let disp = disp | (1 << 0x0C);
|
||||||
DISPLAY_CONTROL.set(disp);
|
DISPLAY_CONTROL.set(disp);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Disable objects, objects won't be rendered.
|
||||||
pub fn disable(&mut self) {
|
pub fn disable(&mut self) {
|
||||||
let disp = DISPLAY_CONTROL.get();
|
let disp = DISPLAY_CONTROL.get();
|
||||||
let disp = disp & !(1 << 0x0C);
|
let disp = disp & !(1 << 0x0C);
|
||||||
DISPLAY_CONTROL.set(disp);
|
DISPLAY_CONTROL.set(disp);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Get an unused standard object. Currently dropping an unused object will
|
||||||
|
/// not free this. You should either keep around all objects you need
|
||||||
|
/// forever or drop and reobtain ObjectControl. Panics if more than 128
|
||||||
|
/// objects are obtained.
|
||||||
pub fn get_object_standard(&mut self) -> ObjectStandard {
|
pub fn get_object_standard(&mut self) -> ObjectStandard {
|
||||||
let id = self.object_count;
|
let id = self.object_count;
|
||||||
self.object_count += 1;
|
self.object_count += 1;
|
||||||
|
@ -194,6 +225,10 @@ impl ObjectControl {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Get an unused affine object. Currently dropping an unused object will
|
||||||
|
/// not free this. You should either keep around all objects you need
|
||||||
|
/// forever or drop and reobtain ObjectControl. Panics if more than 128
|
||||||
|
/// objects are obtained.
|
||||||
pub fn get_object_affine(&mut self) -> ObjectAffine {
|
pub fn get_object_affine(&mut self) -> ObjectAffine {
|
||||||
let id = self.object_count;
|
let id = self.object_count;
|
||||||
self.object_count += 1;
|
self.object_count += 1;
|
||||||
|
@ -205,6 +240,10 @@ impl ObjectControl {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Get an unused affine matrix. Currently dropping an unused object will
|
||||||
|
/// not free this. You should either keep around all affine matricies you
|
||||||
|
/// need forever or drop and reobtain ObjectControl. Panics if more than 32
|
||||||
|
/// affine matricies are obtained.
|
||||||
pub fn get_affine(&mut self) -> AffineMatrix {
|
pub fn get_affine(&mut self) -> AffineMatrix {
|
||||||
let id = self.affine_count;
|
let id = self.affine_count;
|
||||||
self.affine_count += 1;
|
self.affine_count += 1;
|
||||||
|
|
Loading…
Reference in a new issue