maurice_lib/hardware/screen/
mod.rs1pub(crate) mod color;
2
3use crate::hardware::memory::Memory;
4use crate::hardware::screen::color::{COLOR_DEPTH, PALETTE};
5use crate::int;
6use crate::raw_image::RawImage;
7
8pub const WIDTH: usize = 320;
9pub const HEIGHT: usize = 200;
10
11pub const DEFAULT_PIXEL_SIZE: usize = 3;
12
13#[derive(Debug)]
14pub struct Screen {
15 pub(crate) mouse_clic: bool,
16 pub(crate) mouse_x: int,
17 pub(crate) mouse_y: int,
18 pixels: Vec<u8>,
19 pub(crate) led: u8,
20 pub(crate) show_led: u8,
21 ratio: usize,
22}
23
24impl Screen {
25 pub fn new(ratio: usize) -> Self {
26 Screen {
27 mouse_clic: false,
28 mouse_x: -1,
29 mouse_y: -1,
30 pixels: vec![0; WIDTH * ratio * HEIGHT * ratio * COLOR_DEPTH],
31 led: 0,
32 show_led: 0,
33 ratio,
34 }
35 }
36
37 pub(crate) fn new_size(&mut self, new_size: crate::dimension::Dimension) {
38 let x_ratio = new_size.width / WIDTH;
39 let y_ratio = new_size.height / HEIGHT;
40 self.set_ratio(std::cmp::min(x_ratio, y_ratio));
41 }
42
43 fn set_ratio(&mut self, mut ratio: usize) {
44 if ratio == 0 {
45 ratio = 1;
46 }
47 self.ratio = ratio;
48 self.pixels = vec![0; WIDTH * ratio * HEIGHT * ratio * COLOR_DEPTH];
49 }
50
51 pub(crate) fn paint(&mut self, mem: &mut Memory) {
52 self.dopaint(mem);
53 if self.show_led > 0 {
54 self.show_led -= 1;
55 let sec = if self.led != 0 {
56 [0xFF, 0x00, 0x00]
57 } else {
58 [0x00, 0x00, 0x00]
59 };
60 let mut line = Vec::with_capacity(16 * self.ratio * sec.len());
61 for _ in 0..16 * self.ratio {
62 line.extend(sec);
63 }
64 let pixels = &mut self.pixels;
65 for y in 1..17 {
66 let start = y * WIDTH * self.ratio * self.ratio * COLOR_DEPTH - line.len();
67 let slice = &mut pixels[start..start + line.len()];
68 slice.copy_from_slice(&line);
69 }
70 }
71 }
72
73 pub fn get_pixels(&mut self) -> RawImage {
74 RawImage::new_with_data(WIDTH * self.ratio, HEIGHT * self.ratio, &self.pixels)
75 }
76
77 pub(crate) fn dopaint(&mut self, mem: &mut Memory) {
78 let mut i = 0;
79
80 let pixels = &mut self.pixels;
81 for y in 0..HEIGHT {
82 let offset = y * WIDTH * self.ratio * self.ratio * COLOR_DEPTH;
83 if !mem.is_dirty(y) {
84 i += 40;
85 } else {
86 let mut x = 0;
87 for _ in 0..40 {
88 let col = mem.COLOR(i);
89 let c2 = (col & 0x0F) as usize;
90 let c1 = (col >> 4) as usize;
91 let cc2 = &PALETTE[c1];
92 let cc1 = &PALETTE[c2];
93
94 let pt = mem.POINT(i);
95 const PATTERN: [int; 8] = [0x80, 0x40, 0x20, 0x10, 0x08, 0x04, 0x02, 0x01];
96 for v in PATTERN {
97 for _ in 0..self.ratio {
98 let range_start = x * COLOR_DEPTH + offset;
99 let pixel_range = range_start..range_start + COLOR_DEPTH;
100 if (v & pt) != 0 {
101 pixels[pixel_range].copy_from_slice(cc2);
102 } else {
103 pixels[pixel_range].copy_from_slice(cc1);
104 }
105 x += 1;
106 }
107 }
108 i += 1;
109 }
110 }
111 for a in 1..self.ratio {
112 pixels.copy_within(
113 offset..offset + WIDTH * COLOR_DEPTH * self.ratio,
114 offset + WIDTH * self.ratio * COLOR_DEPTH * a,
115 );
116 }
117 }
118 }
119}