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)]
60#[derive(Clone, Copy)]
61pub struct Palette<Color>(pub [Color; PALETTE_SIZE]);
62
63// only needed, because its easier to set u8 color values than u10 by hand, so i store them in u8 and convert to RGB10A2
64impl Palette<RGB8> {
65 pub const CAMOUFLAGE: Palette<RGB8> = Palette([
66 [0, 0, 0],
67 [124, 88, 68],
68 [180, 148, 120],
69 [232, 232, 200],
70 [176, 0, 84],
71 [252, 252, 84],
72 [68, 152, 84],
73 [76, 12, 24],
74 [32, 84, 0],
75 [24, 116, 44],
76 [56, 156, 116],
77 [220, 232, 224],
78 [160, 160, 160],
79 [140, 20, 84],
80 [88, 64, 60],
81 [52, 48, 44],
82 ]);
83}
84
85// i can't do blanket impl because the two colors could be the same :(
86impl From<Palette<RGB8>> for Palette<RGB10A2> {
87 fn from(value: Palette<RGB8>) -> Self {
88 Self(value.0.map(RGB10A2::from))
89 }
90}
91
92impl From<Palette<RGB8>> for Palette<ZRGB> {
93 fn from(value: Palette<RGB8>) -> Self {
94 Self(value.0.map(ZRGB::from))
95 }
96}
97
98impl Palette<ZRGB> {
99 pub fn get_raw(&self, index: u8) -> u32 {
100 self.0[usize::from(index)].0
101 }
102}
103
104impl From<Palette<RGB8>> for Palette<RGBA8> {
105 fn from(value: Palette<RGB8>) -> Self {
106 Self(value.0.map(RGBA8::from))
107 }
108}