old school music tracker
1pub const PALETTE_SIZE: usize = 16;
2
3pub type RGB8 = [u8; 3];
4
5/// See https://docs.rs/softbuffer/latest/softbuffer/struct.Buffer.html#data-representation
6pub struct ZRGB(u32);
7
8impl ZRGB {
9 const fn from_rgb8(value: RGB8) -> Self {
10 // needs be_bytes. otherwise everything is green
11 Self(u32::from_be_bytes([0, value[0], value[1], value[2]]))
12 }
13}
14
15impl From<RGB8> for ZRGB {
16 fn from(value: RGB8) -> Self {
17 Self::from_rgb8(value)
18 }
19}
20
21/// see: https://developer.apple.com/documentation/metal/mtlpixelformat/rgb10a2unorm
22#[repr(transparent)]
23#[derive(Debug, Clone, Copy)]
24pub struct RGB10A2(pub u32);
25
26impl RGB10A2 {
27 const fn from_rgb8(value: RGB8) -> Self {
28 let mut storage: u32 = 0;
29
30 let blue: u32 = (value[2] as u32 * 4) << 20;
31 storage |= blue;
32
33 let green: u32 = (value[1] as u32 * 4) << 10;
34 storage |= green;
35
36 let red: u32 = value[0] as u32 * 4;
37 storage |= red;
38
39 Self(storage)
40 }
41}
42
43impl From<RGB8> for RGB10A2 {
44 fn from(value: RGB8) -> Self {
45 Self::from_rgb8(value)
46 }
47}
48
49#[repr(transparent)]
50#[derive(Debug, Clone, Copy)]
51pub struct RGBA8(pub u32);
52
53impl From<RGB8> for RGBA8 {
54 fn from(value: RGB8) -> Self {
55 Self(u32::from_le_bytes([value[0], value[1], value[2], 0]))
56 }
57}
58
59#[repr(transparent)]
60pub struct Palette<Color>(pub [Color; PALETTE_SIZE]);
61
62// only needed, because its easier to set u8 color values than u10 by hand, so i store them in u8 and convert to RGB10A2
63impl Palette<RGB8> {
64 pub const CAMOUFLAGE: Palette<RGB8> = Palette([
65 [0, 0, 0],
66 [124, 88, 68],
67 [180, 148, 120],
68 [232, 232, 200],
69 [176, 0, 84],
70 [252, 252, 84],
71 [68, 152, 84],
72 [76, 12, 24],
73 [32, 84, 0],
74 [24, 116, 44],
75 [56, 156, 116],
76 [220, 232, 224],
77 [160, 160, 160],
78 [140, 20, 84],
79 [88, 64, 60],
80 [52, 48, 44],
81 ]);
82}
83
84// i can't do blanket impl because the two colors could be the same :(
85impl From<Palette<RGB8>> for Palette<RGB10A2> {
86 fn from(value: Palette<RGB8>) -> Self {
87 Self(value.0.map(RGB10A2::from))
88 }
89}
90
91impl From<Palette<RGB8>> for Palette<ZRGB> {
92 fn from(value: Palette<RGB8>) -> Self {
93 Self(value.0.map(ZRGB::from))
94 }
95}
96
97impl Palette<ZRGB> {
98 pub fn get_raw(&self, index: u8) -> u32 {
99 self.0[usize::from(index)].0
100 }
101}
102
103impl From<Palette<RGB8>> for Palette<RGBA8> {
104 fn from(value: Palette<RGB8>) -> Self {
105 Self(value.0.map(RGBA8::from))
106 }
107}