vexide_graphics/
embedded_graphics.rs1use embedded_graphics_core::{pixelcolor::Rgb888, prelude::*, primitives::Rectangle};
4use vexide_devices::{display::Display, rgb::Rgb};
5
6fn rgb_into_raw(rgb: Rgb<u8>) -> u32 {
7 (u32::from(rgb.r) << 16) + (u32::from(rgb.g) << 8) + u32::from(rgb.b)
8}
9
10pub struct BrainDisplay {
13 display: Display,
14 triple_buffer:
15 [u32; Display::HORIZONTAL_RESOLUTION as usize * Display::VERTICAL_RESOLUTION as usize],
16}
17impl BrainDisplay {
18 #[must_use]
22 pub fn new(mut display: Display) -> Self {
23 display.set_render_mode(vexide_devices::display::RenderMode::DoubleBuffered);
24 Self {
25 display,
26 #[allow(clippy::large_stack_arrays)] triple_buffer: [0; Display::HORIZONTAL_RESOLUTION as usize
28 * Display::VERTICAL_RESOLUTION as usize],
29 }
30 }
31}
32impl Dimensions for BrainDisplay {
33 fn bounding_box(&self) -> Rectangle {
34 Rectangle::new(
35 Point::new(0, 0),
36 Size::new(
37 Display::HORIZONTAL_RESOLUTION as _,
38 Display::VERTICAL_RESOLUTION as _,
39 ),
40 )
41 }
42}
43impl DrawTarget for BrainDisplay {
44 type Color = Rgb888;
45
46 type Error = !;
47
48 fn draw_iter<I>(&mut self, pixels: I) -> Result<(), Self::Error>
49 where
50 I: IntoIterator<Item = Pixel<Self::Color>>,
51 {
52 pixels
53 .into_iter()
54 .map(|p| (p.0, rgb_into_raw(Rgb::new(p.1.r(), p.1.g(), p.1.b()))))
55 .for_each(|(pos, col)| {
56 self.triple_buffer
57 [pos.y as usize * Display::HORIZONTAL_RESOLUTION as usize + pos.x as usize] =
58 col;
59 });
60
61 unsafe {
62 vex_sdk::vexDisplayCopyRect(
63 0,
64 0x20,
65 Display::HORIZONTAL_RESOLUTION.into(),
66 Display::VERTICAL_RESOLUTION.into(),
67 self.triple_buffer.as_mut_ptr(),
68 Display::HORIZONTAL_RESOLUTION.into(),
69 );
70 };
71 self.display.render();
72
73 Ok(())
74 }
75}