add some texture transforms
authoralfadur
Thu, 08 Nov 2018 22:22:47 +0300
changeset 14175 76a52e8149e3
parent 14174 fac275de34e5
child 14176 5ad911992460
add some texture transforms
rust/integral-geometry/src/lib.rs
rust/mapgen/src/lib.rs
rust/mapgen/src/theme.rs
--- a/rust/integral-geometry/src/lib.rs	Thu Nov 08 11:34:01 2018 -0500
+++ b/rust/integral-geometry/src/lib.rs	Thu Nov 08 22:22:47 2018 +0300
@@ -152,6 +152,11 @@
     }
 
     #[inline]
+    pub fn transpose(&self) -> Self {
+        Self::new(self.height, self.width)
+    }
+
+    #[inline]
     pub fn to_mask(&self) -> SizeMask {
         SizeMask::new(*self)
     }
--- a/rust/mapgen/src/lib.rs	Thu Nov 08 11:34:01 2018 -0500
+++ b/rust/mapgen/src/lib.rs	Thu Nov 08 22:22:47 2018 +0300
@@ -141,6 +141,7 @@
         if let Some(border_sprite) = theme.border_texture() {
             assert!(border_sprite.height() <= 512);
             let border_width = (border_sprite.height() / 2) as u8;
+            let border_sprite = border_sprite.to_tiled();
 
             let mut offsets = vec![255u8; land.width()];
 
--- a/rust/mapgen/src/theme.rs	Thu Nov 08 11:34:01 2018 -0500
+++ b/rust/mapgen/src/theme.rs	Thu Nov 08 22:22:47 2018 +0300
@@ -23,18 +23,18 @@
 
 impl ThemeSprite {
     #[inline]
+    pub fn size(&self) -> Size {
+        self.pixels.size()
+    }
+
+    #[inline]
     pub fn width(&self) -> usize {
-        self.pixels.size().width
+        self.size().width
     }
 
     #[inline]
     pub fn height(&self) -> usize {
-        self.pixels.size().height
-    }
-
-    #[inline]
-    pub fn bounds(&self) -> Size {
-        self.pixels.size()
+        self.size().height
     }
 
     #[inline]
@@ -51,6 +51,65 @@
     pub fn get_pixel(&self, x: usize, y: usize) -> u32 {
         self.pixels[y][x]
     }
+
+    pub fn to_transposed(&self) -> ThemeSprite {
+        let size = self.size().transpose();
+        let mut pixels = Vec2D::new(size, 0u32);
+        for (y, row) in self.pixels.rows().enumerate() {
+            for (x, v) in row.iter().enumerate() {
+                pixels[x][y] = *v;
+            }
+        }
+        ThemeSprite { pixels }
+    }
+
+    pub fn to_tiled(&self) -> TiledSprite {
+        let size = self.size();
+        assert!(size.is_power_of_two());
+        let tile_width_shift = size.width.trailing_zeros() as usize + 2;
+        let mut pixels = vec![0u32; size.area()];
+
+        for (y, row) in self.pixels.rows().enumerate() {
+            for (x, v) in row.iter().enumerate() {
+                pixels[get_tiled_index(x, y, tile_width_shift)] = *v;
+            }
+        }
+
+        TiledSprite { tile_width_shift, size, pixels }
+    }
+}
+
+#[inline]
+fn get_tiled_index(x: usize, y: usize, tile_width_shift: usize) -> usize {
+    (((y >> 2) << tile_width_shift) + ((x >> 2) << 4)) + ((y & 0b11) << 2) + (x & 0b11)
+}
+
+pub struct TiledSprite {
+    tile_width_shift: usize,
+    size: Size,
+    pixels: Vec<u32>
+}
+
+impl TiledSprite {
+    #[inline]
+    pub fn size(&self) -> Size {
+        self.size
+    }
+
+    #[inline]
+    pub fn width(&self) -> usize {
+        self.size().width
+    }
+
+    #[inline]
+    pub fn height(&self) -> usize {
+        self.size().height
+    }
+
+    #[inline]
+    pub fn get_pixel(&self, x: usize, y: usize) -> u32 {
+        self.pixels[get_tiled_index(x, y, self.tile_width_shift)]
+    }
 }
 
 pub struct Theme {