134 lines
No EOL
3.8 KiB
Rust
134 lines
No EOL
3.8 KiB
Rust
use crate::dev::virtio::framebuffer_update;
|
|
use crate::dev::{FRAMEBUFFER_ADDR, FRAMEBUFFER_BPP, FRAMEBUFFER_HEIGHT, FRAMEBUFFER_WIDTH};
|
|
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, y: usize, chars: &[char]) {
|
|
let ogx = x;
|
|
let ogy = y;
|
|
const BYTES: [u8; 3] = FB_FG_COLOR.to_bytes();
|
|
let fbaddr = FRAMEBUFFER_ADDR.load(Ordering::Relaxed);
|
|
if fbaddr == 0 {
|
|
return;
|
|
}
|
|
let fbstride = FRAMEBUFFER_BPP.load(Ordering::Relaxed) * FRAMEBUFFER_WIDTH;
|
|
const CHAR_SIZE: usize = 16;
|
|
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 {
|
|
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;
|
|
fb.write_volatile(u32::from_ne_bytes([
|
|
0, BYTES[0], BYTES[1], BYTES[2],
|
|
]));
|
|
}
|
|
}
|
|
}
|
|
}
|
|
x += CHAR_SIZE;
|
|
}
|
|
}
|
|
|
|
framebuffer_update(
|
|
tc,
|
|
0,
|
|
0,
|
|
FRAMEBUFFER_WIDTH as u32,
|
|
FRAMEBUFFER_HEIGHT as u32,
|
|
);
|
|
}
|
|
|
|
pub fn fb_clearscreen(tc: &mut TrafficControl, send_refresh: bool) {
|
|
const BYTES: [u8; 3] = FB_BG_COLOR.to_bytes();
|
|
let fbaddr = FRAMEBUFFER_ADDR.load(Ordering::Relaxed);
|
|
if fbaddr == 0 {
|
|
return;
|
|
}
|
|
let fbstride = FRAMEBUFFER_BPP.load(Ordering::Relaxed) * FRAMEBUFFER_WIDTH;
|
|
for y in 0..FRAMEBUFFER_HEIGHT {
|
|
for x in 0..FRAMEBUFFER_WIDTH {
|
|
unsafe {
|
|
let fb = (fbaddr as *mut u8).add(((y) * fbstride) + ((x) * 4)) as *mut u32;
|
|
fb.write_volatile(u32::from_ne_bytes([0, BYTES[0], BYTES[1], BYTES[2]]));
|
|
}
|
|
}
|
|
}
|
|
if send_refresh {
|
|
framebuffer_update(
|
|
tc,
|
|
0,
|
|
0,
|
|
FRAMEBUFFER_WIDTH as u32,
|
|
FRAMEBUFFER_HEIGHT as u32,
|
|
);
|
|
}
|
|
}
|
|
|
|
pub fn fb_clear_area(tc: &mut TrafficControl, x: usize, y: usize, w: usize, h: usize) {
|
|
const BYTES: [u8; 3] = FB_BG_COLOR.to_bytes();
|
|
let fbaddr = FRAMEBUFFER_ADDR.load(Ordering::Relaxed);
|
|
if fbaddr == 0 {
|
|
return;
|
|
}
|
|
let fbstride = FRAMEBUFFER_BPP.load(Ordering::Relaxed) * FRAMEBUFFER_WIDTH;
|
|
for row in 0..h {
|
|
for col in 0..w {
|
|
unsafe {
|
|
unsafe {
|
|
let fb = (fbaddr as *mut u8).add(((y+row) * fbstride) + ((x+col) * 4)) as *mut u32;
|
|
fb.write_volatile(u32::from_ne_bytes([0, BYTES[0], BYTES[1], BYTES[2]]));
|
|
}
|
|
}
|
|
}
|
|
}
|
|
framebuffer_update(
|
|
tc,
|
|
0,
|
|
0,
|
|
FRAMEBUFFER_WIDTH as u32,
|
|
FRAMEBUFFER_HEIGHT as u32,
|
|
);
|
|
} |