103 lines
2.6 KiB
Rust
103 lines
2.6 KiB
Rust
|
use embedded_graphics::{
|
||
|
Drawable,
|
||
|
geometry::{Point, Size},
|
||
|
mono_font::{ascii::FONT_6X10, MonoTextStyle},
|
||
|
prelude::{RgbColor},
|
||
|
primitives::rectangle::Rectangle,
|
||
|
text::{Text, Baseline},
|
||
|
draw_target::DrawTarget,
|
||
|
};
|
||
|
|
||
|
pub struct Console<const W: usize, const H: usize> {
|
||
|
array: [[char; W]; H],
|
||
|
dirty: [bool; H],
|
||
|
curline: usize,
|
||
|
curcol: usize,
|
||
|
}
|
||
|
|
||
|
impl<const W: usize, const H: usize> Console<W, H> {
|
||
|
const FONT_H: i32 = 12;
|
||
|
const FONT_W: i32 = 6;
|
||
|
|
||
|
pub fn new() -> Self {
|
||
|
Self {
|
||
|
array: [[' '; W]; H],
|
||
|
dirty: [true; H],
|
||
|
curline: 0,
|
||
|
curcol: 0,
|
||
|
}
|
||
|
}
|
||
|
|
||
|
pub fn write_char(&mut self, c: char) {
|
||
|
let mut wrapped = false;
|
||
|
if self.curcol >= W {
|
||
|
self.curcol = 0;
|
||
|
self.curline += 1;
|
||
|
}
|
||
|
if self.curline >= H {
|
||
|
self.curline = 0;
|
||
|
for i in 0..W {
|
||
|
self.array[0][i] = ' ';
|
||
|
}
|
||
|
wrapped = true;
|
||
|
}
|
||
|
|
||
|
if c == '\n' {
|
||
|
self.curline += 1;
|
||
|
self.curcol = 0;
|
||
|
} else {
|
||
|
self.array[self.curline][self.curcol] = c;
|
||
|
self.curcol += 1;
|
||
|
self.dirty[self.curline] = true;
|
||
|
}
|
||
|
|
||
|
if wrapped {
|
||
|
//self.array.rotate_left(1);
|
||
|
for i in 0..H {
|
||
|
self.dirty[i] = true;
|
||
|
}
|
||
|
for i in 1..H {
|
||
|
for j in 0..W {
|
||
|
self.array[i][j] = ' ';
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
|
||
|
pub fn blit<D, C: RgbColor>(&mut self, target: &mut D)
|
||
|
where
|
||
|
D: DrawTarget<Color=C>,
|
||
|
{
|
||
|
let style = MonoTextStyle::new(&FONT_6X10, C::WHITE);
|
||
|
for (i, dirty) in self.dirty.iter().enumerate() {
|
||
|
if !dirty {
|
||
|
continue
|
||
|
}
|
||
|
|
||
|
let mut s = heapless::String::<W>::new();
|
||
|
for c in self.array[i] {
|
||
|
s.push(c);
|
||
|
}
|
||
|
|
||
|
let tl = Point::new(0, Self::FONT_H * (i as i32));
|
||
|
let sz = Size::new((Self::FONT_W * (W as i32)) as u32, Self::FONT_H as u32);
|
||
|
let rect = Rectangle::new(tl, sz);
|
||
|
target.fill_solid(&rect, C::BLACK);
|
||
|
Text::with_baseline(&s, tl, style, Baseline::Top).draw(target);
|
||
|
}
|
||
|
for i in 0..H {
|
||
|
self.dirty[i] = false;
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
|
||
|
impl<const W: usize, const H: usize> core::fmt::Write for Console<W, H> {
|
||
|
fn write_str(&mut self, text: &str) -> core::fmt::Result {
|
||
|
for c in text.chars() {
|
||
|
self.write_char(c);
|
||
|
}
|
||
|
Ok(())
|
||
|
}
|
||
|
}
|
||
|
|