use core::convert::TryInto;
use crate::clock::Ts;
use crate::video::{
pixel_line_offset, color_line_offset,
CellCoords
};
use crate::memory::ScreenArray;
pub trait VideoFrameDataIterator: Iterator<Item=(u8, u8)> {
fn next_line(&mut self);
}
pub trait PlusVidFrameDataIterator: Iterator<Item=(u8, u8, Ts)> {
fn next_line(&mut self);
}
pub const COLUMNS: usize = 32;
pub const PIXEL_LINES: usize = 192;
pub const ATTR_ROWS: usize = 24;
pub const ATTRS_OFFSET: usize = 0x1800;
#[inline(always)]
pub fn pixel_address_coords(addr: u16) -> CellCoords {
let column = (addr & 0b0001_1111) as u8;
let row = (addr >> 5 & 0b1100_0000 |
addr >> 2 & 0b0011_1000 |
addr >> 8 & 0b0000_0111) as u8;
CellCoords { column, row }
}
#[inline(always)]
pub fn color_address_coords(addr: u16) -> CellCoords {
let column = (addr & 0b0001_1111) as u8;
let row = (addr >> 5 & 0b0001_1111) as u8;
CellCoords { column, row }
}
#[inline(always)]
pub fn attr_line_from(line: usize, screen: &ScreenArray) -> &[u8;COLUMNS] {
let offset = ATTRS_OFFSET + color_line_offset(line);
cast_line(&screen[offset..offset + COLUMNS])
}
#[inline(always)]
pub fn ink_line_from(line: usize, screen: &ScreenArray) -> &[u8;COLUMNS] {
let offset = pixel_line_offset(line);
cast_line(&screen[offset..offset + COLUMNS])
}
#[inline(always)]
fn cast_line(line_slice: &[u8]) -> &[u8; COLUMNS] {
line_slice.try_into().unwrap()
}