GraphicsWriter changes

This commit is contained in:
Ryan Kennedy 2020-04-16 17:49:18 -05:00
parent c3155975ad
commit 30728c0534
5 changed files with 81 additions and 57 deletions

View file

@ -1,5 +1,9 @@
use super::pci::{find_pci_device, PciDevice}; use super::pci::{find_pci_device, PciDevice};
use crate::drawing::{Bresenham, Point, Rectangle}; use crate::{
drawing::{Bresenham, Point, Rectangle},
writers::GraphicsWriter,
};
use font8x8::UnicodeFonts;
use x86_64::{instructions::port::Port, PhysAddr, VirtAddr}; use x86_64::{instructions::port::Port, PhysAddr, VirtAddr};
const BOCHS_ID: u32 = 0x1111_1234; const BOCHS_ID: u32 = 0x1111_1234;
@ -100,24 +104,6 @@ impl BochsDevice {
} }
} }
/// Clears the screen using the given `color`.
pub fn clear_screen(&self, color: u32) {
let screen_size = self.current_resolution.width * self.current_resolution.height;
let frame_buffer = self.virtual_address.as_mut_ptr::<u32>();
for offset in 0..screen_size {
unsafe {
frame_buffer.add(offset).write_volatile(color);
}
}
}
/// Draws a line from the given `start` to `end` using the given `color`.
pub fn draw_line(&self, start: Point<isize>, end: Point<isize>, color: u32) {
for (x, y) in Bresenham::new(start, end) {
self.set_pixel(x as usize, y as usize, color);
}
}
/// Draws a rectangle using the given `rectangle` and `color`. /// Draws a rectangle using the given `rectangle` and `color`.
pub fn draw_rectangle(&self, rectangle: &Rectangle, color: u32) { pub fn draw_rectangle(&self, rectangle: &Rectangle, color: u32) {
let p1 = (rectangle.left as isize, rectangle.top as isize); let p1 = (rectangle.left as isize, rectangle.top as isize);
@ -134,22 +120,11 @@ impl BochsDevice {
pub fn fill_rectangle(&self, rectangle: &Rectangle, color: u32) { pub fn fill_rectangle(&self, rectangle: &Rectangle, color: u32) {
for y in rectangle.top..rectangle.bottom { for y in rectangle.top..rectangle.bottom {
for x in rectangle.left..rectangle.right { for x in rectangle.left..rectangle.right {
self.set_pixel(x, y, color); self.set_pixel(x as usize, y as usize, color);
} }
} }
} }
/// Sets the pixel at `(x, y)` to the given `color`.
pub fn set_pixel(&self, x: usize, y: usize, color: u32) {
let offset = (y * self.current_resolution.width) + x;
unsafe {
self.virtual_address
.as_mut_ptr::<u32>()
.add(offset)
.write_volatile(color);
}
}
fn disable_display(&mut self) { fn disable_display(&mut self) {
unsafe { unsafe {
self.index_port.write(VBE_DISPI_INDEX_ENABLE); self.index_port.write(VBE_DISPI_INDEX_ENABLE);
@ -217,3 +192,48 @@ impl BochsDevice {
} }
} }
} }
impl GraphicsWriter<u32> for BochsDevice {
fn clear_screen(&self, color: u32) {
let screen_size = self.current_resolution.width * self.current_resolution.height;
let frame_buffer = self.virtual_address.as_mut_ptr::<u32>();
for offset in 0..screen_size {
unsafe {
frame_buffer.add(offset).write_volatile(color);
}
}
}
fn draw_character(&self, x: usize, y: usize, character: char, color: u32) {
let character = match font8x8::BASIC_FONTS.get(character) {
Some(character) => character,
// Default to a filled block if the character isn't found
None => font8x8::unicode::BLOCK_UNICODE[8].byte_array(),
};
for (row, byte) in character.iter().enumerate() {
for bit in 0..8 {
match *byte & 1 << bit {
0 => (),
_ => self.set_pixel(x + bit, y + row, color),
}
}
}
}
fn draw_line(&self, start: Point<isize>, end: Point<isize>, color: u32) {
for (x, y) in Bresenham::new(start, end) {
self.set_pixel(x as usize, y as usize, color);
}
}
fn set_pixel(&self, x: usize, y: usize, color: u32) {
let offset = (y * self.current_resolution.width) + x;
unsafe {
self.virtual_address
.as_mut_ptr::<u32>()
.add(offset)
.write_volatile(color);
}
}
fn get_frame_buffer<T>(&self) -> *mut T {
self.virtual_address.as_mut_ptr()
}
}

View file

@ -76,14 +76,6 @@ impl GraphicsWriter<u8> for Graphics320x200x256 {
} }
} }
} }
fn set_mode(&self) {
let mut vga = VGA.lock();
vga.set_video_mode(VideoMode::Mode320x200x256);
// Some bios mess up the palette when switching modes,
// so explicitly set it.
vga.color_palette_registers.load_palette(&DEFAULT_PALETTE);
}
fn get_frame_buffer<T>(&self) -> *mut T { fn get_frame_buffer<T>(&self) -> *mut T {
u32::from(VGA.lock().get_frame_buffer()) as *mut T u32::from(VGA.lock().get_frame_buffer()) as *mut T
} }
@ -94,4 +86,14 @@ impl Graphics320x200x256 {
pub const fn new() -> Graphics320x200x256 { pub const fn new() -> Graphics320x200x256 {
Graphics320x200x256 Graphics320x200x256
} }
/// Sets the graphics device to a `VideoMode`.
pub fn set_mode(&self) {
let mut vga = VGA.lock();
vga.set_video_mode(VideoMode::Mode320x200x256);
// Some bios mess up the palette when switching modes,
// so explicitly set it.
vga.color_palette_registers.load_palette(&DEFAULT_PALETTE);
}
} }

