1pub struct Display {
3 pub display: [[u8; 128]; 64],
5 pub dirty: bool,
9 pub clear: bool,
12 pub hires: bool,
14 pub width: u8,
16 pub height: u8,
18 pub active_plane: u8,
20}
21
22impl Display {
23 pub fn new() -> Display {
25 Display {
26 display: [[0; 128]; 64],
27 dirty: false,
28 clear: true,
29 hires: false,
30 width: 64,
31 height: 32,
32 active_plane: 1,
33 }
34 }
35
36 pub fn clear(&mut self, all_planes: bool) {
38 for y in self.display.iter_mut() {
39 for pixel in y.iter_mut() {
40 if all_planes {
41 *pixel = 0;
42 } else {
43 *pixel &= !self.active_plane;
44 }
45 }
46 }
47
48 self.dirty = true;
49 self.clear = true;
50 }
51
52 pub fn draw(&mut self, sprite: Vec<Vec<u8>>, x: u8, y: u8) -> u8 {
55 let x = x % self.width as u8;
56 let y = y % self.height as u8;
57 let mut collision = 0;
58 for (row, sprite_row) in sprite.into_iter().enumerate() {
59 if row + y as usize >= self.height as usize {
60 break;
61 }
62 for (col, pixel) in sprite_row.iter().enumerate() {
63 if col + x as usize >= self.width as usize {
64 break;
65 }
66 if *pixel == 1 {
67 let display_pixel = &mut self.display[y as usize + row][x as usize + col];
68 if *display_pixel & self.active_plane == 0 {
69 *display_pixel |= self.active_plane;
70 } else {
71 *display_pixel &= !self.active_plane;
72 collision = 1;
73 };
74 }
75 }
76 }
77 self.clear = false;
78 self.dirty = true;
79 collision
80 }
81
82 pub fn scroll_up(&mut self, pixels: u8) {
84 if !self.clear && pixels > 0 {
85 for y in pixels..self.height {
86 for x in 0..self.width {
87 self.display[(y - pixels) as usize][x as usize] |=
88 self.display[y as usize][x as usize] & self.active_plane;
89 self.display[y as usize][x as usize] &= !self.active_plane;
90 }
91 }
92 for y in (self.height - pixels)..self.height {
93 for x in 0..=self.width {
94 self.display[y as usize][x as usize] &= !self.active_plane;
95 }
96 }
97
98 self.dirty = true;
99 }
100 }
101
102 pub fn scroll_down(&mut self, pixels: u8) {
104 if !self.clear && pixels > 0 {
105 for y in (0..self.height - pixels).rev() {
106 for x in 0..self.width {
107 self.display[(y + pixels) as usize][x as usize] |=
108 self.display[y as usize][x as usize] & self.active_plane;
109 self.display[y as usize][x as usize] &= !self.active_plane;
110 }
111 }
112 for y in 0..pixels {
113 for x in 0..self.width {
114 self.display[y as usize][x as usize] &= !self.active_plane;
115 }
116 }
117
118 self.dirty = true;
119 }
120 }
121
122 pub fn scroll_left(&mut self, pixels: u8) {
124 if !self.clear && pixels > 0 {
125 for y in 0..self.height {
126 for x in pixels..self.width {
127 self.display[y as usize][(x - pixels) as usize] |=
128 self.display[y as usize][x as usize] & self.active_plane;
129 self.display[y as usize][x as usize] &= !self.active_plane;
130 }
131 }
132 for y in 0..self.height {
133 for x in (self.width - pixels)..self.width {
134 self.display[y as usize][x as usize] &= !self.active_plane;
135 }
136 }
137
138 self.dirty = true;
139 }
140 }
141
142 pub fn scroll_right(&mut self, pixels: u8) {
144 if !self.clear && pixels > 0 {
145 for y in 0..self.height {
146 for x in (0..self.width - pixels).rev() {
147 self.display[y as usize][(x + pixels) as usize] |=
148 self.display[y as usize][x as usize] & self.active_plane;
149 self.display[y as usize][x as usize] &= !self.active_plane;
150 }
151 }
152 for y in 0..self.height {
153 for x in 0..pixels {
154 self.display[y as usize][x as usize] &= !self.active_plane;
155 }
156 }
157
158 self.dirty = true;
159 }
160 }
161
162 pub fn plane(&mut self, plane: u8) {
164 self.active_plane = plane;
165 }
166
167 pub fn hires(&mut self, clear: bool) {
169 self.hires = true;
170 self.width = 128;
171 self.height = 64;
172 if clear && !self.clear {
173 self.clear(true);
174 self.clear = true;
175 }
176 }
177
178 pub fn lores(&mut self, clear: bool) {
180 self.hires = false;
181 self.width = 64;
182 self.height = 32;
183 if clear && !self.clear {
184 self.clear(true);
185 self.clear = true;
186 }
187 }
188}
189
190impl Default for Display {
191 fn default() -> Self {
192 Self::new()
193 }
194}