168 ); |
168 ); |
169 } |
169 } |
170 |
170 |
171 texture |
171 texture |
172 } |
172 } |
|
173 |
|
174 // TODO: no way to pass both u8 & u32? |
|
175 pub fn make_texture32(&self, land: &Land2D<u32>, theme: &Theme) -> Vec2D<u32> { |
|
176 let mut texture = Vec2D::new(land.size(), 0); |
|
177 |
|
178 if let Some(land_sprite) = theme.land_texture() { |
|
179 for (row_index, (land_row, tex_row)) in land.rows() |
|
180 .zip(texture.rows_mut()) |
|
181 .enumerate() |
|
182 { |
|
183 let sprite_row = land_sprite.get_row(row_index % land_sprite.height()); |
|
184 let mut x_offset = 0; |
|
185 while sprite_row.len() < land.width() - x_offset { |
|
186 let copy_range = x_offset..x_offset + sprite_row.len(); |
|
187 tex_row_copy32( |
|
188 &land_row[copy_range.clone()], |
|
189 &mut tex_row[copy_range], |
|
190 sprite_row |
|
191 ); |
|
192 |
|
193 x_offset += land_sprite.width() |
|
194 } |
|
195 |
|
196 if x_offset < land.width() { |
|
197 let final_range = x_offset..land.width(); |
|
198 tex_row_copy32( |
|
199 &land_row[final_range.clone()], |
|
200 &mut tex_row[final_range], |
|
201 &sprite_row[..land.width() - x_offset] |
|
202 ); |
|
203 } |
|
204 } |
|
205 } |
|
206 |
|
207 if let Some(border_sprite) = theme.border_texture() { |
|
208 assert!(border_sprite.height() <= 512); |
|
209 let border_width = (border_sprite.height() / 2) as u8; |
|
210 let border_sprite = border_sprite.to_tiled(); |
|
211 |
|
212 let mut offsets = vec![255u8; land.width()]; |
|
213 |
|
214 land_border_pass32( |
|
215 land.rows().rev().zip(texture.rows_mut().rev()), |
|
216 &mut offsets, |
|
217 border_width, |
|
218 |x, y| border_sprite.get_pixel( |
|
219 x % border_sprite.width(), |
|
220 border_sprite.height() - 1 - y, |
|
221 ) |
|
222 ); |
|
223 |
|
224 offsets.iter_mut().for_each(|v| *v = 255); |
|
225 |
|
226 land_border_pass32( |
|
227 land.rows().zip(texture.rows_mut()), |
|
228 &mut offsets, |
|
229 border_width, |
|
230 |x, y| border_sprite.get_pixel( |
|
231 x % border_sprite.width(), |
|
232 y, |
|
233 ) |
|
234 ); |
|
235 } |
|
236 |
|
237 texture |
|
238 } |
173 } |
239 } |
174 |
240 |
175 #[derive(Debug, Clone, Copy, PartialEq, Eq)] |
241 #[derive(Debug, Clone, Copy, PartialEq, Eq)] |
176 struct Color(u32); |
242 struct Color(u32); |
177 |
243 |
236 } |
302 } |
237 } |
303 } |
238 } |
304 } |
239 } |
305 } |
240 |
306 |
|
307 fn land_border_pass32<'a, T, F>(rows: T, offsets: &mut [u8], border_width: u8, pixel_getter: F) |
|
308 where T: Iterator<Item = (&'a [u32], &'a mut [u32])>, |
|
309 F: (Fn(usize, usize) -> u32) |
|
310 { |
|
311 for (land_row, tex_row) in rows { |
|
312 for (x, ((land_v, tex_v), offset_v)) in land_row.iter() |
|
313 .zip(tex_row.iter_mut()) |
|
314 .zip(offsets.iter_mut()) |
|
315 .enumerate() |
|
316 { |
|
317 *offset_v = if *land_v == 0 { |
|
318 if *offset_v < border_width { |
|
319 *tex_v = blend( |
|
320 pixel_getter(x, *offset_v as usize), |
|
321 *tex_v, |
|
322 ) |
|
323 } |
|
324 offset_v.saturating_add(1) |
|
325 } else { |
|
326 0 |
|
327 } |
|
328 } |
|
329 } |
|
330 } |
|
331 |
241 fn tex_row_copy(land_row: &[u8], tex_row: &mut [u32], sprite_row: &[u32]) { |
332 fn tex_row_copy(land_row: &[u8], tex_row: &mut [u32], sprite_row: &[u32]) { |
|
333 for ((land_v, tex_v), sprite_v) in |
|
334 land_row.iter().zip(tex_row.iter_mut()).zip(sprite_row) |
|
335 { |
|
336 *tex_v = if *land_v == 0 { |
|
337 *sprite_v |
|
338 } else { |
|
339 0 |
|
340 } |
|
341 } |
|
342 } |
|
343 |
|
344 fn tex_row_copy32(land_row: &[u32], tex_row: &mut [u32], sprite_row: &[u32]) { |
242 for ((land_v, tex_v), sprite_v) in |
345 for ((land_v, tex_v), sprite_v) in |
243 land_row.iter().zip(tex_row.iter_mut()).zip(sprite_row) |
346 land_row.iter().zip(tex_row.iter_mut()).zip(sprite_row) |
244 { |
347 { |
245 *tex_v = if *land_v == 0 { |
348 *tex_v = if *land_v == 0 { |
246 *sprite_v |
349 *sprite_v |