mirror of
https://github.com/italicsjenga/gba.git
synced 2024-12-23 10:51: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.
|
||||
|
||||
pub use crate::{
|
||||
asm_runtime::*, bios::*, builtin_art::*, dma::*, fixed::*, gba_cell::*,
|
||||
include_aligned_bytes, interrupts::*, keys::*, mgba::*, mmio::*, sound::*,
|
||||
timers::*, video::*, Align4,
|
||||
asm_runtime::*,
|
||||
bios::*,
|
||||
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)]
|
||||
use crate::prelude::*;
|
||||
|
||||
pub mod obj;
|
||||
|
||||
/// An RGB555 color value (packed into `u16`).
|
||||
#[derive(Debug, Clone, Copy, Default, PartialEq, Eq, PartialOrd, Ord, Hash)]
|
||||
#[repr(transparent)]
|
||||
pub struct Color(pub u16);
|
||||
#[allow(clippy::unusual_byte_groupings)]
|
||||
#[allow(missing_docs)]
|
||||
impl Color {
|
||||
pub const BLACK: Color = Color(0b0_00000_00000_00000);
|
||||
pub const RED: Color = Color(0b0_00000_00000_11111);
|
||||
|
@ -305,85 +308,3 @@ impl TextEntry {
|
|||
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