mirror of
https://github.com/italicsjenga/gba.git
synced 2024-12-24 03:11:29 +11:00
better interfaces for video modes 3/4/5
This commit is contained in:
parent
6d119969eb
commit
96fc89cdbe
74
src/mmio.rs
74
src/mmio.rs
|
@ -316,37 +316,91 @@ make_me_a_screenblock_addr!(
|
||||||
max_index: 23
|
max_index: 23
|
||||||
);
|
);
|
||||||
|
|
||||||
/// Gets the block of memory for a single scanline of the Video Mode 3 bitmap.
|
/// Video mode 3 has a single full resolution bitmap
|
||||||
|
#[derive(Debug, Clone, Copy, Default, PartialEq, Eq, PartialOrd, Ord, Hash)]
|
||||||
|
pub struct VideoMode3Bitmap;
|
||||||
|
impl VideoMode3Bitmap {
|
||||||
|
/// Gets the block of memory for a single scanline of the bitmap.
|
||||||
///
|
///
|
||||||
/// ## Panics
|
/// ## Panics
|
||||||
/// * `line` must be less than 160.
|
/// * `line` must be less than 160.
|
||||||
#[inline]
|
#[inline]
|
||||||
#[must_use]
|
#[must_use]
|
||||||
pub const fn mode3_scanline(line: usize) -> VolBlock<Color, Safe, Safe, 240> {
|
pub const fn scanline(self, line: usize) -> VolBlock<Color, Safe, Safe, 240> {
|
||||||
assert!(line < 160);
|
assert!(line < 160);
|
||||||
unsafe { VolBlock::new(0x0600_0000 + line * size_of::<[Color; 240]>()) }
|
unsafe { VolBlock::new(0x0600_0000 + line * size_of::<[Color; 240]>()) }
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Gets an individual pixel within the Video Mode 3 bitmap.
|
/// Gets an individual pixel address within the bitmap.
|
||||||
///
|
///
|
||||||
/// ## Panics
|
/// ## Panics
|
||||||
/// * `row` must be less than 160.
|
/// * `row` must be less than 160.
|
||||||
/// * `col` must be less than 240.
|
/// * `col` must be less than 240.
|
||||||
#[inline]
|
#[inline]
|
||||||
#[must_use]
|
#[must_use]
|
||||||
pub const fn mode3_row_col(row: usize, col: usize) -> VolAddress<Color, Safe, Safe> {
|
pub const fn row_col(self, row: usize, col: usize) -> VolAddress<Color, Safe, Safe> {
|
||||||
assert!(row < 160);
|
assert!(row < 160);
|
||||||
assert!(col < 240);
|
assert!(col < 240);
|
||||||
mode3_scanline(row).index(col)
|
self.scanline(row).index(col)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
def_mmio!(0x0600_0000 = MODE4_FRAME0: VolBlock<u8x2, Safe, Safe, {(240/2) * 160}>; "Mode 4 indexmap, frame 0, (240/2)x160.");
|
/// Video mode 4 has two 8bpp indexmaps.
|
||||||
def_mmio!(0x0600_A000 = MODE4_FRAME1: VolBlock<u8x2, Safe, Safe, {(240/2) * 160}>; "Mode 4 indexmap, frame 1, (240/2)x160.");
|
///
|
||||||
|
/// Because VRAM can't be written with less than `u16` at a time, the scanlines
|
||||||
|
/// here use `u8x2` to represent pixels pairs so that all the writes are at
|
||||||
|
/// least `u16` large.
|
||||||
|
#[derive(Debug, Clone, Copy, Default, PartialEq, Eq, PartialOrd, Ord, Hash)]
|
||||||
|
pub struct VideoMode4Frame(usize);
|
||||||
|
impl VideoMode4Frame {
|
||||||
|
pub const _0: Self = Self(0x0600_0000);
|
||||||
|
pub const _1: Self = Self(0x0600_A000);
|
||||||
|
|
||||||
def_mmio!(0x0600_0000 = MODE5_FRAME0: VolBlock<Color, Safe, Safe, {160 * 128}>; "Mode 5 bitmap, frame 0, 160x128.");
|
/// Gets the block of memory for a single scanline of the frame's indexmap.
|
||||||
def_mmio!(0x0600_A000 = MODE5_FRAME1: VolBlock<Color, Safe, Safe, {160 * 128}>; "Mode 5 bitmap, frame 1, 160x128.");
|
///
|
||||||
|
/// ## Panics
|
||||||
|
/// * `line` must be less than 160.
|
||||||
|
#[inline]
|
||||||
|
#[must_use]
|
||||||
|
pub const fn scanline(self, line: usize) -> VolBlock<u8x2, Safe, Safe, {240/2}> {
|
||||||
|
assert!(line < 160);
|
||||||
|
unsafe { VolBlock::new(self.0 + line * size_of::<[u8x2; 240/2]>()) }
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
def_mmio!(0x0601_0000 = OBJ_TILES: VolBlock<Tile4, Safe, Safe, 1024>; "Object tiles. In bitmap modes, only indices 512..=1023 are available.");
|
/// Video mode 5 has two reduced-resolution bitmaps.
|
||||||
|
#[derive(Debug, Clone, Copy, Default, PartialEq, Eq, PartialOrd, Ord, Hash)]
|
||||||
|
pub struct VideoMode5Frame(usize);
|
||||||
|
impl VideoMode5Frame {
|
||||||
|
pub const _0: Self = Self(0x0600_0000);
|
||||||
|
pub const _1: Self = Self(0x0600_A000);
|
||||||
|
|
||||||
|
/// Gets the block of memory for a single scanline of the frame's indexmap.
|
||||||
|
///
|
||||||
|
/// ## Panics
|
||||||
|
/// * `line` must be less than 128.
|
||||||
|
#[inline]
|
||||||
|
#[must_use]
|
||||||
|
pub const fn scanline(self, line: usize) -> VolBlock<Color, Safe, Safe, 160> {
|
||||||
|
assert!(line < 128);
|
||||||
|
unsafe { VolBlock::new(self.0 + line * size_of::<[Color; 160]>()) }
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Gets an individual pixel address within the bitmap.
|
||||||
|
///
|
||||||
|
/// ## Panics
|
||||||
|
/// * `row` must be less than 128.
|
||||||
|
/// * `col` must be less than 160.
|
||||||
|
#[inline]
|
||||||
|
#[must_use]
|
||||||
|
pub const fn row_col(self, row: usize, col: usize) -> VolAddress<Color, Safe, Safe> {
|
||||||
|
assert!(row < 128);
|
||||||
|
assert!(col < 160);
|
||||||
|
self.scanline(row).index(col)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
def_mmio!(0x0601_0000 = OBJ_TILES: VolBlock<Tile4, Safe, Safe, 1024>; "Object tiles. In video modes 3, 4, and 5 only indices 512..=1023 are available.");
|
||||||
|
|
||||||
// Object Attribute Memory (OAM)
|
// Object Attribute Memory (OAM)
|
||||||
|
|
||||||
|
|
Loading…
Reference in a new issue