Files
RedBear-OS/src/devices/graphical_debug/debug.rs
T
2024-07-24 17:10:35 +02:00

103 lines
2.6 KiB
Rust

use core::{cmp, ptr};
use super::Display;
static FONT: &[u8] = include_bytes!("../../../res/unifont.font");
pub struct DebugDisplay {
pub(super) display: Display,
x: usize,
y: usize,
w: usize,
h: usize,
}
impl DebugDisplay {
pub(super) fn new(display: Display) -> DebugDisplay {
let w = display.width / 8;
let h = display.height / 16;
DebugDisplay {
display,
x: 0,
y: 0,
w,
h,
}
}
fn write_char(&mut self, c: char) {
if self.x >= self.w || c == '\n' {
self.x = 0;
self.y += 1;
}
if self.y >= self.h {
let new_y = self.h - 1;
let d_y = self.y - new_y;
self.scroll(d_y * 16);
unsafe {
self.display
.sync(0, 0, self.display.width, self.display.height);
}
self.y = new_y;
}
if c != '\n' {
self.char(self.x * 8, self.y * 16, c, 0xFFFFFF);
unsafe {
self.display.sync(self.x * 8, self.y * 16, 8, 16);
}
self.x += 1;
}
}
pub fn write(&mut self, buf: &[u8]) {
for &b in buf {
self.write_char(b as char);
}
}
/// Draw a character
fn char(&mut self, x: usize, y: usize, character: char, color: u32) {
if x + 8 <= self.display.width && y + 16 <= self.display.height {
let mut dst = unsafe {
self.display
.data_mut()
.as_mut_ptr()
.add(y * self.display.stride + x)
};
let font_i = 16 * (character as usize);
if font_i + 16 <= FONT.len() {
for row in 0..16 {
let row_data = FONT[font_i + row];
for col in 0..8 {
if (row_data >> (7 - col)) & 1 == 1 {
unsafe {
*dst.add(col) = color;
}
}
}
dst = unsafe { dst.add(self.display.stride) };
}
}
}
}
/// Scroll the screen
fn scroll(&mut self, lines: usize) {
let offset = cmp::min(self.display.height, lines) * self.display.stride;
let size = (self.display.stride * self.display.height) - offset;
unsafe {
let ptr = self.display.data_mut().as_mut_ptr();
ptr::copy(ptr.add(offset), ptr, size);
ptr::write_bytes(ptr.add(size), 0, offset);
}
}
}