diff options
Diffstat (limited to 'src/devices/screen/draw_line.rs')
-rw-r--r-- | src/devices/screen/draw_line.rs | 223 |
1 files changed, 0 insertions, 223 deletions
diff --git a/src/devices/screen/draw_line.rs b/src/devices/screen/draw_line.rs deleted file mode 100644 index 94066f4..0000000 --- a/src/devices/screen/draw_line.rs +++ /dev/null @@ -1,223 +0,0 @@ -use super::*; - -impl ScreenDevice { - pub fn draw_line(&mut self, colour: u8, layer: ScreenLayer) { - let [p0, p1] = [self.cursor, self.vector]; - match (p0.x == p1.x, p0.y == p1.y) { - (false, false) => self.draw_diagonal_line(colour, layer), - (false, true) => self.draw_horizontal_line(colour, layer), - ( true, false) => self.draw_vertical_line(colour, layer), - ( true, true) => self.draw_pixel(colour, layer, p0), - }; - } - - pub fn draw_line_1bit(&mut self, params: u8, layer: ScreenLayer) { - let [p0, p1] = [self.cursor, self.vector]; - match (p0.x == p1.x, p0.y == p1.y) { - (false, false) => self.draw_diagonal_line_1bit(params, layer), - (false, true) => self.draw_horizontal_line_1bit(params, layer), - ( true, false) => self.draw_vertical_line_1bit(params, layer), - ( true, true) => self.draw_pixel_1bit(params, layer, p0), - }; - } - - pub fn draw_pixel_1bit(&mut self, params: u8, layer: ScreenLayer, point: ScreenPosition) { - let dim = self.dimensions; - let sprite = self.sprite_buffer.get_1bit_sprite(params); - let colour = sprite[point.y as usize % 8][point.x as usize % 8]; - if !dim.contains_point(point) || colour == 0xff { return } - let index = point.x as usize + ((dim.width as usize) * (point.y as usize)); - match layer { - ScreenLayer::Background => self.background[index] = colour, - ScreenLayer::Foreground => self.foreground[index] = colour, - }; - } - - fn draw_horizontal_line(&mut self, colour: u8, layer: ScreenLayer) { - if let Some([x0, y, x1, _]) = self.find_vector_bounding_box() { - let screen_width = self.dimensions.width as usize; - let i = screen_width * y; - let buffer = match layer { - ScreenLayer::Background => &mut self.background, - ScreenLayer::Foreground => &mut self.foreground, - }; - buffer[i+x0..=i+x1].fill(colour); - } - } - - fn draw_horizontal_line_1bit(&mut self, params: u8, layer: ScreenLayer) { - if let Some([x0, y, x1, _]) = self.find_vector_bounding_box() { - let screen_width = self.dimensions.width as usize; - let i = screen_width * y; - let buffer = match layer { - ScreenLayer::Background => &mut self.background, - ScreenLayer::Foreground => &mut self.foreground, - }; - let sprite = self.sprite_buffer.get_1bit_sprite(params); - let row = sprite[y % 8]; - for x in x0..=x1 { - let colour = row[x % 8]; - if colour != 0xff { buffer[i+x] = colour }; - } - } - } - - fn draw_vertical_line(&mut self, colour: u8, layer: ScreenLayer) { - if let Some([x, y0, _, y1]) = self.find_vector_bounding_box() { - let screen_width = self.dimensions.width as usize; - let mut i = (screen_width * y0) + x; - let buffer = match layer { - ScreenLayer::Background => &mut self.background, - ScreenLayer::Foreground => &mut self.foreground, - }; - for _ in y0..=y1 { - buffer[i] = colour; - i += screen_width; - } - } - } - - fn draw_vertical_line_1bit(&mut self, params: u8, layer: ScreenLayer) { - if let Some([x, y0, _, y1]) = self.find_vector_bounding_box() { - let screen_width = self.dimensions.width as usize; - let mut i = (screen_width * y0) + x; - let buffer = match layer { - ScreenLayer::Background => &mut self.background, - ScreenLayer::Foreground => &mut self.foreground, - }; - let sprite = self.sprite_buffer.get_1bit_sprite(params); - let mut column = [0u8; 8]; - for y in 0..8 { column[y] = sprite[y][x % 8] } - for y in y0..=y1 { - let colour = column[y % 8]; - if colour != 0xff { buffer[i] = colour }; - i += screen_width; - } - } - } - - fn draw_diagonal_line(&mut self, colour: u8, layer: ScreenLayer) { - fn abs_diff(v0: u16, v1: u16) -> u16 { - let v = v1.wrapping_sub(v0); - if v > 0x8000 { !v + 1 } else { v } - } - let [p0, p1] = [self.cursor, self.vector]; - - // If the slope of the line is greater than 1. - if abs_diff(p0.y, p1.y) > abs_diff(p0.x, p1.x) { - // Swap points 0 and 1 such that y0 is always smaller than y1. - let (x0, y0, x1, y1) = match p0.y > p1.y { - true => (p1.x, p1.y, p0.x, p0.y), - false => (p0.x, p0.y, p1.x, p1.y), - }; - let dy = y1 - y0; - let (dx, xi) = match x0 > x1 { - true => (x0 - x1, 0xffff), - false => (x1 - x0, 0x0001), - }; - let dxdy2 = (dx.wrapping_sub(dy)).wrapping_mul(2); - let dx2 = dx * 2; - let mut d = dx2.wrapping_sub(dy); - let mut x = x0; - - for y in y0..=y1 { - self.draw_pixel(colour, layer, ScreenPosition::new(x, y)); - if d < 0x8000 { - x = x.wrapping_add(xi); d = d.wrapping_add(dxdy2); - } else { - d = d.wrapping_add(dx2); - } - } - // If the slope of the line is less than or equal to 1. - } else { - // Swap points 0 and 1 so that x0 is always smaller than x1. - let (x0, y0, x1, y1) = match p0.x > p1.x { - true => (p1.x, p1.y, p0.x, p0.y), - false => (p0.x, p0.y, p1.x, p1.y), - }; - let dx = x1 - x0; - let (dy, yi) = match y0 > y1 { - true => (y0 - y1, 0xffff), - false => (y1 - y0, 0x0001), - }; - let dydx2 = (dy.wrapping_sub(dx)).wrapping_mul(2); - let dy2 = dy * 2; - let mut d = dy2.wrapping_sub(dx); - let mut y = y0; - - for x in x0..=x1 { - self.draw_pixel(colour, layer, ScreenPosition::new(x, y)); - if d < 0x8000 { - y = y.wrapping_add(yi); - d = d.wrapping_add(dydx2); - } else { - d = d.wrapping_add(dy2); - } - } - } - } - - fn draw_diagonal_line_1bit(&mut self, params: u8, layer: ScreenLayer) { - fn abs_diff(v0: u16, v1: u16) -> u16 { - let v = v1.wrapping_sub(v0); - if v > 0x8000 { !v + 1 } else { v } - } - let [p0, p1] = [self.cursor, self.vector]; - - // If the slope of the line is greater than 1. - if abs_diff(p0.y, p1.y) > abs_diff(p0.x, p1.x) { - // Swap points 0 and 1 such that y0 is always smaller than y1. - let (x0, y0, x1, y1) = match p0.y > p1.y { - true => (p1.x, p1.y, p0.x, p0.y), - false => (p0.x, p0.y, p1.x, p1.y), - }; - let dy = y1 - y0; - let (dx, xi) = match x0 > x1 { - true => (x0 - x1, 0xffff), - false => (x1 - x0, 0x0001), - }; - let dxdy2 = (dx.wrapping_sub(dy)).wrapping_mul(2); - let dx2 = dx * 2; - let mut d = dx2.wrapping_sub(dy); - let mut x = x0; - - for y in y0..=y1 { - self.draw_pixel_1bit(params, layer, ScreenPosition::new(x, y)); - if d < 0x8000 { - x = x.wrapping_add(xi); d = d.wrapping_add(dxdy2); - } else { - d = d.wrapping_add(dx2); - } - } - // If the slope of the line is less than or equal to 1. - } else { - // Swap points 0 and 1 so that x0 is always smaller than x1. - let (x0, y0, x1, y1) = match p0.x > p1.x { - true => (p1.x, p1.y, p0.x, p0.y), - false => (p0.x, p0.y, p1.x, p1.y), - }; - let dx = x1 - x0; - let (dy, yi) = match y0 > y1 { - true => (y0 - y1, 0xffff), - false => (y1 - y0, 0x0001), - }; - let dydx2 = (dy.wrapping_sub(dx)).wrapping_mul(2); - let dy2 = dy * 2; - let mut d = dy2.wrapping_sub(dx); - let mut y = y0; - - for x in x0..=x1 { - self.draw_pixel_1bit(params, layer, ScreenPosition::new(x, y)); - if d < 0x8000 { - y = y.wrapping_add(yi); - d = d.wrapping_add(dydx2); - } else { - d = d.wrapping_add(dy2); - } - } - } - } - - - -} |