aboutsummaryrefslogtreecommitdiff
path: root/mtree-test/src/lib.rs
blob: bf0117d476b78efa93d3dd43d9b3e5a9e937bcfb (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
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<u8>);

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<i16>) -> [&[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<I16Vec2>, out: &mut Vec<u8>) {
        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<I16Vec2>, 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<Frame>,
}