From 39dfe987cbd99f42d85ea1a0c7d5df866fe739e5 Mon Sep 17 00:00:00 2001 From: Ben Bridle Date: Wed, 20 Nov 2024 10:42:57 +1300 Subject: Cache transformed sprite data In programs where the same sprite is drawn many times repeatedly, a lot of time is saved by caching the transformed sprite data instead of having to recalculate it for every draw operation. No testing has been done on the efficiency improvements this offers, but it doesn't seem like it could have any downsides. --- src/devices/screen_device.rs | 19 +++++++++++++++++-- 1 file changed, 17 insertions(+), 2 deletions(-) (limited to 'src/devices') diff --git a/src/devices/screen_device.rs b/src/devices/screen_device.rs index b4eae22..a10ab20 100644 --- a/src/devices/screen_device.rs +++ b/src/devices/screen_device.rs @@ -419,6 +419,7 @@ impl HasDimensions for ScreenDevice { pub struct SpriteBuffer { pub mem: [u8; 16], pub pointer: usize, + pub cached: Option<(Sprite, u8)>, } impl SpriteBuffer { @@ -426,15 +427,22 @@ impl SpriteBuffer { Self { mem: [0; 16], pointer: 0, + cached: None, } } pub fn push_byte(&mut self, byte: u8) { self.mem[self.pointer] = byte; self.pointer = (self.pointer + 1) % 16; + self.cached = None; } - pub fn read_1bit_sprite(&self, draw: u8) -> Sprite { + pub fn read_1bit_sprite(&mut self, draw: u8) -> Sprite { + if let Some((sprite, transform)) = self.cached { + if transform == (draw & 0x77) { + return sprite; + } + } macro_rules! c { ($v:ident=mem[$p:ident++]) => { let $v = self.mem[$p % 16]; $p = $p.wrapping_add(1); }; ($v:ident=mem[--$p:ident]) => { $p = $p.wrapping_sub(1); let $v = self.mem[$p % 16]; }; @@ -455,10 +463,16 @@ impl SpriteBuffer { 0x7 => { for y in 0..8 { c!(l=mem[--p]); for x in 0..8 { sprite[x][y] = l>>( x) & 1; } } }, _ => unreachable!(), } + self.cached = Some((sprite, draw & 0x77)); return sprite; } - pub fn read_2bit_sprite(&self, draw: u8) -> Sprite { + pub fn read_2bit_sprite(&mut self, draw: u8) -> Sprite { + if let Some((sprite, transform)) = self.cached { + if transform == (draw & 0x77) { + return sprite; + } + } macro_rules! c { ($v:ident=mem[$p:ident++]) => { let $v = self.mem[$p % 16]; $p = $p.wrapping_add(1); }; ($v:ident=mem[--$p:ident]) => { $p = $p.wrapping_sub(1); let $v = self.mem[$p % 16]; }; @@ -480,6 +494,7 @@ impl SpriteBuffer { 0x7 => for y in 0..8 { c!(l=mem[--p]); c!(h=mem[--s]); for x in 0..8 { let i= x; sprite[x][y] = (l>>i & 1) | (h>>i & 1) << 1; } }, _ => unreachable!(), } + self.cached = Some((sprite, draw & 0x77)); return sprite; } } -- cgit v1.2.3-70-g09d2