summaryrefslogtreecommitdiff
path: root/src/devices/screen/sprite_data.rs
diff options
context:
space:
mode:
Diffstat (limited to 'src/devices/screen/sprite_data.rs')
-rw-r--r--src/devices/screen/sprite_data.rs98
1 files changed, 87 insertions, 11 deletions
diff --git a/src/devices/screen/sprite_data.rs b/src/devices/screen/sprite_data.rs
index aade2c6..0a1d3c2 100644
--- a/src/devices/screen/sprite_data.rs
+++ b/src/devices/screen/sprite_data.rs
@@ -1,11 +1,17 @@
-pub struct SpriteData {
+use super::*;
+
+macro_rules! test { ($value:expr, $mask:expr) => { $value & $mask != 0 }; }
+
+
+pub struct SpriteBuffer {
data: [u8; 16],
pointer: usize,
+ colours: [u8; 4],
}
-impl SpriteData {
+impl SpriteBuffer {
pub fn new() -> Self {
- Self { data: [0; 16], pointer: 0 }
+ Self { data: [0; 16], pointer: 0, colours: [0; 4] }
}
pub fn push(&mut self, val: u8) {
@@ -13,21 +19,91 @@ impl SpriteData {
self.pointer = (self.pointer + 1) % 16;
}
- pub fn get_1bit_sprite(&self) -> [u8; 8] {
- let mut sprite = [0u8; 8];
- for (i, r) in sprite.iter_mut().enumerate() {
- *r = self.data[(self.pointer + i + 8) % 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;
}
- pub fn get_2bit_sprite(&self) -> [u8; 16] {
- let mut sprite = [0u8; 16];
- for (i, r) in sprite.iter_mut().enumerate() {
- *r = self.data[(self.pointer + i) % 16]
+ // 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;
+}