use glam::{I16Vec2, i16vec2}; use std::{collections::VecDeque, ops::Range}; pub const BLOCK_SIZE: i16 = 4; #[derive(Debug, Clone, Copy, PartialEq, Eq)] pub struct AbsRef { pub off: I16Vec2, pub frame: u64, } #[derive(Clone)] pub struct Frame(pub Vec); impl Frame { pub fn new(res: I16Vec2) -> Self { let res = res.as_usizevec2(); Self(vec![0; res.x * res.y + 2 * (res.x / 2 * res.y / 2)]) } pub fn index(&self, res: I16Vec2, p: I16Vec2) -> [usize; 3] { let res = res.as_usizevec2(); let p = p.as_usizevec2(); let ystride = res.y; let ysize = res.x * ystride; let uvstride = res.x / 2; let usize = uvstride * (res.y / 2); let puv = p / 2; [ p.x + p.y * ystride, ysize + puv.x + puv.y * uvstride, ysize + usize + puv.x + puv.y * uvstride, ] } pub fn slice(&self, res: I16Vec2, y: i16, x: Range) -> [&[u8]; 3] { let start = self.index(res, i16vec2(x.start, y)); let end = self.index(res, i16vec2(x.end, y)); [ &self.0[start[0]..end[0]], &self.0[start[1]..end[1]], &self.0[start[2]..end[2]], ] } pub fn get(&self, res: I16Vec2, p: I16Vec2) -> [u8; 3] { self.index(res, p).map(|i| self.0[i]) } pub fn export_rect(&self, res: I16Vec2, r: Range, out: &mut Vec) { for y in r.start.y..r.end.y { let slices = self.slice(res, y, r.start.x..r.end.x); out.extend(slices[0]); out.extend(slices[1]); out.extend(slices[2]); } } pub fn import_rect(&mut self, res: I16Vec2, r: Range, mut data: &[u8]) -> usize { let mut off = 0; for y in r.start.y..r.end.y { let start = self.index(res, i16vec2(r.start.x, y)); let end = self.index(res, i16vec2(r.end.x, y)); let mut do_slice = |s: &mut [u8]| { s.copy_from_slice(&data[..s.len()]); data = &data[s.len()..]; off += s.len(); }; do_slice(&mut self.0[start[0]..end[0]]); do_slice(&mut self.0[start[1]..end[1]]); do_slice(&mut self.0[start[2]..end[2]]); } off } } pub fn frame_to_frame_rect_copy( res: I16Vec2, aframe: &mut Frame, bframe: &Frame, size: I16Vec2, aoff: I16Vec2, boff: I16Vec2, ) { for y in 0..size.y { let astart = aframe.index(res, i16vec2(aoff.x, aoff.y + y)); let aend = aframe.index(res, i16vec2(aoff.x + size.x, aoff.y + y)); let bstart = bframe.index(res, i16vec2(boff.x, boff.y + y)); let bend = bframe.index(res, i16vec2(boff.x + size.x, boff.y + y)); aframe.0[astart[0]..aend[0]].copy_from_slice(&bframe.0[bstart[0]..bend[0]]); aframe.0[astart[1]..aend[1]].copy_from_slice(&bframe.0[bstart[1]..bend[1]]); aframe.0[astart[2]..aend[2]].copy_from_slice(&bframe.0[bstart[2]..bend[2]]); } } pub struct LastFrames { pub frame_offset: u64, pub frames: VecDeque, }