1use alloc::vec::Vec;
2use alloc::{boxed::Box, vec};
3
4use crate::display::object::{DynamicSprite16, PaletteVramSingle, Size, SpriteVram};
5use crate::display::{Palette16, Rgb15};
6use crate::{
7 display::{HEIGHT, WIDTH, object::Object},
8 fixnum::{Num, Vector2D, num, vec2},
9 include_colours,
10};
11
12static PALETTE: &[Rgb15] = &include_colours!("gfx/pastel.png");
13
14fn letters() -> Vec<Vec<Vector2D<Num<i32, 8>>>> {
15 vec![
16 vec![
18 (num!(0.), num!(0.)).into(),
19 (num!(1.), num!(1.)).into(),
20 (num!(2.), num!(2.)).into(),
21 (num!(3.), num!(3.)).into(),
22 (num!(0.), num!(1.)).into(),
23 (num!(0.), num!(2.)).into(),
24 (num!(0.), num!(3.)).into(),
25 (num!(3.), num!(0.)).into(),
26 (num!(3.), num!(1.)).into(),
27 (num!(3.), num!(2.)).into(),
28 (num!(3.), num!(3.)).into(),
29 ],
30 vec![
32 (num!(0.), num!(0.)).into(),
33 (num!(0.), num!(1.)).into(),
34 (num!(0.), num!(2.)).into(),
35 (num!(0.), num!(3.)).into(),
36 (num!(1.), num!(3.)).into(),
37 (num!(2.), num!(3.)).into(),
38 (num!(3.), num!(3.)).into(),
39 (num!(3.), num!(2.)).into(),
40 (num!(3.), num!(1.)).into(),
41 (num!(3.), num!(0.)).into(),
42 (num!(2.), num!(0.)).into(),
43 (num!(1.), num!(0.)).into(),
44 ],
45 vec![
47 (num!(3.), num!(0.)).into(),
48 (num!(2.), num!(0.)).into(),
49 (num!(1.), num!(0.)).into(),
50 (num!(0.), num!(0.)).into(),
51 (num!(0.), num!(1.)).into(),
52 (num!(0.), num!(2.)).into(),
53 (num!(0.), num!(3.)).into(),
54 (num!(1.), num!(3.)).into(),
55 (num!(2.), num!(3.)).into(),
56 (num!(3.), num!(3.)).into(),
57 (num!(3.), num!(2.25)).into(),
58 (num!(3.), num!(1.5)).into(),
59 (num!(2.), num!(1.5)).into(),
60 ],
61 vec![
63 (num!(0.), num!(0.)).into(),
64 (num!(0.), num!(1.)).into(),
65 (num!(0.), num!(2.)).into(),
66 (num!(0.), num!(3.)).into(),
67 (num!(3.), num!(3.)).into(),
68 (num!(3.), num!(2.)).into(),
69 (num!(3.), num!(1.)).into(),
70 (num!(3.), num!(0.)).into(),
71 (num!(2.), num!(0.)).into(),
72 (num!(1.), num!(0.)).into(),
73 (num!(1.), num!(1.5)).into(),
74 (num!(2.), num!(1.5)).into(),
75 ],
76 vec![
78 (num!(0.), num!(0.)).into(),
79 (num!(0.), num!(1.)).into(),
80 (num!(0.), num!(2.)).into(),
81 (num!(0.), num!(3.)).into(),
82 (num!(3.), num!(3.)).into(),
83 (num!(3.), num!(2.)).into(),
84 (num!(3.), num!(1.)).into(),
85 (num!(3.), num!(0.)).into(),
86 (num!(1.5), num!(1.5)).into(),
87 (num!(0.75), num!(0.75)).into(),
88 (num!(2.25), num!(0.75)).into(),
89 ],
90 vec![
92 (num!(0.), num!(0.)).into(),
93 (num!(0.), num!(1.)).into(),
94 (num!(0.), num!(2.)).into(),
95 (num!(0.), num!(3.)).into(),
96 (num!(1.), num!(3.)).into(),
97 (num!(2.), num!(3.)).into(),
98 (num!(3.), num!(3.)).into(),
99 (num!(3.), num!(0.)).into(),
100 (num!(2.), num!(0.)).into(),
101 (num!(1.), num!(0.)).into(),
102 (num!(1.), num!(1.5)).into(),
103 (num!(2.), num!(1.5)).into(),
104 ],
105 ]
106}
107
108fn generate_sprites() -> Box<[SpriteVram]> {
109 let mut sprites = Vec::new();
110
111 let palettes: Vec<PaletteVramSingle> = PALETTE
114 .chunks(15)
115 .map(|x| {
116 core::iter::once(Rgb15::BLACK)
117 .chain(x.iter().copied())
118 .chain(core::iter::repeat(Rgb15::BLACK))
119 .take(16)
120 .collect::<Vec<_>>()
121 })
122 .map(|palette| {
123 let palette = Palette16::new(palette.try_into().unwrap());
124 PaletteVramSingle::try_allocate_new(&palette).unwrap()
125 })
126 .collect();
127
128 for (palette, colour) in (0..PALETTE.len()).map(|x| (x / 15, x % 15)) {
131 let mut sprite = DynamicSprite16::new(Size::S8x8);
132 sprite.clear(colour + 1);
133 sprites.push(sprite.to_vram(palettes[palette].clone()));
134 }
135
136 sprites.into_boxed_slice()
137}
138
139pub fn no_game(mut gba: crate::Gba) -> ! {
141 let mut gfx: crate::display::Graphics<'_> = gba.graphics.get();
142
143 let squares = generate_sprites();
144
145 let mut letter_positons = Vec::new();
146
147 let square_positions = {
148 let mut s = letters();
149 for letter in s.iter_mut() {
150 letter.sort_by_key(|a| a.magnitude_squared());
151 }
152 s
153 };
154 for (letter_idx, letter_parts) in square_positions.iter().enumerate() {
155 for part in letter_parts.iter() {
156 let position = part
157 .hadamard((8, 10).into())
158 .hadamard((num!(3.) / 2, num!(3.) / 2).into());
159
160 let letter_pos = vec2(
161 60 * (1 + letter_idx as i32 - ((letter_idx >= 2) as i32 * 3)),
162 70 * ((letter_idx >= 2) as i32),
163 );
164
165 letter_positons.push(position + letter_pos.change_base());
166 }
167 }
168
169 let bottom_right = letter_positons
170 .iter()
171 .copied()
172 .max_by_key(|x| x.manhattan_distance())
173 .unwrap();
174
175 let difference = (vec2(WIDTH - 8, HEIGHT - 8).change_base() - bottom_right) / 2;
176
177 for pos in letter_positons.iter_mut() {
178 *pos += difference;
179 }
180
181 let mut time: Num<i32, 8> = num!(0.);
182 let time_delta: Num<i32, 8> = num!(0.025);
183
184 loop {
185 time += time_delta;
186 time %= 1;
187 let letters: Vec<Object> = letter_positons
188 .iter()
189 .enumerate()
190 .map(|(idx, position)| {
191 let time = time + Num::<i32, 8>::new(idx as i32) / 128;
192 (idx, *position + vec2(time.sin(), time.cos()) * 10)
193 })
194 .map(|(idx, pos)| {
195 let mut obj = Object::new(squares[idx % squares.len()].clone());
196 obj.set_pos(pos.floor());
197 obj
198 })
199 .collect();
200
201 let mut frame = gfx.frame();
202
203 for obj in letters.iter() {
204 obj.show(&mut frame);
205 }
206
207 frame.commit();
208 }
209}