--- a/rust/land2d/src/lib.rs Wed Nov 07 19:43:17 2018 +0100
+++ b/rust/land2d/src/lib.rs Wed Nov 07 22:01:47 2018 +0300
@@ -30,7 +30,7 @@
}
pub fn raw_pixels(&self) -> &[T] {
- &self.pixels.raw_data()
+ &self.pixels.as_slice()
}
#[inline]
--- a/rust/mapgen/Cargo.toml Wed Nov 07 19:43:17 2018 +0100
+++ b/rust/mapgen/Cargo.toml Wed Nov 07 22:01:47 2018 +0300
@@ -5,6 +5,7 @@
edition = "2018"
[dependencies]
+vec2d = { path = "../vec2d" }
land2d = { path = "../land2d" }
landgen = { path = "../landgen" }
lfprng = { path = "../lfprng" }
--- a/rust/mapgen/src/lib.rs Wed Nov 07 19:43:17 2018 +0100
+++ b/rust/mapgen/src/lib.rs Wed Nov 07 22:01:47 2018 +0300
@@ -5,7 +5,6 @@
borrow::Borrow,
mem::replace
};
-use serde::{Deserialize};
use serde_derive::{Deserialize};
use serde_yaml;
use integral_geometry::{Point, Size, Rect};
@@ -14,6 +13,7 @@
};
use rand::{thread_rng, Rng};
use land2d::Land2D;
+use vec2d::Vec2D;
use self::theme::Theme;
#[derive(Deserialize)]
@@ -106,11 +106,52 @@
self.templates.get(template_type).and_then(|t| thread_rng().choose(t))
}
- pub fn make_texture(&self, land: &Land2D<u32>, theme: &Theme) {
+ pub fn make_texture(&self, land: &Land2D<u32>, theme: &Theme) -> Vec2D<u32> {
+ let mut texture = Vec2D::new(land.size(), 0);
+ if let Some(land_sprite) = theme.land_texture() {
+ for (row_index, (land_row, tex_row)) in land.rows()
+ .zip(texture.rows_mut())
+ .enumerate()
+ {
+ let sprite_row = land_sprite.get_row(row_index % land_sprite.height());
+ let mut x_offset = 0;
+ while sprite_row.len() < land.width() - x_offset {
+ let copy_range = x_offset..x_offset + sprite_row.len();
+ tex_row_copy(
+ &land_row[copy_range.clone()],
+ &mut tex_row[copy_range],
+ sprite_row
+ );
+
+ x_offset += land_sprite.width()
+ }
+ if x_offset < land.width() {
+ let final_range = x_offset..land.width() - 1;
+ tex_row_copy(
+ &land_row[final_range.clone()],
+ &mut tex_row[final_range],
+ &sprite_row[..land.width() - x_offset]
+ );
+ }
+ }
+ }
+ texture
}
}
+fn tex_row_copy(land_row: &[u32], tex_row: &mut [u32], sprite_row: &[u32]) {
+ for ((land_v, tex_v), sprite_v) in
+ land_row.iter().zip(tex_row.iter_mut()).zip(sprite_row)
+ {
+ *tex_v = if *land_v == 0 {
+ *sprite_v
+ } else {
+ 0
+ }
+ }
+}
+
#[cfg(test)]
mod tests {
use crate::{
--- a/rust/mapgen/src/theme.rs Wed Nov 07 19:43:17 2018 +0100
+++ b/rust/mapgen/src/theme.rs Wed Nov 07 22:01:47 2018 +0300
@@ -6,25 +6,55 @@
path::Path
};
use png::{
- BitDepth,
ColorType,
Decoder,
DecodingError
};
-use integral_geometry::{
- Rect, Size
-};
+use integral_geometry::Size;
+use vec2d::Vec2D;
pub struct ThemeSprite {
- bounds: Size,
- pixels: Vec<u32>
+ pixels: Vec2D<u32>
+}
+
+impl ThemeSprite {
+ #[inline]
+ pub fn width(&self) -> usize {
+ self.pixels.size().width
+ }
+
+ #[inline]
+ pub fn height(&self) -> usize {
+ self.pixels.size().height
+ }
+
+ #[inline]
+ pub fn bounds(&self) -> Size {
+ self.pixels.size()
+ }
+
+ #[inline]
+ pub fn rows(&self) -> impl Iterator<Item = &[u32]> {
+ self.pixels.rows()
+ }
+
+ #[inline]
+ pub fn get_row(&self, index: usize) -> &[u32] {
+ &self.pixels[index]
+ }
}
pub struct Theme {
land_texture: Option<ThemeSprite>
}
+impl Theme {
+ pub fn land_texture(&self) -> Option<&ThemeSprite> {
+ self.land_texture.as_ref()
+ }
+}
+
pub enum ThemeLoadError {
File(io::Error),
Decoding(DecodingError),
@@ -66,18 +96,17 @@
}
let size = Size::new(info.width as usize, info.height as usize);
- let mut buffer: Vec<u32> = Vec::with_capacity(size.area());
- let mut slice_u32 = buffer.as_mut_slice();
- let mut slice_u8 = unsafe {
+ let mut buffer: Vec2D<u32> = Vec2D::new(size, 0);
+ let slice_u32 = buffer.as_mut_slice();
+ let slice_u8 = unsafe {
from_raw_parts_mut::<u8>(
slice_u32.as_mut_ptr() as *mut u8,
slice_u32.len() / 4
)
};
- reader.next_frame(slice_u8);
+ reader.next_frame(slice_u8)?;
let land_tex = ThemeSprite {
- bounds: size,
pixels: buffer
};
theme.land_texture = Some(land_tex)
--- a/rust/vec2d/src/lib.rs Wed Nov 07 19:43:17 2018 +0100
+++ b/rust/vec2d/src/lib.rs Wed Nov 07 22:01:47 2018 +0300
@@ -55,8 +55,14 @@
Self { size, data: vec![value; size.area()] }
}
- pub fn raw_data(&self) -> &[T] {
- &self.data
+ #[inline]
+ pub fn as_slice(&self) -> &[T] {
+ self.data.as_slice()
+ }
+
+ #[inline]
+ pub fn as_mut_slice(&mut self) -> &mut [T] {
+ self.data.as_mut_slice()
}
#[inline]
@@ -83,6 +89,24 @@
pub fn rows(&self) -> impl Iterator<Item = &[T]> {
self.data.chunks(self.width())
}
+
+ #[inline]
+ pub fn rows_mut(&mut self) -> impl Iterator<Item = &mut [T]> {
+ let width = self.width();
+ self.data.chunks_mut(width)
+ }
+}
+
+impl<T: Copy> AsRef<[T]> for Vec2D<T> {
+ fn as_ref(&self) -> &[T] {
+ self.as_slice()
+ }
+}
+
+impl<T: Copy> AsMut<[T]> for Vec2D<T> {
+ fn as_mut(&mut self) -> &mut [T] {
+ self.as_mut_slice()
+ }
}
#[cfg(test)]