summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--src/devices/screen.rs74
1 files changed, 45 insertions, 29 deletions
diff --git a/src/devices/screen.rs b/src/devices/screen.rs
index 0b5e571..75f0e57 100644
--- a/src/devices/screen.rs
+++ b/src/devices/screen.rs
@@ -370,43 +370,59 @@ impl ScreenDevice {
}
fn draw_rect(&mut self, colour: u8, layer: ScreenLayer) {
- let [start, end] = self.vector.get_pair();
- let dim = self.dimensions;
- let x0 = min(start.x, end.x);
- let x1 = max(start.x, end.x);
- let y0 = min(start.y, end.y);
- let y1 = max(start.y, end.y);
- if (x0 >= dim.width && x1 >= dim.width) || (y0 >= dim.height && y1 >= dim.height) { return }
- let x0 = min(x0, dim.width.saturating_sub(1)) as usize;
- let x1 = min(x1, dim.width.saturating_sub(1)) as usize;
- let y0 = min(y0, dim.height.saturating_sub(1)) as usize;
- let y1 = min(y1, dim.height.saturating_sub(1)) as usize;
- let width = x1 - x0 + 1;
- let mut i = x0 + ((dim.width as usize) * y0);
+ let [x0, y0, x1, y1] = {
+ macro_rules! raise {($v:expr) => {$v.wrapping_add(0x8000)};}
+ macro_rules! lower {($v:expr) => {$v.wrapping_sub(0x8000)};}
+ let [p0, p1] = self.vector.get_pair();
+ let [p0x, p0y] = [ raise!(p0.x), raise!(p0.y) ];
+ let [p1x, p1y] = [ raise!(p1.x), raise!(p1.y) ];
+ let [x0, y0] = [ min(p0x, p1x), min(p0y, p1y) ];
+ let [x1, y1] = [ max(p0x, p1x), max(p0y, p1y) ];
+ let right = self.dimensions.width.saturating_sub(1);
+ let bottom = self.dimensions.height.saturating_sub(1);
+ if x0 > raise!(right) || y0 > raise!(bottom) || x1 < 0x8000 || y1 < 0x8000 { return }
+ [
+ if x0 < 0x8000 { 0 } else { min(lower!(x0), right) } as usize,
+ if y0 < 0x8000 { 0 } else { min(lower!(y0), bottom) } as usize,
+ if x1 < 0x8000 { 0 } else { min(lower!(x1), right) } as usize,
+ if y1 < 0x8000 { 0 } else { min(lower!(y1), bottom) } as usize,
+ ]
+ };
+ let screen_width = self.dimensions.width as usize;
+ let rect_width = x1 - x0 + 1;
+ let mut i = x0 + (screen_width * y0);
let pixels = match layer {
ScreenLayer::Background => &mut self.background,
ScreenLayer::Foreground => &mut self.foreground,
};
for _ in y0..=y1 {
- pixels[i..i+width].fill(colour);
- i += dim.width as usize;
+ pixels[i..i+rect_width].fill(colour);
+ i += screen_width;
}
}
fn draw_rect_1bit(&mut self, params: u8, layer: ScreenLayer) {
- let [start, end] = self.vector.get_pair();
- let dim = self.dimensions;
- let x0 = min(start.x, end.x);
- let x1 = max(start.x, end.x);
- let y0 = min(start.y, end.y);
- let y1 = max(start.y, end.y);
- if (x0 >= dim.width && x1 >= dim.width) || (y0 >= dim.height && y1 >= dim.height) { return }
- let x0 = min(x0, dim.width.saturating_sub(1)) as usize;
- let x1 = min(x1, dim.width.saturating_sub(1)) as usize;
- let y0 = min(y0, dim.height.saturating_sub(1)) as usize;
- let y1 = min(y1, dim.height.saturating_sub(1)) as usize;
- let width = x1 - x0 + 1;
- let mut i = x0 + ((dim.width as usize) * y0);
+ let [x0, y0, x1, y1] = {
+ macro_rules! raise {($v:expr) => {$v.wrapping_add(0x8000)};}
+ macro_rules! lower {($v:expr) => {$v.wrapping_sub(0x8000)};}
+ let [p0, p1] = self.vector.get_pair();
+ let [p0x, p0y] = [ raise!(p0.x), raise!(p0.y) ];
+ let [p1x, p1y] = [ raise!(p1.x), raise!(p1.y) ];
+ let [x0, y0] = [ min(p0x, p1x), min(p0y, p1y) ];
+ let [x1, y1] = [ max(p0x, p1x), max(p0y, p1y) ];
+ let right = self.dimensions.width.saturating_sub(1);
+ let bottom = self.dimensions.height.saturating_sub(1);
+ if x0 > raise!(right) || y0 > raise!(bottom) || x1 < 0x8000 || y1 < 0x8000 { return }
+ [
+ if x0 < 0x8000 { 0 } else { min(lower!(x0), right) } as usize,
+ if y0 < 0x8000 { 0 } else { min(lower!(y0), bottom) } as usize,
+ if x1 < 0x8000 { 0 } else { min(lower!(x1), right) } as usize,
+ if y1 < 0x8000 { 0 } else { min(lower!(y1), bottom) } as usize,
+ ]
+ };
+ let screen_width = self.dimensions.width as usize;
+ let rect_width = x1 - x0 + 1;
+ let mut i = x0 + (screen_width * y0);
let pixels = match layer {
ScreenLayer::Background => &mut self.background,
ScreenLayer::Foreground => &mut self.foreground,
@@ -431,7 +447,7 @@ impl ScreenDevice {
i += 1;
}
sprite_i = (sprite_i + 1) % 8;
- i += (dim.width as usize) - width;
+ i += screen_width - rect_width;
}
}