fix texturing and add a theme loading option to land_dump
authoralfadur
Wed, 07 Nov 2018 22:58:54 +0300
changeset 14169 1749961647b9
parent 14168 e337e9920440
child 14170 8d9e3af8abce
fix texturing and add a theme loading option to land_dump
rust/land_dump/src/main.rs
rust/mapgen/src/lib.rs
rust/mapgen/src/theme.rs
--- a/rust/land_dump/src/main.rs	Wed Nov 07 14:56:34 2018 -0500
+++ b/rust/land_dump/src/main.rs	Wed Nov 07 22:58:54 2018 +0300
@@ -13,8 +13,12 @@
     LandGenerationParameters,
     LandGenerator
 };
-use mapgen::MapGenerator;
+use mapgen::{
+    MapGenerator,
+    theme::{Theme, slice_u32_to_u8}
+};
 use lfprng::LaggedFibonacciPRNG;
+use land2d::Land2D;
 
 #[derive(StructOpt, Debug)]
 #[structopt(name = "basic")]
@@ -30,7 +34,9 @@
     #[structopt(short = "i", long = "templates-file")]
     templates_file: Option<String>,
     #[structopt(short = "t", long = "template-type")]
-    template_type: Option<String>
+    template_type: Option<String>,
+    #[structopt(short = "z", long = "theme-dir")]
+    theme_dir: Option<String>
 }
 
 fn template() -> OutlineTemplate {
@@ -53,7 +59,7 @@
     skip_distort: bool,
     skip_bezier: bool,
     file_name: &Path,
-) -> std::io::Result<()> {
+) -> std::io::Result<Land2D<u8>> {
     let params = LandGenerationParameters::new(0 as u8, 255, distance_divisor, skip_distort, skip_bezier);
     let landgen = TemplatedLandGenerator::new(template.clone());
     let mut prng = LaggedFibonacciPRNG::new(seed);
@@ -70,7 +76,24 @@
 
     writer.write_image_data(land.raw_pixels()).unwrap();
 
-    Ok(())
+    Ok(land)
+}
+
+fn texturize(theme_dir: &Path, land: &Land2D<u8>, output_filename: &Path) {
+    let theme = Theme::load(theme_dir).unwrap();
+    let texture = MapGenerator::new().make_texture(land, &theme);
+
+    let file = File::create(output_filename).unwrap();
+    let ref mut w = BufWriter::new(file);
+
+    let mut encoder = png::Encoder::new(w, land.width() as u32, land.height() as u32); // Width is 2 pixels and height is 1.
+    encoder
+        .set(png::ColorType::RGBA)
+        .set(png::BitDepth::Eight);
+
+    let mut writer = encoder.write_header().unwrap();
+
+    writer.write_image_data(slice_u32_to_u8(texture.as_slice())).unwrap();
 }
 
 fn main() {
@@ -121,7 +144,7 @@
         )
         .unwrap();
     }
-    dump(
+    let land = dump(
         &template,
         opt.seed.as_str().as_bytes(),
         opt.distance_divisor,
@@ -130,4 +153,12 @@
         Path::new("out.full.png"),
     )
     .unwrap();
+
+    if let Some(dir) = opt.theme_dir {
+        texturize(
+            &Path::new(&dir),
+            &land,
+            &Path::new("out.texture.png")
+        );
+    }
 }
--- a/rust/mapgen/src/lib.rs	Wed Nov 07 14:56:34 2018 -0500
+++ b/rust/mapgen/src/lib.rs	Wed Nov 07 22:58:54 2018 +0300
@@ -106,7 +106,7 @@
         self.templates.get(template_type).and_then(|t| thread_rng().choose(t))
     }
 
-    pub fn make_texture(&self, land: &Land2D<u32>, theme: &Theme) -> Vec2D<u32> {
+    pub fn make_texture(&self, land: &Land2D<u8>, 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()
@@ -127,7 +127,7 @@
                 }
 
                 if x_offset < land.width() {
-                    let final_range = x_offset..land.width() - 1;
+                    let final_range = x_offset..land.width();
                     tex_row_copy(
                         &land_row[final_range.clone()],
                         &mut tex_row[final_range],
@@ -140,16 +140,16 @@
     }
 }
 
-fn tex_row_copy(land_row: &[u32], tex_row: &mut [u32], sprite_row: &[u32]) {
+fn tex_row_copy(land_row: &[u8], 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
-            }
+    {
+        *tex_v = if *land_v == 0 {
+            *sprite_v
+        } else {
+            0
         }
+    }
 }
 
 #[cfg(test)]
--- a/rust/mapgen/src/theme.rs	Wed Nov 07 14:56:34 2018 -0500
+++ b/rust/mapgen/src/theme.rs	Wed Nov 07 22:58:54 2018 +0300
@@ -1,5 +1,8 @@
 use std::{
-    slice::from_raw_parts_mut,
+    slice::{
+        from_raw_parts,
+        from_raw_parts_mut
+    },
     io,
     io::BufReader,
     fs::{File, read_dir},
@@ -55,6 +58,7 @@
     }
 }
 
+#[derive(Debug)]
 pub enum ThemeLoadError {
     File(io::Error),
     Decoding(DecodingError),
@@ -86,8 +90,8 @@
         for entry in read_dir(path)? {
             let file = entry?;
             if file.file_name() == "LandTex.png" {
-                let buffer = BufReader::new(File::create(file.path())?);
-                let decoder = Decoder::new(buffer);
+                let decoder = Decoder::new(
+                    BufReader::new(File::open(file.path())?));
                 let (info, mut reader) = decoder.read_info()?;
 
                 if info.color_type != ColorType::RGBA {
@@ -97,14 +101,7 @@
                 let size = Size::new(info.width as usize, info.height as usize);
 
                 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_u32_to_u8_mut(buffer.as_mut_slice()))?;
 
                 let land_tex = ThemeSprite {
                     pixels: buffer
@@ -117,4 +114,21 @@
     }
 }
 
+pub fn slice_u32_to_u8(slice_u32: &[u32]) -> &[u8] {
+    unsafe {
+        from_raw_parts::<u8>(
+            slice_u32.as_ptr() as *const u8,
+            slice_u32.len() * 4
+        )
+    }
+}
 
+pub fn slice_u32_to_u8_mut(slice_u32: &mut [u32]) -> &mut [u8] {
+    unsafe {
+        from_raw_parts_mut::<u8>(
+            slice_u32.as_mut_ptr() as *mut u8,
+            slice_u32.len() * 4
+        )
+    }
+}
+