1use crate::memory_mapped::MemoryMapped;
2
3use bilge::prelude::*;
4use bitflags::bitflags;
5
6use video::Video;
7
8use self::{
9 blend::Blend,
10 object::{initilise_oam, OamManaged, OamUnmanaged, SpriteLoader},
11 window::Windows,
12};
13
14pub mod bitmap3;
16pub mod bitmap4;
18pub mod example_logo;
20pub mod object;
21pub mod palette16;
23pub mod tile_data;
25pub mod tiled;
27pub mod video;
29
30pub mod affine;
31pub mod blend;
32pub mod window;
33
34pub mod font;
35pub use font::{Font, FontLetter};
36
37const DISPLAY_CONTROL: MemoryMapped<u16> = unsafe { MemoryMapped::new(0x0400_0000) };
38pub(crate) const DISPLAY_STATUS: MemoryMapped<u16> = unsafe { MemoryMapped::new(0x0400_0004) };
39const VCOUNT: MemoryMapped<u16> = unsafe { MemoryMapped::new(0x0400_0006) };
40
41bitflags! {
42 #[derive(PartialEq, Eq, Hash, Debug, Clone, Copy)]
43 struct GraphicsSettings: u16 {
44 const PAGE_SELECT = 1 << 0x4;
45 const OAM_HBLANK = 1 << 0x5;
46 const SPRITE1_D = 1 << 0x6;
47 const SCREEN_BLANK = 1 << 0x7;
48 const LAYER_BG0 = 1 << 0x8;
49 const LAYER_BG1 = 1 << 0x9;
50 const LAYER_BG2 = 1 << 0xA;
51 const LAYER_BG3 = 1 << 0xB;
52 const LAYER_OBJ = 1 << 0xC;
53 const WINDOW0 = 1 << 0xD;
54 const WINDOW1 = 1 << 0xE;
55 const WINDOW_OBJECT = 1 << 0xF;
56 }
57}
58
59pub const WIDTH: i32 = 240;
61pub const HEIGHT: i32 = 160;
63
64#[allow(dead_code)]
65enum DisplayMode {
66 Tiled0 = 0,
67 Tiled1 = 1,
68 Tiled2 = 2,
69 Bitmap3 = 3,
70 Bitmap4 = 4,
71 Bitmap5 = 5,
72}
73
74#[non_exhaustive]
75pub struct Display {
77 pub video: Video,
78 pub object: ObjectDistribution,
79 pub window: WindowDist,
80 pub blend: BlendDist,
81}
82
83#[non_exhaustive]
84pub struct ObjectDistribution;
85
86impl ObjectDistribution {
87 pub fn get_unmanaged(&mut self) -> (OamUnmanaged<'_>, SpriteLoader) {
88 unsafe { initilise_oam() };
89 (OamUnmanaged::new(), SpriteLoader::new())
90 }
91
92 pub fn get_managed(&mut self) -> OamManaged<'_> {
93 unsafe { initilise_oam() };
94 OamManaged::new()
95 }
96
97 #[deprecated = "use get_managed to get the managed oam instead"]
100 pub fn get(&mut self) -> OamManaged<'_> {
101 self.get_managed()
102 }
103}
104
105#[non_exhaustive]
106pub struct WindowDist;
107
108impl WindowDist {
109 pub fn get(&mut self) -> Windows<'_> {
110 Windows::new()
111 }
112}
113
114#[non_exhaustive]
115pub struct BlendDist;
116
117impl BlendDist {
118 pub fn get(&mut self) -> Blend<'_> {
119 Blend::new()
120 }
121}
122
123impl Display {
124 pub(crate) const unsafe fn new() -> Self {
125 Display {
126 video: Video,
127 object: ObjectDistribution,
128 window: WindowDist,
129 blend: BlendDist,
130 }
131 }
132}
133
134unsafe fn set_graphics_mode(mode: DisplayMode) {
135 let current = DISPLAY_CONTROL.get();
136 let current = current & (!0b111);
137 let s = current | (mode as u16 & 0b111);
138
139 let s = s & !(1 << 7);
141
142 DISPLAY_CONTROL.set(s);
143}
144
145unsafe fn set_graphics_settings(settings: GraphicsSettings) {
146 let current = DISPLAY_CONTROL.get();
147 let current = current & 0b111;
149 let s = settings.bits() | current;
150
151 DISPLAY_CONTROL.set(s);
152}
153
154pub fn busy_wait_for_vblank() {
158 while VCOUNT.get() >= 160 {}
159 while VCOUNT.get() < 160 {}
160}
161
162#[bitsize(2)]
167#[derive(FromBits, PartialEq, Eq, Clone, Copy, Debug, Default)]
168pub enum Priority {
169 #[default]
170 P0 = 0,
171 P1 = 1,
172 P2 = 2,
173 P3 = 3,
174}