1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
|
use super::*;
macro_rules! test { ($value:expr, $mask:expr) => { $value & $mask != 0 }; }
pub struct SpriteBuffer {
data: [u8; 16],
pointer: usize,
colours: [u8; 4],
}
impl SpriteBuffer {
pub fn new() -> Self {
Self { data: [0; 16], pointer: 0, colours: [0; 4] }
}
pub fn push(&mut self, val: u8) {
self.data[self.pointer] = val;
self.pointer = (self.pointer + 1) % 16;
}
pub fn set_colour_high(&mut self, val: u8) {
self.colours[0] = val >> 4;
self.colours[1] = val & 0x0f;
}
pub fn set_colour_low(&mut self, val: u8) {
self.colours[2] = val >> 4;
self.colours[3] = val & 0x0f;
}
// Return the 64 transformed pixels of the current 1-bit sprite.
// Each pixel is the palette index of that pixel, or 0xff if transparent.
pub fn get_1bit_sprite(&self, params: u8) -> Sprite {
let mut sprite = [[0u8; 8]; 8];
let plane = self.get_low_plane(params);
let colours = self.get_colours(params);
for (y, row) in plane.into_iter().enumerate() {
for x in (0..8).rev() {
sprite[y][7-x] = colours[(row >> x & 0x1) as usize];
}
}
return sprite;
}
// Return the 64 transformed pixels of the current 2-bit sprite.
// Each pixel is the palette index of that pixel, or 0xff if transparent.
pub fn get_2bit_sprite(&self, params: u8) -> Sprite {
let mut sprite = [[0u8; 8]; 8];
let high_plane = self.get_high_plane(params);
let low_plane = self.get_low_plane(params);
let colours = self.get_colours(params);
for (y, (row_h, row_l)) in zip(high_plane, low_plane).enumerate() {
for x in (0..8).rev() {
let bit_h = (row_h >> x) & 0x1;
let bit_l = (row_l >> x) & 0x1;
sprite[y][7-x] = colours[(bit_h << 1 | bit_l) as usize];
}
}
return sprite;
}
fn get_high_plane(&self, params: u8) -> Plane {
let mut plane = [0u8; 8];
for (i, row) in plane.iter_mut().enumerate() {
*row = self.data[(self.pointer + i) % 16]
}
transform_plane(plane, params)
}
fn get_low_plane(&self, params: u8) -> Plane {
let mut plane = [0u8; 8];
for (i, row) in plane.iter_mut().enumerate() {
*row = self.data[(self.pointer + i + 8) % 16]
}
transform_plane(plane, params)
}
fn get_colours(&self, params: u8) -> [u8; 4] {
let mut colours = self.colours;
if test!(params, TRANSPARENT) {
colours[0] = 0xff;
}
return colours;
}
}
fn transform_plane(mut plane: Plane, params: u8) -> Plane {
if test!(params, FLIP_DIAGONAL) {
let mut flipped = [0u8; 8];
for mut row in plane {
for y in 0..8 {
flipped[y] = flipped[y] << 1 | row >> 7;
row <<= 1;
}
}
plane = flipped;
}
if test!(params, FLIP_VERTICAL) {
plane.reverse();
}
if test!(params, FLIP_HORIZONTAL) {
for row in plane.iter_mut() {
*row = row.reverse_bits();
}
}
return plane;
}
|