lifeblood_os/src/dev/framebuffer/mod.rs

96 lines
2.9 KiB
Rust
Raw Normal View History

2025-09-11 16:00:04 -07:00
use crate::dev::{linebuffer_push, FRAMEBUFFER_HEIGHT, FRAMEBUFFER_WIDTH, LINEBUFFER_ADDR, LINEBUFFER_BPP};
use crate::trafficcontrol::TrafficControl;
use core::sync::atomic::Ordering;
pub mod console;
pub const VAPFONT: &[u8] = include_bytes!("./vapfont.data");
pub const VAPFONT_W: usize = 256;
pub const VAPFONT_H: usize = 112;
pub struct FBColor {
pub red: u8,
pub green: u8,
pub blue: u8,
}
pub const FB_BG_COLOR: FBColor = FBColor {
red: 216,
green: 216,
blue: 216,
};
pub const FB_FG_COLOR: FBColor = FBColor {
red: 0,
green: 0,
blue: 0,
};
impl FBColor {
#[inline]
pub const fn to_bytes(&self) -> [u8; 3] {
[self.red, self.green, self.blue]
}
}
pub fn fb_write_char_array(tc: &mut TrafficControl, mut x: usize, mut y: usize, chars: &[char]) {
const BYTES: [u8; 3] = FB_FG_COLOR.to_bytes();
2025-09-11 16:00:04 -07:00
let fbaddr = LINEBUFFER_ADDR.load(Ordering::Relaxed);
if fbaddr == 0 {
return;
}
const CHAR_SIZE: usize = 16;
let mut drew_anything = false;
2025-09-11 16:00:04 -07:00
for line in 0..FRAMEBUFFER_HEIGHT {
for c in chars {
let c = *c;
if c == ' ' {
x += CHAR_SIZE;
} else if c as u8 > 32 {
let c = c as u8 - 32;
let cx = (c % 16) as usize * CHAR_SIZE;
let cy = (c / 16) as usize * CHAR_SIZE;
for row in 0..CHAR_SIZE {
if (y+row) != line {
continue;
}
for col in 0..CHAR_SIZE {
let coff = (VAPFONT_W * (cy + row)) + (cx + col);
let draw = VAPFONT[coff / 8] & (0x80 >> (coff % 8));
if draw != 0 {
unsafe {
//let fb = (fbaddr as *mut u8).add(((y + row) * fbstride) + ((x + col) * 4)) as *mut u32;
let fb = (fbaddr as *mut u8).add((x + col) * 4) as *mut u32;
fb.write_volatile(u32::from_ne_bytes([0, BYTES[0], BYTES[1], BYTES[2]]));
drew_anything = true;
}
}
}
}
2025-09-11 16:00:04 -07:00
x += CHAR_SIZE;
}
2025-09-11 16:00:04 -07:00
}
if drew_anything {
linebuffer_push(tc, line as u32);
}
}
}
pub fn fb_clearscreen(tc: &mut TrafficControl) {
const BYTES: [u8; 3] = FB_BG_COLOR.to_bytes();
2025-09-11 16:00:04 -07:00
let fbaddr = LINEBUFFER_ADDR.load(Ordering::Relaxed);
if fbaddr == 0 {
return;
}
for y in 0..FRAMEBUFFER_HEIGHT {
for x in 0..FRAMEBUFFER_WIDTH {
unsafe {
2025-09-11 16:00:04 -07:00
//let fb = (fbaddr as *mut u8).add(((y)*fbstride) + ((x)*4)) as *mut u32;
let fb = (fbaddr as *mut u8).add(x*4) as *mut u32;
fb.write_volatile(u32::from_ne_bytes([0, BYTES[0], BYTES[1], BYTES[2]]));
}
}
2025-09-11 16:00:04 -07:00
linebuffer_push(tc, y as u32);
}
}