1#[derive(Default, Copy, Clone)]
9pub struct Sprite {
10 pub y: u16,
11 pub x: u8,
12 pub tile: u8,
13 attr: u8,
14 pub num: u8,
15}
16
17impl Sprite {
18 pub fn from(data: &[u8], num: u8) -> Self {
19 Sprite {
20 y: ((data[0] as u16) + 1),
21 x: data[3],
22 tile: data[1],
23 attr: data[2],
24 num,
25 }
26 }
27
28 pub fn palette(&self) -> u8 {
29 self.attr & 0x03
30 }
31
32 pub fn priority(&self) -> bool {
33 bit_is_set!(self.attr, 5)
34 }
35
36 pub fn flip_v(&self) -> bool {
37 bit_is_set!(self.attr, 7)
38 }
39
40 pub fn flip_h(&self) -> bool {
41 bit_is_set!(self.attr, 6)
42 }
43
44 pub fn pattern_table_8x16(&self) -> u16 {
45 (self.tile & 0x01) as u16 * 0x1000
46 }
47
48 pub fn tile_number_8x16(&self) -> u8 {
49 self.tile & 0xFE
50 }
51}
52
53#[cfg(test)]
54mod tests {
55 use super::*;
56
57 #[test]
58 fn load_from_slice() {
59 let data: [u8; 4] = [0, 2, 0, 3];
60 let sprite = Sprite::from(&data[..], 0);
61
62 assert_eq!(sprite.x, 3);
63 assert_eq!(sprite.y, 1);
64 assert_eq!(sprite.tile, 2);
65 }
66
67
68 #[test]
69 fn sprite_attributes() {
70 let data: [u8; 4] = [0, 0, 0xFF, 0];
71 let sprite = Sprite::from(&data[..], 0);
72
73 assert_eq!(sprite.palette(), 3);
74 assert_eq!(sprite.priority(), true);
75 assert_eq!(sprite.flip_v(), true);
76 assert_eq!(sprite.flip_h(), true);
77 }
78
79 #[test]
80 fn sprite_y_255() {
81 let data: [u8; 4] = [255, 0, 0, 0];
82 let sprite = Sprite::from(&data[..], 0);
83
84 assert_eq!(sprite.y, 256);
85 }
86
87 #[test]
88 fn sprite_8x16_mode() {
89 let data: [u8; 4] = [0, 0x0F, 0, 0];
90 let sprite = Sprite::from(&data[..], 0);
91
92 assert_eq!(sprite.pattern_table_8x16(), 0x1000);
93 assert_eq!(sprite.tile_number_8x16(), 0x0E);
94 }
95}