From 81a6b0da7a507214a01dc3a4513d8b73525e4381 Mon Sep 17 00:00:00 2001
From: Ben Bridle <ben@derelict.engineering>
Date: Mon, 4 Nov 2024 13:06:36 +1300
Subject: Fix issue when drawing textured shapes off-screen

When determining whether or not to draw each pixel of a textured line
or rectangle, the modulo-by-eight operation was being performed on a
signed value, which was returning a negative value when the pixel being
drawn was off-screen. When the negative value was then converted to an
unsigned value, the result was close to usize::MAX, and was causing an
out-of-bounds array access.

To fix this, the value is converted to an unsigned value before taking
the modulo.
---
 src/devices/screen_device.rs | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)

diff --git a/src/devices/screen_device.rs b/src/devices/screen_device.rs
index 64f3815..73cfcae 100644
--- a/src/devices/screen_device.rs
+++ b/src/devices/screen_device.rs
@@ -283,7 +283,7 @@ impl ScreenDevice {
             let c0 = (self.colours >> 12 & 0xf) as u8;
             let opaque = draw & 0x08 == 0;
             loop {
-                let sprite_pixel = sprite[(y % 8) as usize][(x % 8) as usize];
+                let sprite_pixel = sprite[(y as usize) % 8][(x as usize) % 8];
                 if sprite_pixel != 0 { self.draw_pixel(layer, x as u16, y as u16, c1); }
                 else if opaque       { self.draw_pixel(layer, x as u16, y as u16, c0); }
                 if x == x_end && y == y_end { break; }
@@ -338,7 +338,7 @@ impl ScreenDevice {
             let opaque = draw & 0x08 == 0;
             for y in t..=b {
                 for x in l..=r {
-                    let sprite_colour = sprite[(y % 8) as usize][(x % 8) as usize];
+                    let sprite_colour = sprite[(y as usize) % 8][(x as usize) % 8];
                     if sprite_colour != 0 { self.draw_pixel(layer, x, y, c1); }
                     else if opaque        { self.draw_pixel(layer, x, y, c0); }
                 }
-- 
cgit v1.2.3-70-g09d2