rubidium/vram/mode3.rs
1#![cfg(feature = "unsafe_addresses")]
2
3use super::*;
4
5/// A ZST for namespacing VideoMode3 stuff into one place.
6///
7/// In Mode 3 the majority of VRAM is occupied with a single bitmap as large as
8/// the GBA's physical display. Each color contains a [`Color`] to display at
9/// that location in the bitmap.
10///
11/// You can access the address of a location by `row` and then `col` or by `x`
12/// and then `y`. It will give equivalent results.
13///
14/// ```rust
15/// # use rubidium::*;
16/// let p = Mode3.row(8).col(5);
17/// let q = Mode3.x(5).y(8);
18/// assert_eq!(p, q);
19/// ```
20///
21/// See Also: [`VideoMode`]
22#[derive(Debug, Clone, Copy)]
23pub struct Mode3;
24
25impl Mode3 {
26 /// In Mode3 the screen is 240 wide.
27 pub const WIDTH: usize = 240;
28
29 /// In Mode3 the screen is 160 tall.
30 pub const HEIGHT: usize = 160;
31
32 /// Index by `row` to get a particular row within the Mode 3 bitmap.
33 /// ## Panics
34 /// If the index is out of bounds.
35 #[must_use]
36 #[inline(always)]
37 pub fn row(self, row: usize) -> Mode3Row {
38 assert!(row < Mode3::HEIGHT);
39 let addr = VRAM + (row * Mode3::WIDTH * size_of::<Color>());
40 Mode3Row { addr }
41 }
42
43 /// Index by `x` to get a particular column within the Mode 3 bitmap.
44 /// ## Panics
45 /// If the index is out of bounds.
46 #[must_use]
47 #[inline(always)]
48 pub fn x(self, x: usize) -> Mode3Col {
49 assert!(x < Mode3::WIDTH);
50 let addr = VRAM + (x * size_of::<Color>());
51 Mode3Col { addr }
52 }
53}
54
55/// A particular row within the Mode 3 bitmap.
56#[derive(Debug, Clone, Copy, Default, PartialEq, Eq, PartialOrd, Ord)]
57#[repr(transparent)]
58pub struct Mode3Row {
59 addr: usize,
60}
61
62impl Mode3Row {
63 /// Index by `col` to get a location within this row.
64 /// ## Panics
65 /// If the index is out of bounds.
66 #[must_use]
67 #[inline(always)]
68 pub fn col(self, col: usize) -> SimpleVolAddr<Color> {
69 assert!(col < Mode3::WIDTH);
70 unsafe { SimpleVolAddr::new(self.addr + col * size_of::<Color>()) }
71 }
72}
73
74/// A particular column within the Mode 3 bitmap.
75#[derive(Debug, Clone, Copy, Default, PartialEq, Eq, PartialOrd, Ord)]
76#[repr(transparent)]
77pub struct Mode3Col {
78 addr: usize,
79}
80
81impl Mode3Col {
82 /// Index by `y` to get a location within this column.
83 /// ## Panics
84 /// If the index is out of bounds.
85 #[must_use]
86 #[inline(always)]
87 pub fn y(self, y: usize) -> SimpleVolAddr<Color> {
88 assert!(y < Mode3::HEIGHT);
89 unsafe {
90 SimpleVolAddr::new(self.addr + (y * Mode3::WIDTH * size_of::<Color>()))
91 }
92 }
93}
94
95// TODO: 0x0601_4000 is the start of OBJ tile memory
96// TODO: 256 tiles at 8bpp (32 bytes / tile)
97// TODO: 512 tiles at 4bpp (64 bytes / tile)