Compare commits

...

2 Commits

Author SHA1 Message Date
6c7c356858 Add colors and draw a rainbow 2025-07-29 21:03:05 +02:00
4e38beb87e Print String 2025-07-29 20:32:53 +02:00
2 changed files with 76 additions and 29 deletions

View File

@@ -28,6 +28,12 @@ pub struct FrameBuffer {
size: u32, //Bytes
}
pub const RED: u32 = 0x00FF0000;
pub const GREEN: u32 = 0x0000FF00;
pub const BLUE: u32 = 0x000000FF;
pub const ORANGE: u32 = 0x00FFA500;
pub const YELLOW: u32 = 0x00FFFF00;
impl FrameBuffer {
pub fn new() -> Self {
let mut mailbox = Mailbox([0; 36]);
@@ -54,7 +60,7 @@ impl FrameBuffer {
mailbox.0[16] = SET_PIXEL_ORDER;
mailbox.0[17] = 4;
mailbox.0[18] = 4;
mailbox.0[19] = 0x1; // RGB
mailbox.0[19] = 0x0; // RGB
mailbox.0[20] = SET_FB_OFFSET;
mailbox.0[21] = 8;
@@ -100,47 +106,47 @@ impl FrameBuffer {
}
}
pub fn draw_pixel(&self, x: u32, y: u32) {
pub fn draw_pixel(&self, x: u32, y: u32, color: u32) {
let offset = x + y * self.pitch;
unsafe {
write_volatile(self.start_addr.add(offset as usize), 0x00AAFFFF);
write_volatile(self.start_addr.add(offset as usize), color);
}
}
/*Bresenham's line algorithm
TODO: check if its possible to optimize y1==y2 case
*/
pub fn draw_line(&self, x1: u32, y1: u32, x2: u32, y2: u32) {
pub fn draw_line(&self, x1: u32, y1: u32, x2: u32, y2: u32, color: u32) {
if x1 == x2 {
for y in y1..=y2 {
self.draw_pixel(x1, y);
self.draw_pixel(x1, y, color);
}
return;
}
if (y2 as i32 - y1 as i32).abs() < (x2 as i32 - x1 as i32).abs() {
if x1 > x2 {
self.plot_line_low(x2, y2, x1, y1);
self.plot_line_low(x2, y2, x1, y1, color);
} else {
self.plot_line_low(x1, y1, x2, y2);
self.plot_line_low(x1, y1, x2, y2, color);
}
} else {
if y1 > y2 {
self.plot_line_high(x2, y2, x1, y1);
self.plot_line_high(x2, y2, x1, y1, color);
} else {
self.plot_line_high(x1, y1, x2, y2);
self.plot_line_high(x1, y1, x2, y2, color);
}
}
}
pub fn draw_square(&self, x1: u32, y1: u32, x2: u32, y2: u32) {
self.draw_line(x1, y1, x2, y1);
self.draw_line(x1, y2, x2, y2);
self.draw_line(x1, y1, x1, y2);
self.draw_line(x2, y1, x2, y2);
pub fn draw_square(&self, x1: u32, y1: u32, x2: u32, y2: u32, color: u32) {
self.draw_line(x1, y1, x2, y1, color);
self.draw_line(x1, y2, x2, y2, color);
self.draw_line(x1, y1, x1, y2, color);
self.draw_line(x2, y1, x2, y2, color);
}
pub fn draw_square_fill(&self, x1: u32, y1: u32, x2: u32, y2: u32) {
pub fn draw_square_fill(&self, x1: u32, y1: u32, x2: u32, y2: u32, color: u32) {
let mut y_start = y1;
let mut y_end = y2;
@@ -150,11 +156,11 @@ impl FrameBuffer {
}
for y in y_start..=y_end {
self.draw_line(x1, y, x2, y);
self.draw_line(x1, y, x2, y, color);
}
}
fn plot_line_low(&self, x1: u32, y1: u32, x2: u32, y2: u32) {
fn plot_line_low(&self, x1: u32, y1: u32, x2: u32, y2: u32, color: u32) {
let dx = x2 as i32 - x1 as i32;
let mut dy = y2 as i32 - y1 as i32;
let mut yi = 1;
@@ -168,7 +174,7 @@ impl FrameBuffer {
}
for x in x1..=x2 {
self.draw_pixel(x, y as u32);
self.draw_pixel(x, y as u32, color);
if d > 0 {
y += yi;
d += 2 * (dy - dx);
@@ -177,7 +183,7 @@ impl FrameBuffer {
}
}
}
fn plot_line_high(&self, x1: u32, y1: u32, x2: u32, y2: u32) {
fn plot_line_high(&self, x1: u32, y1: u32, x2: u32, y2: u32, color: u32) {
let mut dx = x2 as i32 - x1 as i32;
let dy = y2 as i32 - y1 as i32;
let mut xi: i32 = 1;
@@ -191,7 +197,7 @@ impl FrameBuffer {
}
for y in y1..=y2 {
self.draw_pixel(x as u32, y);
self.draw_pixel(x as u32, y, color);
if d > 0 {
x += xi;
d += 2 * (dx - dy);
@@ -201,8 +207,25 @@ impl FrameBuffer {
}
}
pub fn draw_letter(&self, x: u32, y: u32, scale: u32) {
for (y_offset, row) in (&BASIC_LEGACY[0x70]).iter().enumerate() {
//TODO: Scale in pixels
pub fn draw_string(&self, string: &str, x: u32, mut y: u32, scale: u32, color: u32) {
let mut offset = 0;
for c in string.bytes() {
match c {
b'\n' => {
y += 8 * scale;
offset = 0;
}
_ => {
self.draw_ascii(x + (offset as u32 * 8 * scale), y, c as usize, scale, color);
offset += 1
}
}
}
}
fn draw_ascii(&self, x: u32, y: u32, char: usize, scale: u32, color: u32) {
for (y_offset, row) in (&BASIC_LEGACY[char]).iter().enumerate() {
for bit in 0..8 {
match row & (1 << bit) {
0 => {}
@@ -211,11 +234,19 @@ impl FrameBuffer {
y + (y_offset as u32 * scale),
x + ((bit + 1) * scale),
y + ((y_offset + 1) as u32 * scale),
color,
),
}
}
}
}
pub fn draw_function(&self, f: fn(u32) -> f64, x_offset: i32, y_offset: i32, color: u32) {
for x in 0..self.pitch as i32 {
let y = f(x as u32);
self.draw_pixel((x + x_offset) as u32, (y + y_offset as f64) as u32, color);
}
}
}
pub fn print_display_resolution() {

View File

@@ -9,7 +9,7 @@ use core::{
};
use nova::{
framebuffer::{print_display_resolution, FrameBuffer},
framebuffer::{print_display_resolution, FrameBuffer, BLUE, GREEN, ORANGE, RED, YELLOW},
irq_interrupt::enable_irq_source,
mailbox::read_soc_temp,
math::polar_to_cartesian,
@@ -100,14 +100,26 @@ pub extern "C" fn kernel_main() -> ! {
for a in 0..360 {
let (x, y) = polar_to_cartesian(100.0, a as f32);
fb.draw_line(150, 150, (150.0 + x) as u32, (150.0 + y) as u32);
fb.draw_line(
150,
150,
(150.0 + x) as u32,
(150.0 + y) as u32,
a * (0x00FFFFFF / 360),
);
}
fb.draw_square(500, 500, 600, 700);
fb.draw_square_fill(800, 800, 900, 900);
fb.draw_square_fill(1000, 800, 1200, 700);
fb.draw_square_fill(900, 100, 800, 150);
fb.draw_letter(500, 5, 4);
fb.draw_square(500, 500, 600, 700, RED);
fb.draw_square_fill(800, 800, 900, 900, GREEN);
fb.draw_square_fill(1000, 800, 1200, 700, BLUE);
fb.draw_square_fill(900, 100, 800, 150, RED | BLUE);
fb.draw_string("Hello World! :D\nTest next Line", 500, 5, 3, BLUE);
fb.draw_function(cos, 100, 101, RED);
fb.draw_function(cos, 100, 102, ORANGE);
fb.draw_function(cos, 100, 103, YELLOW);
fb.draw_function(cos, 100, 104, GREEN);
fb.draw_function(cos, 100, 105, BLUE);
loop {
let temp = read_soc_temp();
@@ -118,6 +130,10 @@ pub extern "C" fn kernel_main() -> ! {
}
}
fn cos(x: u32) -> f64 {
libm::cos(x as f64 * 0.1) * 20.0
}
pub fn get_current_el() -> u64 {
let el: u64;
unsafe {