1use crate::graphics::sprite::{byte4, byte5};
2use crate::models::{Byteable, Sprite};
3
4impl Sprite {
5 #[allow(clippy::too_many_arguments)]
6 pub fn new(
7 x: usize,
8 y: usize,
9 id: usize,
10 flip_v: bool,
11 flip_h: bool,
12 palette: usize,
13 large: bool,
14 order: usize,
15 half_alpha: bool,
16 rotated: bool,
17 atlas: usize,
18 enabled: bool,
19 ) -> Self {
20 Self {
21 x,
22 y,
23 id,
24 flip_v,
25 flip_h,
26 palette,
27 large,
28 order,
29 half_alpha,
30 rotated,
31 atlas,
32 enabled,
33 }
34 }
35}
36
37impl Byteable for Sprite {
38 const SIZE: usize = 5;
39
40 fn from_bytes(bytes: &[u8]) -> Sprite {
41 Sprite {
42 x: bytes[0] as usize,
43 y: bytes[1] as usize,
44 id: bytes[2] as usize,
45 flip_v: bytes[3] & byte4::MASK_FLIP_V == byte4::MASK_FLIP_V,
46 flip_h: bytes[3] & byte4::MASK_FLIP_H == byte4::MASK_FLIP_H,
47 palette: (bytes[4] & byte5::MASK_PALETTE) as usize,
48 large: bytes[4] & byte5::MASK_LARGE == byte5::MASK_LARGE,
49 order: ((bytes[4] & byte5::MASK_ORDER) >> byte5::OFFSET_ORDER) as usize,
50 half_alpha: bytes[3] & byte4::MASK_HALF_ALPHA == byte4::MASK_HALF_ALPHA,
51 rotated: bytes[3] & byte4::MASK_ROTATED == byte4::MASK_ROTATED,
52 atlas: ((bytes[4] & byte5::MASK_ATLAS) >> byte5::OFFSET_ATLAS) as usize,
53 enabled: bytes[3] & byte4::MASK_ENABLED == byte4::MASK_ENABLED,
54 }
55 }
56
57 fn to_bytes(&self) -> Vec<u8> {
58 let mut byte4 = 0;
59 let mut byte5 = 0;
60 if self.flip_h {
61 byte4 |= byte4::MASK_FLIP_H;
62 }
63 if self.flip_v {
64 byte4 |= byte4::MASK_FLIP_V;
65 }
66 if self.half_alpha {
67 byte4 |= byte4::MASK_HALF_ALPHA;
68 }
69 if self.enabled {
70 byte4 |= byte4::MASK_ENABLED;
71 }
72 if self.rotated {
73 byte4 |= byte4::MASK_ROTATED;
74 }
75 if self.large {
76 byte5 |= byte5::MASK_LARGE;
77 }
78 byte5 |= (self.atlas << byte5::OFFSET_ATLAS) as u8;
79 byte5 |= (self.order << byte5::OFFSET_ORDER) as u8;
80 byte5 |= self.palette as u8;
81 vec![self.x as u8, self.y as u8, self.id as u8, byte4, byte5]
82 }
83}
84
85#[cfg(test)]
86mod test {
87 use crate::graphics::sprite::{byte4, byte5};
88 use crate::models::{Byteable, Sprite};
89
90 #[test]
91 fn write_test() {
92 let sprite = Sprite::default();
93 assert_eq!(sprite.to_bytes(), [0, 0, 0, 0, 0]);
94 let sprite = Sprite::new(255, 255, 255, true, true, 3, true, 3, true, true, 3, true);
95 assert_eq!(sprite.to_bytes(), [255, 255, 255, 241, 251]);
96 let sprite = Sprite::new(51, 120, 34, true, false, 1, true, 2, true, false, 0, true);
97 let bytes = sprite.to_bytes();
98 assert_eq!(bytes, [51, 120, 34, 161, 193]);
99 assert_eq!(bytes[3] & byte4::MASK_ENABLED, byte4::MASK_ENABLED);
100 assert_eq!(bytes[3] & byte4::MASK_FLIP_V, byte4::MASK_FLIP_V);
101 assert_eq!(bytes[3] & byte4::MASK_FLIP_H, 0);
102 assert_eq!(bytes[3] & byte4::MASK_ROTATED, 0);
103 assert_eq!(bytes[3] & byte4::MASK_HALF_ALPHA, byte4::MASK_HALF_ALPHA);
104 assert_eq!(bytes[4] & byte5::MASK_LARGE, byte5::MASK_LARGE);
105 assert_eq!((bytes[4] & byte5::MASK_ORDER) >> byte5::OFFSET_ORDER, 2);
106 assert_eq!(bytes[4] & byte5::MASK_PALETTE, 1);
107 assert_eq!((bytes[4] & byte5::MASK_ATLAS) >> byte5::OFFSET_ATLAS, 0);
108 }
109
110 #[test]
111 fn read_test() {
112 let sprite = Sprite::from_bytes(&[0, 0, 0, 0, 0]);
113 assert_eq!(sprite, Sprite::default());
114 let sprite = Sprite::from_bytes(&[255, 255, 255, 255, 255]);
115 assert_eq!(
116 sprite,
117 Sprite::new(255, 255, 255, true, true, 3, true, 3, true, true, 3, true)
118 );
119 let sprite = Sprite::from_bytes(&[
120 126,
121 69,
122 99,
123 byte4::MASK_ENABLED | byte4::MASK_FLIP_V | byte4::MASK_HALF_ALPHA,
124 byte5::MASK_LARGE | 1,
125 ]);
126 assert_eq!(
127 sprite,
128 Sprite::new(126, 69, 99, true, false, 1, true, 0, true, false, 0, true)
129 );
130 }
131}