working on colour support
This commit is contained in:
@@ -6,7 +6,6 @@
|
||||
- Specific rustup components that can be installed with the following commands:
|
||||
> rustup component add rust-src
|
||||
> rustup component add llvm-tools-preview
|
||||
|
||||
### Building
|
||||
run the following command (in the root directory of the project)
|
||||
> ./run.sh
|
||||
|
||||
@@ -5,7 +5,7 @@ use lazy_static::lazy_static;
|
||||
use spin::{Lazy, Mutex};
|
||||
use x86_64::instructions::interrupts;
|
||||
|
||||
use lib_framebuffer::FRAMEBUFFER_WRITER;
|
||||
use lib_framebuffer::{FRAMEBUFFER_WRITER, Color};
|
||||
|
||||
mod font;
|
||||
use font::FONT;
|
||||
@@ -15,6 +15,8 @@ static FONT_HEIGHT: u32 = 16;
|
||||
|
||||
pub static WRITER: Lazy<Mutex<Writer>> = Lazy::new(|| Mutex::new(Writer::new()));
|
||||
|
||||
|
||||
|
||||
pub fn screensize_chars() -> (u32, u32) {
|
||||
let writer = WRITER.lock();
|
||||
(writer.screen_width, writer.screen_height)
|
||||
@@ -71,10 +73,10 @@ impl Writer {
|
||||
|
||||
if line & (0x80 >> col) != 0 {
|
||||
// write the foreground color
|
||||
writer.write_pixel(pixel_x as usize, pixel_y as usize, self.fg_color);
|
||||
writer.write_pixel(pixel_x as usize, pixel_y as usize, Color::RGB(255, 0, 0));
|
||||
} else {
|
||||
// write the background color
|
||||
writer.write_pixel(pixel_x as usize, pixel_y as usize, self.bg_color);
|
||||
writer.write_pixel(pixel_x as usize, pixel_y as usize, Color::HexARGB(self.bg_color));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -0,0 +1,51 @@
|
||||
#[repr(u32)]
|
||||
#[derive(Copy, Clone, PartialEq, Eq, Debug)]
|
||||
pub enum Color {
|
||||
ARGB(u8, u8, u8, u8),
|
||||
RGB(u8, u8, u8),
|
||||
HexARGB(u32),
|
||||
Black = 0x000000FF,
|
||||
Blue = 0x0000FFFF,
|
||||
Green = 0x00FF00FF,
|
||||
Cyan = 0x00FFFFFF,
|
||||
Red = 0xFF0000FF,
|
||||
Magenta = 0xFF00FFFF,
|
||||
Yellow = 0xFFFF00FF,
|
||||
White = 0xFFFFFFFF,
|
||||
}
|
||||
|
||||
impl Into<u32> for Color {
|
||||
fn into(self) -> u32 {
|
||||
match self {
|
||||
Color::ARGB(a, r, g, b) => (a as u32) << 24 | (r as u32) << 16 | (g as u32) << 8 | (b as u32),
|
||||
Color::RGB(r, g, b) => (0u32) << 24 | (r as u32) << 16 | (g as u32) << 8 | (b as u32),
|
||||
Color::HexARGB(hex) => hex,
|
||||
Color::Black => 0xFF000000,
|
||||
Color::Blue => 0xFF0000FF,
|
||||
Color::Green => 0xFF00FF00,
|
||||
Color::Cyan => 0xFF00FFFF,
|
||||
Color::Red => 0xFFFF0000,
|
||||
Color::Magenta => 0xFFFF00FF,
|
||||
Color::Yellow => 0xFFFFFF00,
|
||||
Color::White => 0xFFFFFFFF,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl core::fmt::Display for Color {
|
||||
fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
|
||||
match self {
|
||||
Color::ARGB(r, g, b, a) => write!(f, "RGBA(#{:x}{:x}{:x}{:x})", r, g, b, a),
|
||||
Color::RGB(r, g, b) => write!(f, "RGB(#{:x}{:x}{:x})", r, g, b),
|
||||
Color::HexARGB(hex) => write!(f, "Hex(#{:x})", hex),
|
||||
Color::Black => write!(f, "Black"),
|
||||
Color::Blue => write!(f, "Blue"),
|
||||
Color::Green => write!(f, "Green"),
|
||||
Color::Cyan => write!(f, "Cyan"),
|
||||
Color::Red => write!(f, "Red"),
|
||||
Color::Magenta => write!(f, "Magenta"),
|
||||
Color::Yellow => write!(f, "Yellow"),
|
||||
Color::White => write!(f, "White"),
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,57 +0,0 @@
|
||||
use core::panic;
|
||||
use limine::framebuffer::Framebuffer;
|
||||
use spin::{Mutex, Lazy};
|
||||
|
||||
use crate::FRAMEBUFFER_REQUEST;
|
||||
|
||||
pub static FRAMEBUFFER_WRITER: Lazy<Mutex<Option<FramebufferWriter>>> = Lazy::new(|| Mutex::new(
|
||||
if let Some(framebuffer_response) = FRAMEBUFFER_REQUEST.get_response() {
|
||||
let framebuffer = framebuffer_response.framebuffers().next().unwrap();
|
||||
Some(FramebufferWriter::new(framebuffer))
|
||||
} else {
|
||||
panic!("Framebuffer request failed");
|
||||
}
|
||||
));
|
||||
|
||||
pub struct FramebufferWriter<'a> {
|
||||
framebuffer: Framebuffer<'a>,
|
||||
}
|
||||
|
||||
unsafe impl<'a> Send for FramebufferWriter<'a> {}
|
||||
unsafe impl<'a> Sync for FramebufferWriter<'a> {}
|
||||
impl<'a> FramebufferWriter<'a> {
|
||||
pub fn new(framebuffer: Framebuffer<'a>) -> Self {
|
||||
Self {
|
||||
framebuffer,
|
||||
}
|
||||
}
|
||||
|
||||
pub fn write_pixel(&self, x: usize, y: usize, color: u32) {
|
||||
let pitch = self.framebuffer.pitch() as usize;
|
||||
let bpp = (self.framebuffer.bpp() / 8) as usize;
|
||||
let pixel_offset = y * pitch + x * bpp;
|
||||
|
||||
unsafe {
|
||||
*(self.framebuffer.addr().add(pixel_offset) as *mut u32) = color;
|
||||
}
|
||||
}
|
||||
|
||||
pub fn width(&self) -> u32 {
|
||||
self.framebuffer.width() as u32
|
||||
}
|
||||
|
||||
pub fn height(&self) -> u32 {
|
||||
self.framebuffer.height() as u32
|
||||
}
|
||||
|
||||
pub fn clear(&self) {
|
||||
let width = self.framebuffer.width() as usize;
|
||||
let height = self.framebuffer.height() as usize;
|
||||
|
||||
for y in 0..height {
|
||||
for x in 0..width {
|
||||
self.write_pixel(x, y, 0x000000);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,67 @@
|
||||
use core::panic;
|
||||
use limine::framebuffer::Framebuffer;
|
||||
use spin::{Mutex, Lazy};
|
||||
|
||||
use crate::{colour::Color, FRAMEBUFFER_REQUEST};
|
||||
|
||||
pub static FRAMEBUFFER_WRITER: Lazy<Mutex<Option<FramebufferWriter>>> = Lazy::new(|| Mutex::new(
|
||||
if let Some(framebuffer_response) = FRAMEBUFFER_REQUEST.get_response() {
|
||||
let framebuffer = framebuffer_response.framebuffers().next().unwrap();
|
||||
Some(FramebufferWriter::new(framebuffer))
|
||||
} else {
|
||||
panic!("Framebuffer request failed");
|
||||
}
|
||||
));
|
||||
|
||||
|
||||
|
||||
pub struct FramebufferWriter<'a> {
|
||||
framebuffer: Framebuffer<'a>,
|
||||
}
|
||||
|
||||
unsafe impl<'a> Send for FramebufferWriter<'a> {}
|
||||
unsafe impl<'a> Sync for FramebufferWriter<'a> {}
|
||||
impl<'a> FramebufferWriter<'a> {
|
||||
pub fn new(framebuffer: Framebuffer<'a>) -> Self {
|
||||
Self {
|
||||
framebuffer,
|
||||
}
|
||||
}
|
||||
|
||||
pub fn write_pixel(&self, x: usize, y: usize, color: Color) {
|
||||
let pitch = self.framebuffer.pitch() as usize;
|
||||
let bpp = (self.framebuffer.bpp() / 8) as usize;
|
||||
let pixel_offset = y * pitch + x * bpp;
|
||||
|
||||
unsafe {
|
||||
*(self.framebuffer.addr().add(pixel_offset) as *mut u32) = color.into();
|
||||
}
|
||||
}
|
||||
|
||||
pub fn render_frame(&self, buffer: &[Color; 1280 * 800]) {
|
||||
for (y, row) in buffer.chunks(1280).enumerate() {
|
||||
for (x, pixel) in row.iter().enumerate() {
|
||||
self.write_pixel(x, y, *pixel);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
pub fn width(&self) -> u32 {
|
||||
self.framebuffer.width() as u32
|
||||
}
|
||||
|
||||
pub fn height(&self) -> u32 {
|
||||
self.framebuffer.height() as u32
|
||||
}
|
||||
|
||||
pub fn clear(&self) {
|
||||
let width = self.framebuffer.width() as usize;
|
||||
let height = self.framebuffer.height() as usize;
|
||||
|
||||
for y in 0..height {
|
||||
for x in 0..width {
|
||||
self.write_pixel(x, y, Color::Black);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -6,8 +6,10 @@ use limine::request::FramebufferRequest;
|
||||
#[link_section = ".requests"]
|
||||
static FRAMEBUFFER_REQUEST: FramebufferRequest = FramebufferRequest::new();
|
||||
|
||||
mod draw;
|
||||
pub use draw::FRAMEBUFFER_WRITER;
|
||||
mod framebuffer;
|
||||
mod colour;
|
||||
pub use framebuffer::FRAMEBUFFER_WRITER;
|
||||
pub use colour::Color;
|
||||
|
||||
pub fn screensize_px() -> (u32, u32) {
|
||||
if let Some(writer) = FRAMEBUFFER_WRITER.lock().as_mut() {
|
||||
|
||||
+18
-8
@@ -22,7 +22,7 @@ info() {
|
||||
}
|
||||
|
||||
compiling() {
|
||||
echo -e "${GREEN}${BOLD}Compiling${NC} $1"
|
||||
echo -e "${GREEN}${BOLD}Compiling${NC}: $1"
|
||||
}
|
||||
|
||||
warning() {
|
||||
@@ -30,7 +30,11 @@ warning() {
|
||||
}
|
||||
|
||||
building() {
|
||||
echo -e "${GREEN}${BOLD}Building${NC} $1"
|
||||
echo -e "${GREEN}${BOLD}Building${NC}: $1"
|
||||
}
|
||||
|
||||
copying() {
|
||||
echo -e "${GREEN}${BOLD} Copying${NC}: $1 to $2"
|
||||
}
|
||||
|
||||
error() {
|
||||
@@ -38,6 +42,11 @@ error() {
|
||||
exit 1
|
||||
}
|
||||
|
||||
copy_file() {
|
||||
copying $1 $2
|
||||
cp "$1" "$2" || error $3
|
||||
}
|
||||
|
||||
build_dir="$project_root/build"
|
||||
iso_root="$build_dir/iso_root"
|
||||
|
||||
@@ -83,12 +92,13 @@ fi
|
||||
|
||||
# Copy files
|
||||
info "Copying files to ISO root"
|
||||
cp -v "$kernel_path" "$iso_root/boot/kernel" || error "failed to copy kernel"
|
||||
cp -v "$project_root/config/limine.conf" "$iso_root/boot/limine/limine.conf" || error "failed to copy limine config"
|
||||
cp -v "$build_dir/limine/limine-bios.sys" "$build_dir/limine/limine-bios-cd.bin" \
|
||||
"$build_dir/limine/limine-uefi-cd.bin" "$iso_root/boot/limine/" || error "failed to copy limine files"
|
||||
cp -v "$build_dir/limine/BOOTX64.EFI" "$iso_root/EFI/BOOT/" || error "failed to copy BOOTX64.EFI"
|
||||
cp -v "$build_dir/limine/BOOTIA32.EFI" "$iso_root/EFI/BOOT/" || error "failed to copy BOOTIA32.EFI"
|
||||
copy_file "$kernel_path" "$iso_root/boot/kernel" "failed to copy kernel"
|
||||
copy_file "$project_root/config/limine.conf" "$iso_root/boot/limine/limine.conf" "failed to copy limine config"
|
||||
copy_file "$build_dir/limine/limine-bios-cd.bin" "$iso_root/boot/limine/" "failed to copy limine-bios-cd.bin"
|
||||
copy_file "$build_dir/limine/limine-uefi-cd.bin" "$iso_root/boot/limine/" "failed to copy limine-uefi-cd.bin"
|
||||
copy_file "$build_dir/limine/limine-bios.sys" "$iso_root/boot/limine/" "failed to copy limine-bios.sys"
|
||||
copy_file "$build_dir/limine/BOOTX64.EFI" "$iso_root/EFI/BOOT/" "failed to copy BOOTX64.EFI"
|
||||
copy_file "$build_dir/limine/BOOTIA32.EFI" "$iso_root/EFI/BOOT/" "failed to copy BOOTIA32.EFI"
|
||||
|
||||
# Create ISO
|
||||
building "bootable ISO image"
|
||||
|
||||
Reference in New Issue
Block a user