Skip to content
This repository has been archived by the owner on Jun 19, 2024. It is now read-only.

Commit

Permalink
feat: simple embedded graphics driver for the V5 display
Browse files Browse the repository at this point in the history
  • Loading branch information
Gavin-Niederman committed Mar 13, 2024
1 parent 21f45c4 commit e42fead
Show file tree
Hide file tree
Showing 2 changed files with 101 additions and 0 deletions.
19 changes: 19 additions & 0 deletions packages/pros-graphics/Cargo.toml
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
[package]
name = "pros-graphics"
version = "0.1.0"
edition = "2021"
license = "MIT"
description = "Core functionality for pros-rs"
keywords = ["PROS", "Robotics", "graphics", "vex", "v5"]
categories = [
"api-bindings",
"no-std",
"science::robotics",
]

[dependencies]
embedded-graphics-core = "0.4.0"
pros-devices = { version = "0.1.0", path = "../pros-devices" }

[lints]
workspace = true
82 changes: 82 additions & 0 deletions packages/pros-graphics/src/lib.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,82 @@
//! An embedded_graphics driver for VEX V5 Brain displays.
//! Implemented for the [`pros-rs`](https://crates.io/crates/pros) ecosystem and implemented using [pros-devices](https://crates.io/crates/pros-devices).
#![no_std]

use embedded_graphics_core::{
draw_target::DrawTarget,
geometry::{Dimensions, Point, Size},
pixelcolor::{Rgb888, RgbColor},
primitives::Rectangle,
Pixel,
};
use pros_devices::{
color::Rgb,
Screen,
};

/// An embedded_graphics driver for the Brain display
pub struct VexDisplay {
screen: Screen,
pixel_buffer: [[Rgb; Screen::HORIZONTAL_RESOLUTION as _]; Screen::VERTICAL_RESOLUTION as _],
}

impl VexDisplay {
/// Creates a new VexDisplay from a Screen
pub const fn new(screen: Screen) -> Self {
Self {
screen,
pixel_buffer: [[Rgb::new(0, 0, 0); Screen::HORIZONTAL_RESOLUTION as _];
Screen::VERTICAL_RESOLUTION as _],
}
}
}

impl From<Screen> for VexDisplay {
fn from(value: Screen) -> Self {
Self::new(value)
}
}

impl Dimensions for VexDisplay {
fn bounding_box(&self) -> Rectangle {
Rectangle::new(
Point::new(0, 0),
Size::new(
Screen::HORIZONTAL_RESOLUTION as _,
Screen::VERTICAL_RESOLUTION as _,
),
)
}
}

impl DrawTarget for VexDisplay {
type Color = Rgb888;
type Error = pros_devices::screen::ScreenError;

fn draw_iter<I>(&mut self, pixels: I) -> Result<(), Self::Error>
where
I: IntoIterator<Item = Pixel<Self::Color>>,
{
pixels
.into_iter()
.map(|pixel| (pixel.0, Rgb::new(pixel.1.r(), pixel.1.g(), pixel.1.b())))
.for_each(|(pos, color)| {
// Make sure that the coordinate is valid to index with.
if !(pos.x > Screen::HORIZONTAL_RESOLUTION as _ || pos.x < 0)
&& !(pos.y > Screen::VERTICAL_RESOLUTION as _ || pos.y < 0)
{
self.pixel_buffer[pos.y as usize][pos.x as usize] = color
}
});

self.screen.draw_buffer(
0,
0,
Screen::HORIZONTAL_RESOLUTION,
Screen::VERTICAL_RESOLUTION,
self.pixel_buffer.clone().into_iter().flatten(),
Screen::HORIZONTAL_RESOLUTION as _,
)?;
Ok(())
}
}

0 comments on commit e42fead

Please sign in to comment.