View file

@ -84,14 +84,6 @@ impl GraphicsWriter<u8> for Graphics320x240x256 {
} }
} }
} }
fn set_mode(&self) {
let mut vga = VGA.lock();
vga.set_video_mode(VideoMode::Mode320x240x256);
// Some bios mess up the palette when switching modes,
// so explicitly set it.
vga.color_palette_registers.load_palette(&DEFAULT_PALETTE);
}
fn get_frame_buffer<T>(&self) -> *mut T { fn get_frame_buffer<T>(&self) -> *mut T {
u32::from(VGA.lock().get_frame_buffer()) as *mut T u32::from(VGA.lock().get_frame_buffer()) as *mut T
} }
@ -102,4 +94,14 @@ impl Graphics320x240x256 {
pub const fn new() -> Graphics320x240x256 { pub const fn new() -> Graphics320x240x256 {
Graphics320x240x256 Graphics320x240x256
} }
/// Sets the graphics device to a `VideoMode`.
pub fn set_mode(&self) {
let mut vga = VGA.lock();
vga.set_video_mode(VideoMode::Mode320x240x256);
// Some bios mess up the palette when switching modes,
// so explicitly set it.
vga.color_palette_registers.load_palette(&DEFAULT_PALETTE);
}
} }

View file

@ -86,14 +86,6 @@ impl GraphicsWriter<Color16> for Graphics640x480x16 {
self._set_pixel(x, y, color); self._set_pixel(x, y, color);
} }
fn set_mode(&self) {
let mut vga = VGA.lock();
vga.set_video_mode(VideoMode::Mode640x480x16);
// Some bios mess up the palette when switching modes,
// so explicitly set it.
vga.color_palette_registers.load_palette(&DEFAULT_PALETTE);
}
fn get_frame_buffer<T>(&self) -> *mut T { fn get_frame_buffer<T>(&self) -> *mut T {
u32::from(VGA.lock().get_frame_buffer()) as *mut T u32::from(VGA.lock().get_frame_buffer()) as *mut T
} }
@ -105,6 +97,16 @@ impl Graphics640x480x16 {
Graphics640x480x16 Graphics640x480x16
} }
/// Sets the graphics device to a `VideoMode`.
pub fn set_mode(&self) {
let mut vga = VGA.lock();
vga.set_video_mode(VideoMode::Mode640x480x16);
// Some bios mess up the palette when switching modes,
// so explicitly set it.
vga.color_palette_registers.load_palette(&DEFAULT_PALETTE);
}
fn set_write_mode_0(self, color: Color16) { fn set_write_mode_0(self, color: Color16) {
let mut vga = VGA.lock(); let mut vga = VGA.lock();
vga.graphics_controller_registers.write_set_reset(color); vga.graphics_controller_registers.write_set_reset(color);

View file

@ -197,8 +197,6 @@ pub trait GraphicsWriter<Color> {
fn draw_character(&self, x: usize, y: usize, character: char, color: Color); fn draw_character(&self, x: usize, y: usize, character: char, color: Color);
/// Sets the given pixel at `(x, y)` to the given `color`. /// Sets the given pixel at `(x, y)` to the given `color`.
fn set_pixel(&self, x: usize, y: usize, color: Color); fn set_pixel(&self, x: usize, y: usize, color: Color);
/// Sets the graphics device to a `VideoMode`.
fn set_mode(&self);
/// Returns the frame buffer for this vga mode. /// Returns the frame buffer for this vga mode.
fn get_frame_buffer<T>(&self) -> *mut T; fn get_frame_buffer<T>(&self) -> *mut T;
} }