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 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 { impl FrameBuffer {
pub fn new() -> Self { pub fn new() -> Self {
let mut mailbox = Mailbox([0; 36]); let mut mailbox = Mailbox([0; 36]);
@@ -54,7 +60,7 @@ impl FrameBuffer {
mailbox.0[16] = SET_PIXEL_ORDER; mailbox.0[16] = SET_PIXEL_ORDER;
mailbox.0[17] = 4; mailbox.0[17] = 4;
mailbox.0[18] = 4; mailbox.0[18] = 4;
mailbox.0[19] = 0x1; // RGB mailbox.0[19] = 0x0; // RGB
mailbox.0[20] = SET_FB_OFFSET; mailbox.0[20] = SET_FB_OFFSET;
mailbox.0[21] = 8; 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; let offset = x + y * self.pitch;
unsafe { 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 /*Bresenham's line algorithm
TODO: check if its possible to optimize y1==y2 case 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 { if x1 == x2 {
for y in y1..=y2 { for y in y1..=y2 {
self.draw_pixel(x1, y); self.draw_pixel(x1, y, color);
} }
return; return;
} }
if (y2 as i32 - y1 as i32).abs() < (x2 as i32 - x1 as i32).abs() { if (y2 as i32 - y1 as i32).abs() < (x2 as i32 - x1 as i32).abs() {
if x1 > x2 { if x1 > x2 {
self.plot_line_low(x2, y2, x1, y1); self.plot_line_low(x2, y2, x1, y1, color);
} else { } else {
self.plot_line_low(x1, y1, x2, y2); self.plot_line_low(x1, y1, x2, y2, color);
} }
} else { } else {
if y1 > y2 { if y1 > y2 {
self.plot_line_high(x2, y2, x1, y1); self.plot_line_high(x2, y2, x1, y1, color);
} else { } 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) { pub fn draw_square(&self, x1: u32, y1: u32, x2: u32, y2: u32, color: u32) {
self.draw_line(x1, y1, x2, y1); self.draw_line(x1, y1, x2, y1, color);
self.draw_line(x1, y2, x2, y2); self.draw_line(x1, y2, x2, y2, color);
self.draw_line(x1, y1, x1, y2); self.draw_line(x1, y1, x1, y2, color);
self.draw_line(x2, y1, x2, y2); 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_start = y1;
let mut y_end = y2; let mut y_end = y2;
@@ -150,11 +156,11 @@ impl FrameBuffer {
} }
for y in y_start..=y_end { 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 dx = x2 as i32 - x1 as i32;
let mut dy = y2 as i32 - y1 as i32; let mut dy = y2 as i32 - y1 as i32;
let mut yi = 1; let mut yi = 1;
@@ -168,7 +174,7 @@ impl FrameBuffer {
} }
for x in x1..=x2 { for x in x1..=x2 {
self.draw_pixel(x, y as u32); self.draw_pixel(x, y as u32, color);
if d > 0 { if d > 0 {
y += yi; y += yi;
d += 2 * (dy - dx); 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 mut dx = x2 as i32 - x1 as i32;
let dy = y2 as i32 - y1 as i32; let dy = y2 as i32 - y1 as i32;
let mut xi: i32 = 1; let mut xi: i32 = 1;
@@ -191,7 +197,7 @@ impl FrameBuffer {
} }
for y in y1..=y2 { for y in y1..=y2 {
self.draw_pixel(x as u32, y); self.draw_pixel(x as u32, y, color);
if d > 0 { if d > 0 {
x += xi; x += xi;
d += 2 * (dx - dy); d += 2 * (dx - dy);
@@ -201,8 +207,25 @@ impl FrameBuffer {
} }
} }
pub fn draw_letter(&self, x: u32, y: u32, scale: u32) { //TODO: Scale in pixels
for (y_offset, row) in (&BASIC_LEGACY[0x70]).iter().enumerate() { 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 { for bit in 0..8 {
match row & (1 << bit) { match row & (1 << bit) {
0 => {} 0 => {}
@@ -211,11 +234,19 @@ impl FrameBuffer {
y + (y_offset as u32 * scale), y + (y_offset as u32 * scale),
x + ((bit + 1) * scale), x + ((bit + 1) * scale),
y + ((y_offset + 1) as u32 * 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() { pub fn print_display_resolution() {

View File

@@ -9,7 +9,7 @@ use core::{
}; };
use nova::{ use nova::{
framebuffer::{print_display_resolution, FrameBuffer}, framebuffer::{print_display_resolution, FrameBuffer, BLUE, GREEN, ORANGE, RED, YELLOW},
irq_interrupt::enable_irq_source, irq_interrupt::enable_irq_source,
mailbox::read_soc_temp, mailbox::read_soc_temp,
math::polar_to_cartesian, math::polar_to_cartesian,
@@ -100,14 +100,26 @@ pub extern "C" fn kernel_main() -> ! {
for a in 0..360 { for a in 0..360 {
let (x, y) = polar_to_cartesian(100.0, a as f32); 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(500, 500, 600, 700, RED);
fb.draw_square_fill(800, 800, 900, 900); fb.draw_square_fill(800, 800, 900, 900, GREEN);
fb.draw_square_fill(1000, 800, 1200, 700); fb.draw_square_fill(1000, 800, 1200, 700, BLUE);
fb.draw_square_fill(900, 100, 800, 150); fb.draw_square_fill(900, 100, 800, 150, RED | BLUE);
fb.draw_letter(500, 5, 4); 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 { loop {
let temp = read_soc_temp(); 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 { pub fn get_current_el() -> u64 {
let el: u64; let el: u64;
unsafe { unsafe {