mappings: first implementation of surface mapping and pixel selection engine
This commit is contained in:
parent
61b28179d1
commit
291affc992
@ -6,6 +6,7 @@ mod time;
|
|||||||
mod geometry;
|
mod geometry;
|
||||||
mod platform;
|
mod platform;
|
||||||
mod animations;
|
mod animations;
|
||||||
|
mod mappings;
|
||||||
|
|
||||||
use crate::platform::DisplayInit;
|
use crate::platform::DisplayInit;
|
||||||
use crate::render::Surfaces;
|
use crate::render::Surfaces;
|
||||||
|
259
src/mappings.rs
Normal file
259
src/mappings.rs
Normal file
@ -0,0 +1,259 @@
|
|||||||
|
use crate::geometry::*;
|
||||||
|
|
||||||
|
use crate::lib8::scale8;
|
||||||
|
|
||||||
|
use std::cmp::max;
|
||||||
|
use std::fmt::{Formatter, Debug};
|
||||||
|
|
||||||
|
pub trait CoordinateView: Debug {
|
||||||
|
fn next(&mut self) -> Option<(VirtualCoordinates, PhysicalCoordinates)>;
|
||||||
|
}
|
||||||
|
|
||||||
|
pub trait PixelMapping<CoordData: CoordLimits<Data = CoordData>> {
|
||||||
|
fn select(&self, rect: &Rectangle<CoordData, Virtual>) -> impl CoordinateView;
|
||||||
|
}
|
||||||
|
|
||||||
|
#[derive(Debug)]
|
||||||
|
struct LinearCoordView {
|
||||||
|
rect: Rectangle<u8, Virtual>,
|
||||||
|
idx: u8,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl CoordinateView for LinearCoordView {
|
||||||
|
fn next(&mut self) -> Option<(VirtualCoordinates, PhysicalCoordinates)> {
|
||||||
|
if self.idx == self.rect.bottom_right.x {
|
||||||
|
None
|
||||||
|
} else {
|
||||||
|
let virt = VirtualCoordinates::new(self.idx, 0);
|
||||||
|
let phys = PhysicalCoordinates::new(self.idx as usize, 0);
|
||||||
|
self.idx += 1;
|
||||||
|
return Some((virt, phys))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
pub struct LinearPixelMapping {
|
||||||
|
}
|
||||||
|
|
||||||
|
impl LinearPixelMapping {
|
||||||
|
pub fn new() -> Self {
|
||||||
|
Self {}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl PixelMapping<u8> for LinearPixelMapping {
|
||||||
|
fn select(&self, rect: &Rectangle<u8, Virtual>) -> impl CoordinateView {
|
||||||
|
LinearCoordView {
|
||||||
|
rect: rect.clone(),
|
||||||
|
idx: 0,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#[derive(Default, Clone, Copy, Debug, PartialEq, Eq)]
|
||||||
|
pub struct Stride {
|
||||||
|
pub length: u8,
|
||||||
|
pub x: u8,
|
||||||
|
pub y: u8,
|
||||||
|
pub reverse: bool,
|
||||||
|
pub physical_idx: usize
|
||||||
|
}
|
||||||
|
|
||||||
|
#[derive(Debug)]
|
||||||
|
pub struct StrideMapping<const STRIDE_NUM: usize = 32> {
|
||||||
|
pub strides: [Stride; STRIDE_NUM],
|
||||||
|
pub stride_count: usize,
|
||||||
|
pixel_count: usize,
|
||||||
|
top: u8,
|
||||||
|
left: u8,
|
||||||
|
height: u8,
|
||||||
|
width: u8
|
||||||
|
}
|
||||||
|
|
||||||
|
impl<const STRIDE_NUM: usize> StrideMapping<STRIDE_NUM> {
|
||||||
|
pub fn new() -> Self {
|
||||||
|
/*let stride_json = vec!(
|
||||||
|
(0, 0, 17),
|
||||||
|
(1, 0, 17),
|
||||||
|
(2, 0, 17),
|
||||||
|
(3, 0, 17),
|
||||||
|
(4, 0, 16),
|
||||||
|
(5, 0, 17),
|
||||||
|
(6, 0, 17),
|
||||||
|
(7, 0, 17),
|
||||||
|
(8, 0, 17),
|
||||||
|
(9, 0, 17),
|
||||||
|
(10, 0, 17),
|
||||||
|
(11, 0, 17),
|
||||||
|
(12, 0, 18),
|
||||||
|
(13, 0, 17),
|
||||||
|
(14, 0, 18),
|
||||||
|
(15, 0, 17),
|
||||||
|
(16, 0, 17),
|
||||||
|
(17, 0, 17)
|
||||||
|
);*/
|
||||||
|
let stride_json = vec!(
|
||||||
|
(0, 0, 16, false),
|
||||||
|
(1, 0, 16, true),
|
||||||
|
(2, 0, 16, false),
|
||||||
|
(3, 0, 16, true),
|
||||||
|
(4, 0, 16, false),
|
||||||
|
(5, 0, 16, true),
|
||||||
|
(6, 0, 16, false),
|
||||||
|
(7, 0, 16, true),
|
||||||
|
(8, 0, 16, false),
|
||||||
|
(9, 0, 16, true),
|
||||||
|
(10, 0, 16, false),
|
||||||
|
(11, 0, 16, true),
|
||||||
|
(12, 0, 16, false),
|
||||||
|
(13, 0, 16, true),
|
||||||
|
(14, 0, 16, false),
|
||||||
|
(15, 0, 16, true),
|
||||||
|
);
|
||||||
|
let mut strides = [Stride::default(); STRIDE_NUM];
|
||||||
|
let stride_count = stride_json.len();
|
||||||
|
let mut physical_idx = 0;
|
||||||
|
let mut height = 0;
|
||||||
|
let mut width = 0;
|
||||||
|
for stride_idx in 0..stride_count {
|
||||||
|
let json_data = stride_json[stride_idx];
|
||||||
|
let x = json_data.0;
|
||||||
|
let y = json_data.1;
|
||||||
|
let length = json_data.2;
|
||||||
|
let reverse = json_data.3;
|
||||||
|
strides[stride_idx] = Stride {
|
||||||
|
length,
|
||||||
|
x,
|
||||||
|
y,
|
||||||
|
reverse,
|
||||||
|
physical_idx
|
||||||
|
};
|
||||||
|
physical_idx += length as usize;
|
||||||
|
width = max(width, stride_idx + x as usize);
|
||||||
|
height = max(height, length as usize + y as usize)
|
||||||
|
}
|
||||||
|
let top = 0;
|
||||||
|
let left = 0;
|
||||||
|
|
||||||
|
log::info!("strides={:?}", strides);
|
||||||
|
|
||||||
|
Self {
|
||||||
|
strides,
|
||||||
|
stride_count,
|
||||||
|
pixel_count: physical_idx,
|
||||||
|
top,
|
||||||
|
left,
|
||||||
|
height: height as u8,
|
||||||
|
width: width as u8
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl PixelMapping<u8> for StrideMapping {
|
||||||
|
fn select(&self, rect: &Rectangle<u8, Virtual>) -> impl CoordinateView {
|
||||||
|
let ret = StrideView::new(self, rect);
|
||||||
|
//log::info!("select={:?}", ret);
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#[derive(Debug)]
|
||||||
|
struct StrideSpace {}
|
||||||
|
impl CoordinateSpace for StrideSpace {}
|
||||||
|
|
||||||
|
type StrideCoords = Coordinates<u8, StrideSpace>;
|
||||||
|
|
||||||
|
struct StrideView<'a> {
|
||||||
|
map: &'a StrideMapping,
|
||||||
|
rect: Rectangle<u8, Virtual>,
|
||||||
|
span_start: u8,
|
||||||
|
span_end: u8,
|
||||||
|
offset_start: u8,
|
||||||
|
offset_end: u8,
|
||||||
|
virt_step_width: u8,
|
||||||
|
virt_step_height: u8,
|
||||||
|
cur_pixel: StrideCoords
|
||||||
|
}
|
||||||
|
|
||||||
|
impl<'a> Debug for StrideView<'a> {
|
||||||
|
fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result {
|
||||||
|
f.debug_struct("StrideView")
|
||||||
|
.field("rect", &self.rect)
|
||||||
|
.field("span", &(self.span_start, self.span_end))
|
||||||
|
.field("offset", &(self.offset_start, self.offset_end))
|
||||||
|
.field("step", &(self.virt_step_width, self.virt_step_height))
|
||||||
|
.field("cur", &self.cur_pixel).finish()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl<'a> StrideView<'a> {
|
||||||
|
fn new(map: &'a StrideMapping, rect: &Rectangle<u8, Virtual>) -> Self {
|
||||||
|
let span_start = scale8(rect.top_left.x, map.width);
|
||||||
|
let span_end = scale8(rect.bottom_right.x, map.width);
|
||||||
|
let offset_start = scale8(rect.top_left.y, map.height);
|
||||||
|
let offset_end = scale8(rect.bottom_right.y, map.height);
|
||||||
|
let virt_step_width = u8::MAX / std::cmp::max(1, span_end - span_start);
|
||||||
|
let virt_step_height = u8::MAX / std::cmp::max(1, offset_end - offset_start);
|
||||||
|
return Self {
|
||||||
|
map,
|
||||||
|
rect: rect.clone(),
|
||||||
|
span_start,
|
||||||
|
span_end,
|
||||||
|
offset_start,
|
||||||
|
offset_end,
|
||||||
|
virt_step_width,
|
||||||
|
virt_step_height,
|
||||||
|
cur_pixel: StrideCoords::new(span_start, offset_start)
|
||||||
|
};
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl<'a> CoordinateView for StrideView<'a> {
|
||||||
|
fn next(&mut self) -> Option<(VirtualCoordinates, PhysicalCoordinates)> {
|
||||||
|
let mut search_idx = self.cur_pixel.x;
|
||||||
|
let mut next_offset = self.cur_pixel.y + 1;
|
||||||
|
//log::info!("view={:?}", self);
|
||||||
|
|
||||||
|
while search_idx <= self.span_end {
|
||||||
|
let cur = &self.map.strides[search_idx as usize];
|
||||||
|
|
||||||
|
if next_offset < self.offset_start || next_offset < cur.y {
|
||||||
|
search_idx += 1;
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
if next_offset > cur.y + cur.length || next_offset > self.offset_end {
|
||||||
|
search_idx += 1;
|
||||||
|
if search_idx <= self.span_end {
|
||||||
|
next_offset = self.map.strides[search_idx as usize].y;
|
||||||
|
continue
|
||||||
|
} else {
|
||||||
|
//log::info!("search end");
|
||||||
|
return None;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
self.cur_pixel = StrideCoords::new(search_idx, next_offset);
|
||||||
|
let virt = VirtualCoordinates::new(
|
||||||
|
(self.cur_pixel.x * self.virt_step_width).try_into().unwrap(),
|
||||||
|
((self.cur_pixel.y - cur.y) * self.virt_step_height).try_into().unwrap()
|
||||||
|
);
|
||||||
|
let stride_pos = StrideCoords::new(self.cur_pixel.x.try_into().unwrap(), (self.cur_pixel.y - cur.y).try_into().unwrap());
|
||||||
|
|
||||||
|
let span = &self.map.strides[stride_pos.x as usize];
|
||||||
|
//log::info!("span={:?} stride={:?} cur={:?}", span, stride_pos, self.cur_pixel);
|
||||||
|
let phys_idx = if span.reverse {
|
||||||
|
span.physical_idx + (span.length - 1 - stride_pos.y) as usize
|
||||||
|
} else {
|
||||||
|
span.physical_idx + stride_pos.y as usize
|
||||||
|
};
|
||||||
|
let phys = PhysicalCoordinates::new(phys_idx, 0);
|
||||||
|
//log::info!("virt={:?} phys={:?}", virt, phys);
|
||||||
|
return Some((virt, phys));
|
||||||
|
}
|
||||||
|
|
||||||
|
//log::info!("end");
|
||||||
|
|
||||||
|
return None;
|
||||||
|
}
|
||||||
|
}
|
Loading…
x
Reference in New Issue
Block a user