diff --git a/TODO.md b/TODO.md
index 482a063..5bdc8d5 100644
--- a/TODO.md
+++ b/TODO.md
@@ -50,9 +50,6 @@
It would be cute if the screen did a side-to-side animation on each
press as well.
-(5) Crash when you try to go below the bottom
- If you're moving down and you hit the bottom edge, we crash.
-
(6) Lines with a positive slope draw wrong
When you're diagonaling right and up, the line draws almost-inverted
and comes out as right and down, but it's more than that. Seemingly,
@@ -87,4 +84,18 @@
because i wrote the smallest winit program, none-surface-left-beef, that's only
job was to make a winit window. It used 11MB. Our surfaces, assuming that
softbuffer holds only one buffer in memory, was ~5.2MB (~5MB for the 640x480 window
- at a 2x scale, and ~1.2MB for 640x480 (both using u32s for pixels)).
\ No newline at end of file
+ at a 2x scale, and ~1.2MB for 640x480 (both using u32s for pixels)).
+
+(5) Crash when you try to go below the bottom
+ If you're moving down and you hit the bottom edge, we crash.
+
+ DONE
+ this was because in image.rs Image::rect() we do not check that we
+ are only drawing within bounds, and our lines (secretly many rects)
+ were 2 wide. so when we draw the stylus, which is also two-wide, it
+ would try to draw below the image and crash.
+ this also happened on the horizontal but it was wrap back around to
+ the left edge. humorously the in-bounds check used to only be done
+ when we handled the joystick events, which was not every frame. so
+ the keyboard could make it significantly past the right-edge and do
+ a little drawing past that on the left.
\ No newline at end of file
diff --git a/src/image.rs b/src/image.rs
index 177eff2..5b6cb33 100644
--- a/src/image.rs
+++ b/src/image.rs
@@ -73,11 +73,18 @@ impl Image {
}
pub fn rect(&mut self, pos: Vec2<u32>, dim: Vec2<u32>, clr: Color) {
+ if pos.x >= self.width || pos.y >= self.height {
+ // if we're fully over in one of these directions, we shouldn't go further.
+ return;
+ }
+
+ // .min(..) so we only draw what we can see/what's within bounds
let x_start = pos.x as usize;
- let x_end = (pos.x + dim.x) as usize;
+ let x_end = (pos.x + dim.x).min(self.width - 1) as usize;
+ let y_end = (pos.y + dim.y).min(self.height - 1) as usize;
for idx in x_start..x_end {
- for idy in pos.y as usize..pos.y as usize + dim.y as usize {
+ for idy in pos.y as usize..y_end {
let data_idx = idx + idy * self.width as usize;
self.data[data_idx] = clr.into();
}
diff --git a/src/main.rs b/src/main.rs
index 59d004f..dc3989a 100644
--- a/src/main.rs
+++ b/src/main.rs
@@ -132,6 +132,20 @@ impl Etch {
gif.save(path).unwrap();
}
}
+
+ pub fn keep_stylus_inbounds(&mut self) {
+ if self.stylus.x < 0.0 {
+ self.stylus.x = 0.0;
+ } else if self.stylus.x > self.img.width() as f32 - 1.0 {
+ self.stylus.x = self.img.width() as f32 - 1.0;
+ }
+
+ if self.stylus.y < 0.0 {
+ self.stylus.y = 0.0
+ } else if self.stylus.y > self.img.height() as f32 - 1.0 {
+ self.stylus.y = self.img.height() as f32 - 1.0;
+ }
+ }
}
// Why are my consts HERE of all places
@@ -240,10 +254,8 @@ impl ApplicationHandler for Etch {
let movement_x = left_delta / DIAL_SENSITIVITY;
let movement_y = right_delta / DIAL_SENSITIVITY;
- self.stylus.x =
- (self.stylus.x + movement_x).clamp(0.0, self.img.width() as f32);
- self.stylus.y =
- (self.stylus.y - movement_y).clamp(0.0, self.img.height() as f32);
+ self.stylus.x = self.stylus.x + movement_x;
+ self.stylus.y = self.stylus.y - movement_y;
self.next_check = Instant::now();
}
@@ -280,6 +292,8 @@ impl ApplicationHandler for Etch {
}
}
+ self.keep_stylus_inbounds();
+
// If the stylus moved, we should draw
if stylus_prev != self.stylus {
self.img.line(
|