mirror of
https://github.com/italicsjenga/gba.git
synced 2024-12-23 19:01:30 +11:00
breaking: put object stuff in a sub-module
This commit is contained in:
parent
b8f19602cf
commit
2ebe3cc510
|
@ -1,7 +1,19 @@
|
||||||
//! A module that just re-exports all the other modules of the crate.
|
//! A module that just re-exports all the other modules of the crate.
|
||||||
|
|
||||||
pub use crate::{
|
pub use crate::{
|
||||||
asm_runtime::*, bios::*, builtin_art::*, dma::*, fixed::*, gba_cell::*,
|
asm_runtime::*,
|
||||||
include_aligned_bytes, interrupts::*, keys::*, mgba::*, mmio::*, sound::*,
|
bios::*,
|
||||||
timers::*, video::*, Align4,
|
builtin_art::*,
|
||||||
|
dma::*,
|
||||||
|
fixed::*,
|
||||||
|
gba_cell::*,
|
||||||
|
include_aligned_bytes,
|
||||||
|
interrupts::*,
|
||||||
|
keys::*,
|
||||||
|
mgba::*,
|
||||||
|
mmio::*,
|
||||||
|
sound::*,
|
||||||
|
timers::*,
|
||||||
|
video::{obj::*, *},
|
||||||
|
Align4,
|
||||||
};
|
};
|
||||||
|
|
|
@ -103,11 +103,14 @@ use crate::macros::{
|
||||||
#[allow(unused_imports)]
|
#[allow(unused_imports)]
|
||||||
use crate::prelude::*;
|
use crate::prelude::*;
|
||||||
|
|
||||||
|
pub mod obj;
|
||||||
|
|
||||||
/// An RGB555 color value (packed into `u16`).
|
/// An RGB555 color value (packed into `u16`).
|
||||||
#[derive(Debug, Clone, Copy, Default, PartialEq, Eq, PartialOrd, Ord, Hash)]
|
#[derive(Debug, Clone, Copy, Default, PartialEq, Eq, PartialOrd, Ord, Hash)]
|
||||||
#[repr(transparent)]
|
#[repr(transparent)]
|
||||||
pub struct Color(pub u16);
|
pub struct Color(pub u16);
|
||||||
#[allow(clippy::unusual_byte_groupings)]
|
#[allow(clippy::unusual_byte_groupings)]
|
||||||
|
#[allow(missing_docs)]
|
||||||
impl Color {
|
impl Color {
|
||||||
pub const BLACK: Color = Color(0b0_00000_00000_00000);
|
pub const BLACK: Color = Color(0b0_00000_00000_00000);
|
||||||
pub const RED: Color = Color(0b0_00000_00000_11111);
|
pub const RED: Color = Color(0b0_00000_00000_11111);
|
||||||
|
@ -305,85 +308,3 @@ impl TextEntry {
|
||||||
Self(id & 0b11_1111_1111)
|
Self(id & 0b11_1111_1111)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Debug, Clone, Copy, Default, PartialEq, Eq, PartialOrd, Ord, Hash)]
|
|
||||||
#[repr(u16)]
|
|
||||||
pub enum ObjDisplayStyle {
|
|
||||||
#[default]
|
|
||||||
Normal = 0 << 8,
|
|
||||||
Affine = 1 << 8,
|
|
||||||
NotDisplayed = 2 << 8,
|
|
||||||
DoubleSizeAffine = 3 << 8,
|
|
||||||
}
|
|
||||||
|
|
||||||
#[derive(Debug, Clone, Copy, Default, PartialEq, Eq, PartialOrd, Ord, Hash)]
|
|
||||||
#[repr(u16)]
|
|
||||||
pub enum ObjDisplayMode {
|
|
||||||
#[default]
|
|
||||||
Normal = 0 << 10,
|
|
||||||
SemiTransparent = 1 << 10,
|
|
||||||
Window = 2 << 10,
|
|
||||||
}
|
|
||||||
|
|
||||||
#[derive(Debug, Clone, Copy, Default, PartialEq, Eq, PartialOrd, Ord, Hash)]
|
|
||||||
#[repr(u16)]
|
|
||||||
pub enum ObjShape {
|
|
||||||
#[default]
|
|
||||||
Square = 0 << 14,
|
|
||||||
Horizontal = 1 << 14,
|
|
||||||
Vertical = 2 << 14,
|
|
||||||
}
|
|
||||||
|
|
||||||
#[derive(Debug, Clone, Copy, Default, PartialEq, Eq, PartialOrd, Ord, Hash)]
|
|
||||||
#[repr(transparent)]
|
|
||||||
pub struct ObjAttr0(u16);
|
|
||||||
impl ObjAttr0 {
|
|
||||||
pub_const_fn_new_zeroed!();
|
|
||||||
u16_int_field!(0 - 7, y, with_y);
|
|
||||||
u16_enum_field!(8 - 9: ObjDisplayStyle, style, with_style);
|
|
||||||
u16_enum_field!(10 - 11: ObjDisplayMode, mode, with_mode);
|
|
||||||
u16_bool_field!(12, mosaic, with_mosaic);
|
|
||||||
u16_bool_field!(13, bpp8, with_bpp8);
|
|
||||||
u16_enum_field!(14 - 15: ObjShape, shape, with_shape);
|
|
||||||
}
|
|
||||||
|
|
||||||
#[derive(Debug, Clone, Copy, Default, PartialEq, Eq, PartialOrd, Ord, Hash)]
|
|
||||||
#[repr(transparent)]
|
|
||||||
pub struct ObjAttr1(u16);
|
|
||||||
impl ObjAttr1 {
|
|
||||||
pub_const_fn_new_zeroed!();
|
|
||||||
u16_int_field!(0 - 8, x, with_x);
|
|
||||||
u16_int_field!(9 - 13, affine_index, with_affine_index);
|
|
||||||
u16_bool_field!(12, hflip, with_hflip);
|
|
||||||
u16_bool_field!(13, vflip, with_vflip);
|
|
||||||
u16_int_field!(14 - 15, size, with_size);
|
|
||||||
}
|
|
||||||
|
|
||||||
#[derive(Debug, Clone, Copy, Default, PartialEq, Eq, PartialOrd, Ord, Hash)]
|
|
||||||
#[repr(transparent)]
|
|
||||||
pub struct ObjAttr2(u16);
|
|
||||||
impl ObjAttr2 {
|
|
||||||
pub_const_fn_new_zeroed!();
|
|
||||||
u16_int_field!(0 - 9, tile_id, with_tile_id);
|
|
||||||
u16_int_field!(10 - 11, priority, with_priority);
|
|
||||||
u16_int_field!(12 - 15, palbank, with_palbank);
|
|
||||||
}
|
|
||||||
|
|
||||||
#[derive(Debug, Clone, Copy, Default, PartialEq, Eq, PartialOrd, Ord, Hash)]
|
|
||||||
#[repr(C)]
|
|
||||||
pub struct ObjAttr(pub ObjAttr0, pub ObjAttr1, pub ObjAttr2);
|
|
||||||
impl ObjAttr {
|
|
||||||
#[inline]
|
|
||||||
pub const fn new() -> Self {
|
|
||||||
Self(ObjAttr0(0), ObjAttr1(0), ObjAttr2(0))
|
|
||||||
}
|
|
||||||
pub fn set_x(&mut self, x: u16) {
|
|
||||||
self.1 = self.1.with_x(x);
|
|
||||||
}
|
|
||||||
pub fn set_y(&mut self, y: u16) {
|
|
||||||
self.0 = self.0.with_y(y);
|
|
||||||
}
|
|
||||||
pub fn set_tile_id(&mut self, id: u16) {
|
|
||||||
self.2 = self.2.with_tile_id(id);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
156
src/video/obj.rs
Normal file
156
src/video/obj.rs
Normal file
|
@ -0,0 +1,156 @@
|
||||||
|
//! Module for object (OBJ) entry data.
|
||||||
|
//!
|
||||||
|
//! The GBA's object drawing allows for hardware drawing that is independent of
|
||||||
|
//! the background layers. Another common term for objects is "sprites", but
|
||||||
|
//! within the GBA community they're called objects, so this crate calls them
|
||||||
|
//! objects too.
|
||||||
|
//!
|
||||||
|
//! The GBA has 128 object entries within the Object Attribute Memory (OAM)
|
||||||
|
//! region. The object entries are also interspersed with the memory for the
|
||||||
|
//! affine entries, so OAM should not be thought of as being an array of just
|
||||||
|
//! one or the other types of data.
|
||||||
|
//!
|
||||||
|
//! A few of the GBA's controls will affect all objects at once, particularly
|
||||||
|
//! the Display Control (which can control if the objects are visible at all),
|
||||||
|
//! but in general each object can be controlled independently.
|
||||||
|
//!
|
||||||
|
//! Each object entry consists of a number of bit-packed "attributes". The
|
||||||
|
//! object's attributes are stored in three 16-bit fields. The [ObjAttr] struct
|
||||||
|
//! has one field for each 16-bit group of attributes: [ObjAttr0], [ObjAttr1],
|
||||||
|
//! [ObjAttr2].
|
||||||
|
//!
|
||||||
|
//! When you've got an object's data configured how you want, use either the
|
||||||
|
//! [`OBJ_ATTR_ALL`] control (to write all fields at once) or the [`OBJ_ATTR0`],
|
||||||
|
//! [`OBJ_ATTR1`], and/or [`OBJ_ATTR2`] controls (to write just some of the
|
||||||
|
//! fields).
|
||||||
|
//!
|
||||||
|
//! **Note:** When the GBA first boots, the object layer will be off but the
|
||||||
|
//! object entries in OAM will *not* be set to prevent individual objects from
|
||||||
|
//! being displayed. Before enabling the object layer you should generally set
|
||||||
|
//! the [ObjDisplayStyle] of all [ObjAttr0] fields so that any objects you're
|
||||||
|
//! not using don't appear on the screen. Otherwise, you'll end up with
|
||||||
|
//! un-configured objects appearing in the upper left corner of the display.
|
||||||
|
|
||||||
|
use super::*;
|
||||||
|
|
||||||
|
/// How the object should be displayed.
|
||||||
|
///
|
||||||
|
/// Bit 9 of Attr0 changes meaning depending on Bit 8, so this merges the two
|
||||||
|
/// bits into a single property.
|
||||||
|
#[derive(Debug, Clone, Copy, Default, PartialEq, Eq, PartialOrd, Ord, Hash)]
|
||||||
|
#[repr(u16)]
|
||||||
|
pub enum ObjDisplayStyle {
|
||||||
|
/// The default, non-affine display
|
||||||
|
#[default]
|
||||||
|
Normal = 0 << 8,
|
||||||
|
/// Affine display
|
||||||
|
Affine = 1 << 8,
|
||||||
|
/// The object is *not* displayed at all.
|
||||||
|
NotDisplayed = 2 << 8,
|
||||||
|
/// Shows the object using Affine style but double sized.
|
||||||
|
DoubleSizeAffine = 3 << 8,
|
||||||
|
}
|
||||||
|
|
||||||
|
/// What special effect the object interacts with
|
||||||
|
#[derive(Debug, Clone, Copy, Default, PartialEq, Eq, PartialOrd, Ord, Hash)]
|
||||||
|
#[repr(u16)]
|
||||||
|
pub enum ObjEffectMode {
|
||||||
|
/// The default, no special effect interaction
|
||||||
|
#[default]
|
||||||
|
Normal = 0 << 10,
|
||||||
|
/// The object counts as a potential 1st target for alpha blending,
|
||||||
|
/// regardless of the actual blend control settings register configuration.
|
||||||
|
SemiTransparent = 1 << 10,
|
||||||
|
/// The object is not displayed. Instead, all non-transparent pixels in this
|
||||||
|
/// object become part of the "OBJ Window" mask.
|
||||||
|
Window = 2 << 10,
|
||||||
|
}
|
||||||
|
|
||||||
|
/// The shape of an object.
|
||||||
|
///
|
||||||
|
/// The object's actual display area also depends on its `size` setting:
|
||||||
|
///
|
||||||
|
/// | Size | Square | Horizontal | Vertical |
|
||||||
|
/// |:-:|:-:|:-:|:-:|
|
||||||
|
/// | 0 | 8x8 | 16x8 | 8x16 |
|
||||||
|
/// | 1 | 16x16 | 32x8 | 8x32 |
|
||||||
|
/// | 2 | 32x32 | 32x16 | 16x32 |
|
||||||
|
/// | 3 | 64x64 | 64x32 | 32x64 |
|
||||||
|
#[derive(Debug, Clone, Copy, Default, PartialEq, Eq, PartialOrd, Ord, Hash)]
|
||||||
|
#[repr(u16)]
|
||||||
|
#[allow(missing_docs)]
|
||||||
|
pub enum ObjShape {
|
||||||
|
#[default]
|
||||||
|
Square = 0 << 14,
|
||||||
|
Horizontal = 1 << 14,
|
||||||
|
Vertical = 2 << 14,
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Object Attributes, field 0 of the entry.
|
||||||
|
#[derive(Debug, Clone, Copy, Default, PartialEq, Eq, PartialOrd, Ord, Hash)]
|
||||||
|
#[repr(transparent)]
|
||||||
|
pub struct ObjAttr0(u16);
|
||||||
|
impl ObjAttr0 {
|
||||||
|
pub_const_fn_new_zeroed!();
|
||||||
|
u16_int_field!(0 - 7, y, with_y);
|
||||||
|
u16_enum_field!(8 - 9: ObjDisplayStyle, style, with_style);
|
||||||
|
u16_enum_field!(10 - 11: ObjEffectMode, mode, with_mode);
|
||||||
|
u16_bool_field!(12, mosaic, with_mosaic);
|
||||||
|
u16_bool_field!(13, bpp8, with_bpp8);
|
||||||
|
u16_enum_field!(14 - 15: ObjShape, shape, with_shape);
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Object Attributes, field 1 of the entry.
|
||||||
|
#[derive(Debug, Clone, Copy, Default, PartialEq, Eq, PartialOrd, Ord, Hash)]
|
||||||
|
#[repr(transparent)]
|
||||||
|
pub struct ObjAttr1(u16);
|
||||||
|
impl ObjAttr1 {
|
||||||
|
pub_const_fn_new_zeroed!();
|
||||||
|
u16_int_field!(0 - 8, x, with_x);
|
||||||
|
u16_int_field!(9 - 13, affine_index, with_affine_index);
|
||||||
|
u16_bool_field!(12, hflip, with_hflip);
|
||||||
|
u16_bool_field!(13, vflip, with_vflip);
|
||||||
|
u16_int_field!(14 - 15, size, with_size);
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Object Attributes, field 2 of the entry.
|
||||||
|
#[derive(Debug, Clone, Copy, Default, PartialEq, Eq, PartialOrd, Ord, Hash)]
|
||||||
|
#[repr(transparent)]
|
||||||
|
pub struct ObjAttr2(u16);
|
||||||
|
impl ObjAttr2 {
|
||||||
|
pub_const_fn_new_zeroed!();
|
||||||
|
u16_int_field!(0 - 9, tile_id, with_tile_id);
|
||||||
|
u16_int_field!(10 - 11, priority, with_priority);
|
||||||
|
u16_int_field!(12 - 15, palbank, with_palbank);
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Object Attributes.
|
||||||
|
///
|
||||||
|
/// The fields of this struct are all `pub` so that you can simply alter them as
|
||||||
|
/// you wish. Some "setter" methods are also provided as a shorthand.
|
||||||
|
#[derive(Debug, Clone, Copy, Default, PartialEq, Eq, PartialOrd, Ord, Hash)]
|
||||||
|
#[repr(C)]
|
||||||
|
pub struct ObjAttr(pub ObjAttr0, pub ObjAttr1, pub ObjAttr2);
|
||||||
|
#[allow(missing_docs)]
|
||||||
|
impl ObjAttr {
|
||||||
|
#[inline]
|
||||||
|
pub const fn new() -> Self {
|
||||||
|
Self(ObjAttr0::new(), ObjAttr1::new(), ObjAttr2::new())
|
||||||
|
}
|
||||||
|
#[inline]
|
||||||
|
pub fn set_y(&mut self, y: u16) {
|
||||||
|
self.0 = self.0.with_y(y);
|
||||||
|
}
|
||||||
|
#[inline]
|
||||||
|
pub fn set_style(&mut self, style: ObjDisplayStyle) {
|
||||||
|
self.0 = self.0.with_style(style);
|
||||||
|
}
|
||||||
|
#[inline]
|
||||||
|
pub fn set_x(&mut self, x: u16) {
|
||||||
|
self.1 = self.1.with_x(x);
|
||||||
|
}
|
||||||
|
#[inline]
|
||||||
|
pub fn set_tile_id(&mut self, id: u16) {
|
||||||
|
self.2 = self.2.with_tile_id(id);
|
||||||
|
}
|
||||||
|
}
|
Loading…
Reference in a new issue