Skip to main content

nescore/ppu/
sprite.rs

1//
2// ppu/sprite.rs
3//
4// @author Natesh Narain <nnaraindev@gmail.com>
5// @date Mar 07 2020
6//
7
8#[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}