use super::{DisplayPort, DisplayPortDeviceType, DisplayPortLayer, DisplayPortLayerBuffer, DisplayPortSeverity};
use core::convert::Infallible;
use core::ops::Deref;
#[derive(Clone, Copy, Debug, PartialEq)]
pub struct DisplayPortLayers {
pub display_port: DisplayPort,
pub display_layers: [DisplayPortLayerBuffer; DisplayPort::LAYER_COUNT],
}
impl DisplayPortLayers {
pub const fn new(device_type: DisplayPortDeviceType) -> Self {
Self {
display_port: DisplayPort::new(device_type),
display_layers: [DisplayPortLayerBuffer::new(); DisplayPort::LAYER_COUNT],
}
}
}
impl Default for DisplayPortLayers {
fn default() -> Self {
Self::new(super::DisplayPortDeviceType::Auto)
}
}
impl Deref for DisplayPortLayers {
type Target = DisplayPort;
fn deref(&self) -> &Self::Target {
&self.display_port
}
}
impl DisplayPortLayers {
pub fn clear_layer(&mut self, layer: DisplayPortLayer) {
self.display_layers[layer as usize].buffer.fill(0x20);
}
pub fn write_byte(&mut self, x: u8, y: u8, byte: u8, _attr: DisplayPortSeverity) -> usize {
if x >= self.display_port.column_count() || y >= self.display_port.row_count() {
return 0;
}
let active_idx = self.display_port.active_layer() as usize;
if let Some(layer) = self.display_layers.get_mut(active_idx) {
if let Some(cell) = layer.get_mut(x, y, self.display_port.column_count()) {
*cell = byte;
return 1;
}
}
0
}
pub fn write_slice(&mut self, x: u8, y: u8, slice: &[u8], _attr: DisplayPortSeverity) -> usize {
let column_count = self.display_port.column_count();
let row_count = self.display_port.row_count();
if x >= column_count || y >= row_count || slice.is_empty() {
return 0;
}
let active_idx = self.display_port.active_layer() as usize;
let Some(layer) = self.display_layers.get_mut(active_idx) else {
return 0;
};
let start_idx = (y as usize * column_count as usize) + x as usize;
let max_line_len = (column_count - x) as usize;
let write_len = slice.len().min(max_line_len);
let bytes_to_write = &slice[..write_len];
if let Some(target_window) = layer.buffer.get_mut(start_idx..(start_idx + write_len)) {
for (cell, &byte) in target_window.iter_mut().zip(bytes_to_write.iter()) {
*cell = byte;
}
write_len
} else {
0
}
}
pub fn layer_copy(&mut self, src: DisplayPortLayer, dst: DisplayPortLayer) {
if src == dst {
return;
}
let src_idx = src as usize;
let dst_idx = dst as usize;
if src_idx >= DisplayPort::LAYER_COUNT || dst_idx >= DisplayPort::LAYER_COUNT {
return;
}
if src_idx < dst_idx {
let (src, dst) = self.display_layers.split_at_mut(dst_idx);
let src_layer = &src[src_idx];
let dst_layer = &mut dst[0];
dst_layer.buffer.copy_from_slice(&src_layer.buffer);
} else {
let (dst, src) = self.display_layers.split_at_mut(src_idx);
let src_layer = &src[0];
let dst_layer = &mut dst[dst_idx];
dst_layer.buffer.copy_from_slice(&src_layer.buffer);
}
}
#[allow(unused)]
pub async fn draw_screen(&mut self) -> Result<bool, Infallible> {
core::future::ready(()).await;
Ok(false)
}
}