diff --git a/src/devices/graphical_debug/display.rs b/src/devices/graphical_debug/display.rs index ab4a93e..d3d93ec 100644 --- a/src/devices/graphical_debug/display.rs +++ b/src/devices/graphical_debug/display.rs @@ -7,13 +7,14 @@ use super::FONT; pub struct Display { pub width: usize, pub height: usize, + pub stride: usize, pub onscreen: &'static mut [u32], pub offscreen: Option> } impl Display { - pub fn new(width: usize, height: usize, onscreen_ptr: *mut u32) -> Display { - let size = width * height; + pub fn new(width: usize, height: usize, stride: usize, onscreen_ptr: *mut u32) -> Display { + let size = stride * height; let onscreen = unsafe { ptr::write_bytes(onscreen_ptr, 0, size); slice::from_raw_parts_mut(onscreen_ptr, size) @@ -21,6 +22,7 @@ impl Display { Display { width, height, + stride, onscreen, offscreen: None, } @@ -36,7 +38,7 @@ impl Display { /// Draw a character pub fn char(&mut self, x: usize, y: usize, character: char, color: u32) { if x + 8 <= self.width && y + 16 <= self.height { - let mut dst = self.data_mut().as_mut_ptr() as usize + (y * self.width + x) * 4; + let mut dst = self.data_mut().as_mut_ptr() as usize + (y * self.stride + x) * 4; let font_i = 16 * (character as usize); if font_i + 16 <= FONT.len() { @@ -47,7 +49,7 @@ impl Display { unsafe { *((dst + col * 4) as *mut u32) = color; } } } - dst += self.width * 4; + dst += self.stride * 4; } } } @@ -55,8 +57,8 @@ impl Display { /// Scroll the screen pub fn scroll(&mut self, lines: usize) { - let offset = cmp::min(self.height, lines) * self.width; - let size = (self.width * self.height) - offset; + let offset = cmp::min(self.height, lines) * self.stride; + let size = (self.stride * self.height) - offset; unsafe { let ptr = self.data_mut().as_mut_ptr(); ptr::copy(ptr.add(offset), ptr, size); @@ -67,12 +69,12 @@ impl Display { /// Sync from offscreen to onscreen, unsafe because it trusts provided x, y, w, h pub unsafe fn sync(&mut self, x: usize, y: usize, w: usize, mut h: usize) { if let Some(offscreen) = &self.offscreen { - let mut offset = y * self.width + x; + let mut offset = y * self.stride + x; while h > 0 { self.onscreen[offset..offset+w].copy_from_slice( &offscreen[offset..offset+w] ); - offset += self.width; + offset += self.stride; h -= 1; } } diff --git a/src/devices/graphical_debug/mod.rs b/src/devices/graphical_debug/mod.rs index 8f25d73..29468f8 100644 --- a/src/devices/graphical_debug/mod.rs +++ b/src/devices/graphical_debug/mod.rs @@ -20,6 +20,7 @@ pub fn init(env: &[u8]) { let mut virt = 0; let mut width = 0; let mut height = 0; + let mut stride = 0; //TODO: should errors be reported? for line in str::from_utf8(env).unwrap_or("").lines() { @@ -42,19 +43,23 @@ pub fn init(env: &[u8]) { if name == "FRAMEBUFFER_HEIGHT" { height = usize::from_str_radix(value, 16).unwrap_or(0); } + + if name == "FRAMEBUFFER_STRIDE" { + stride = usize::from_str_radix(value, 16).unwrap_or(0); + } } - *FRAMEBUFFER.lock() = (phys, virt, width * height * 4); + *FRAMEBUFFER.lock() = (phys, virt, stride * height * 4); - if phys == 0 || virt == 0 || width == 0 || height == 0 { + if phys == 0 || virt == 0 || width == 0 || height == 0 || stride == 0 { println!("Framebuffer not found"); return; } - println!("Framebuffer {}x{} at {:X} mapped to {:X}", width, height, phys, virt); + println!("Framebuffer {}x{} stride {} at {:X} mapped to {:X}", width, height, stride, phys, virt); { - let display = Display::new(width, height, virt as *mut u32); + let display = Display::new(width, height, stride, virt as *mut u32); let debug_display = DebugDisplay::new(display); *DEBUG_DISPLAY.lock() = Some(debug_display); }