add type safe power of two sizes
authoralfadur
Thu, 27 Jan 2022 03:51:13 +0300
changeset 15828 44b49f255e31
parent 15827 64b0a5cead86
child 15829 d5e6c8c92d87
add type safe power of two sizes
rust/hwphysics/src/collision.rs
rust/hwphysics/src/grid.rs
rust/hwphysics/src/lib.rs
rust/hwphysics/src/physics.rs
rust/integral-geometry/src/lib.rs
rust/land2d/src/lib.rs
rust/land_dump/src/main.rs
rust/landgen/src/lib.rs
rust/landgen/src/outline.rs
rust/landgen/src/template_based.rs
rust/lib-hedgewars-engine/src/render/atlas.rs
rust/lib-hedgewars-engine/src/time.rs
rust/lib-hedgewars-engine/src/world.rs
rust/mapgen/src/lib.rs
--- a/rust/hwphysics/src/collision.rs	Tue Jan 25 23:46:11 2022 +0300
+++ b/rust/hwphysics/src/collision.rs	Thu Jan 27 03:51:13 2022 +0300
@@ -3,7 +3,7 @@
 use crate::{common::GearId, data::GearDataManager, grid::Grid};
 
 use fpnum::*;
-use integral_geometry::{Point, Size};
+use integral_geometry::{Point, PotSize};
 use land2d::Land2D;
 
 pub fn fppoint_round(point: &FPPoint) -> Point {
@@ -105,7 +105,7 @@
         data.register::<ContactData>();
     }
 
-    pub fn new(size: Size) -> Self {
+    pub fn new(size: PotSize) -> Self {
         Self {
             grid: Grid::new(size),
             enabled_collisions: EnabledCollisionsCollection::new(),
--- a/rust/hwphysics/src/grid.rs	Tue Jan 25 23:46:11 2022 +0300
+++ b/rust/hwphysics/src/grid.rs	Thu Jan 27 03:51:13 2022 +0300
@@ -4,7 +4,7 @@
 };
 
 use fpnum::FPPoint;
-use integral_geometry::{GridIndex, Point, Size};
+use integral_geometry::{GridIndex, Point, PotSize};
 
 struct GridBin {
     refs: Vec<GearId>,
@@ -39,35 +39,41 @@
 
 pub struct Grid {
     bins: Vec<GridBin>,
-    space_size: Size,
-    bins_count: Size,
+    space_size: PotSize,
+    bins_count: PotSize,
     index: GridIndex,
 }
 
 impl Grid {
-    pub fn new(size: Size) -> Self {
-        assert!(size.is_power_of_two());
-        let bins_count = Size::new(size.width / GRID_BIN_SIZE, size.height / GRID_BIN_SIZE);
+    pub fn new(size: PotSize) -> Self {
+        let bins_count =
+            PotSize::new(size.width() / GRID_BIN_SIZE, size.height() / GRID_BIN_SIZE).unwrap();
 
         Self {
             bins: (0..bins_count.area()).map(|_| GridBin::new()).collect(),
             space_size: size,
             bins_count,
-            index: Size::square(GRID_BIN_SIZE).to_grid_index(),
+            index: PotSize::square(GRID_BIN_SIZE).unwrap().to_grid_index(),
         }
     }
 
+    fn linear_bin_index(&self, index: Point) -> usize {
+        self.bins_count
+            .linear_index(index.x as usize, index.y as usize)
+    }
+
     fn bin_index(&self, position: &FPPoint) -> Point {
         self.index.map(fppoint_round(position))
     }
 
     fn get_bin(&mut self, index: Point) -> &mut GridBin {
-        &mut self.bins[index.y as usize * self.bins_count.width + index.x as usize]
+        let index = self.linear_bin_index(index);
+        &mut self.bins[index]
     }
 
     fn try_get_bin(&mut self, index: Point) -> Option<&mut GridBin> {
-        self.bins
-            .get_mut(index.y as usize * self.bins_count.width + index.x as usize)
+        let index = self.linear_bin_index(index);
+        self.bins.get_mut(index)
     }
 
     fn lookup_bin(&mut self, position: &FPPoint) -> &mut GridBin {
@@ -94,14 +100,11 @@
         } else {
             self.remove_all(gear_id);
         }
-
     }
 
     pub fn check_collisions(&self, collisions: &mut DetectedCollisions) {
         for bin in &self.bins {
-            for (index, bounds) in bin.entries.iter().enumerate() {
-
-            }
+            for (index, bounds) in bin.entries.iter().enumerate() {}
         }
     }
 }
--- a/rust/hwphysics/src/lib.rs	Tue Jan 25 23:46:11 2022 +0300
+++ b/rust/hwphysics/src/lib.rs	Thu Jan 27 03:51:13 2022 +0300
@@ -4,7 +4,7 @@
 mod grid;
 pub mod physics;
 
-use integral_geometry::Size;
+use integral_geometry::PotSize;
 use land2d::Land2D;
 
 use crate::{
@@ -22,7 +22,7 @@
 }
 
 impl World {
-    pub fn new(world_size: Size) -> Self {
+    pub fn new(world_size: PotSize) -> Self {
         let mut data = GearDataManager::new();
         PhysicsProcessor::register_components(&mut data);
         CollisionProcessor::register_components(&mut data);
@@ -72,12 +72,12 @@
         World,
     };
     use fpnum::{fp, FPNum, FPPoint};
-    use integral_geometry::Size;
+    use integral_geometry::PotSize;
     use land2d::Land2D;
 
     #[test]
     fn data_flow() {
-        let world_size = Size::new(2048, 2048);
+        let world_size = PotSize::new(2048, 2048).unwrap;
 
         let mut world = World::new(world_size);
         let gear_id = world.new_gear().unwrap();
--- a/rust/hwphysics/src/physics.rs	Tue Jan 25 23:46:11 2022 +0300
+++ b/rust/hwphysics/src/physics.rs	Thu Jan 27 03:51:13 2022 +0300
@@ -67,11 +67,7 @@
         }
     }
 
-    pub fn process(
-        &mut self,
-        data: &mut GearDataManager,
-        time_step: Millis,
-    ) -> &PositionUpdates {
+    pub fn process(&mut self, data: &mut GearDataManager, time_step: Millis) -> &PositionUpdates {
         if time_step == Millis::new(1) {
             self.process_impl::<true>(data, time_step)
         } else {
--- a/rust/integral-geometry/src/lib.rs	Tue Jan 25 23:46:11 2022 +0300
+++ b/rust/integral-geometry/src/lib.rs	Thu Jan 27 03:51:13 2022 +0300
@@ -141,11 +141,16 @@
     }
 
     #[inline]
-    pub fn next_power_of_two(&self) -> Self {
-        Self {
-            width: self.width.next_power_of_two(),
-            height: self.height.next_power_of_two(),
-        }
+    pub const fn as_power_of_two(&self) -> Option<PotSize> {
+        PotSize::new(self.width, self.height)
+    }
+
+    #[inline]
+    pub const fn next_power_of_two(&self) -> PotSize {
+        PotSize::new_impl(
+            self.width.next_power_of_two(),
+            self.height.next_power_of_two(),
+        )
     }
 
     #[inline]
@@ -154,19 +159,10 @@
     }
 
     #[inline]
-    pub fn to_mask(&self) -> SizeMask {
-        SizeMask::new(*self)
-    }
-
-    #[inline]
     pub fn to_square(&self) -> Self {
         Self::square(max(self.width, self.height))
     }
 
-    pub fn to_grid_index(&self) -> GridIndex {
-        GridIndex::new(*self)
-    }
-
     #[inline]
     pub const fn contains(&self, other: Self) -> bool {
         self.width >= other.width && self.height >= other.height
@@ -174,11 +170,96 @@
 
     #[inline]
     pub fn join(&self, other: Self) -> Self {
+        Self::new(max(self.width, other.width), max(self.height, other.height))
+    }
+}
+
+#[derive(PartialEq, Eq, Clone, Copy, Debug)]
+pub struct PotSize {
+    size: Size,
+}
+
+impl PotSize {
+    #[inline]
+    const fn new_impl(width: usize, height: usize) -> Self {
+        debug_assert!(width.is_power_of_two() && height.is_power_of_two());
         Self {
-            width: max(self.width, other.width),
-            height: max(self.height, other.height)
+            size: Size::new(width, height),
+        }
+    }
+
+    #[inline]
+    pub const fn new(width: usize, height: usize) -> Option<Self> {
+        if width.is_power_of_two() && height.is_power_of_two() {
+            Some(Self::new_impl(width, height))
+        } else {
+            None
+        }
+    }
+
+    pub const fn size(&self) -> Size {
+        self.size
+    }
+
+    pub const fn width(&self) -> usize {
+        self.size.width
+    }
+
+    pub const fn height(&self) -> usize {
+        self.size.height
+    }
+
+    #[inline]
+    pub const fn square(size: usize) -> Option<Self> {
+        if size.is_power_of_two() {
+            Some(Self::new_impl(size, size))
+        } else {
+            None
         }
     }
+
+    #[inline]
+    pub const fn area(&self) -> usize {
+        self.size.area()
+    }
+
+    #[inline]
+    pub const fn linear_index(&self, x: usize, y: usize) -> usize {
+        self.size.linear_index(x, y)
+    }
+
+    #[inline]
+    pub const fn transpose(&self) -> Self {
+        Self::new_impl(self.height(), self.width())
+    }
+
+    #[inline]
+    pub fn to_square(&self) -> Self {
+        let size = max(self.width(), self.height());
+        Self::new_impl(size, size)
+    }
+
+    #[inline]
+    pub const fn to_mask(&self) -> SizeMask {
+        SizeMask::new(*self)
+    }
+
+    pub const fn to_grid_index(&self) -> GridIndex {
+        GridIndex::new(*self)
+    }
+
+    #[inline]
+    pub const fn contains(&self, other: Self) -> bool {
+        self.size.contains(other.size)
+    }
+
+    #[inline]
+    pub fn join(&self, other: Self) -> Self {
+        Self::new_impl(
+            max(self.width(), other.width()),
+            max(self.height(), other.height()),
+        )
+    }
 }
 
 #[derive(PartialEq, Eq, Clone, Copy, Debug)]
@@ -188,13 +269,10 @@
 
 impl SizeMask {
     #[inline]
-    pub fn new(size: Size) -> Self {
-        debug_assert!(size.is_power_of_two());
-        let size = Size {
-            width: !(size.width - 1),
-            height: !(size.height - 1),
-        };
-        Self { size }
+    pub const fn new(size: PotSize) -> Self {
+        Self {
+            size: Size::new(!(size.width() - 1), !(size.height() - 1)),
+        }
     }
 
     #[inline]
@@ -211,6 +289,11 @@
     pub fn contains(&self, point: Point) -> bool {
         self.contains_x(point.x as usize) && self.contains_y(point.y as usize)
     }
+
+    #[inline]
+    pub const fn to_size(&self) -> PotSize {
+        PotSize::new_impl(!self.size.width + 1, !self.size.height + 1)
+    }
 }
 
 pub struct GridIndex {
@@ -218,11 +301,10 @@
 }
 
 impl GridIndex {
-    pub fn new(size: Size) -> Self {
-        debug_assert!(size.is_power_of_two());
+    pub const fn new(size: PotSize) -> Self {
         let shift = Point::new(
-            size.width.trailing_zeros() as i32,
-            size.height.trailing_zeros() as i32,
+            size.width().trailing_zeros() as i32,
+            size.height().trailing_zeros() as i32,
         );
         Self { shift }
     }
@@ -324,7 +406,7 @@
     };
 
     #[inline]
-    pub fn new(top_left: Point, bottom_right: Point) -> Self {
+    pub const fn new(top_left: Point, bottom_right: Point) -> Self {
         debug_assert!(top_left.x <= bottom_right.x + 1);
         debug_assert!(top_left.y <= bottom_right.y + 1);
         Self {
@@ -333,7 +415,7 @@
         }
     }
 
-    pub fn from_box(left: i32, right: i32, top: i32, bottom: i32) -> Self {
+    pub const fn from_box(left: i32, right: i32, top: i32, bottom: i32) -> Self {
         Self::new(Point::new(left, top), Point::new(right, bottom))
     }
 
@@ -450,7 +532,7 @@
     }
 
     #[inline]
-    pub fn split_at(&self, point: Point) -> [Rect; 4] {
+    pub const fn split_at(&self, point: Point) -> [Rect; 4] {
         debug_assert!(self.contains_inside(point));
         [
             Self::from_box(self.left(), point.x, self.top(), point.y),
@@ -461,7 +543,7 @@
     }
 
     #[inline]
-    pub fn with_margins(&self, left: i32, right: i32, top: i32, bottom: i32) -> Self {
+    pub const fn with_margins(&self, left: i32, right: i32, top: i32, bottom: i32) -> Self {
         Self::from_box(
             self.left() - left,
             self.right() + right,
--- a/rust/land2d/src/lib.rs	Tue Jan 25 23:46:11 2022 +0300
+++ b/rust/land2d/src/lib.rs	Thu Jan 27 03:51:13 2022 +0300
@@ -1,9 +1,6 @@
-use std::{
-    cmp,
-    ops::Index
-};
+use std::{cmp, ops::Index};
 
-use integral_geometry::{ArcPoints, EquidistantPoints, Line, Point, Rect, Size, SizeMask};
+use integral_geometry::{ArcPoints, EquidistantPoints, Line, Point, PotSize, Rect, Size, SizeMask};
 
 pub struct Land2D<T> {
     pixels: vec2d::Vec2D<T>,
@@ -15,13 +12,13 @@
     pub fn new(play_size: Size, fill_value: T) -> Self {
         let real_size = play_size.next_power_of_two();
         let top_left = Point::new(
-            ((real_size.width - play_size.width) / 2) as i32,
-            (real_size.height - play_size.height) as i32,
+            ((real_size.width() - play_size.width) / 2) as i32,
+            (real_size.height() - play_size.height) as i32,
         );
         let play_box = Rect::from_size(top_left, play_size);
         Self {
             play_box,
-            pixels: vec2d::Vec2D::new(real_size, fill_value),
+            pixels: vec2d::Vec2D::new(real_size.size(), fill_value),
             mask: real_size.to_mask(),
         }
     }
@@ -31,9 +28,7 @@
     }
 
     pub fn raw_pixel_bytes(&self) -> &[u8] {
-        unsafe {
-            self.pixels.as_bytes()
-        }
+        unsafe { self.pixels.as_bytes() }
     }
 
     #[inline]
@@ -47,8 +42,8 @@
     }
 
     #[inline]
-    pub fn size(&self) -> Size {
-        self.pixels.size()
+    pub fn size(&self) -> PotSize {
+        self.mask.to_size()
     }
 
     #[inline]
@@ -117,7 +112,8 @@
                 *v = value;
                 1
             })
-        }).count()
+        })
+        .count()
     }
 
     pub fn draw_line(&mut self, line: Line, value: T) -> usize {
@@ -149,31 +145,34 @@
         let start_x_l = (start_point.x - 1) as usize;
         let start_x_r = start_point.x as usize;
         for dir in [-1, 1].iter().cloned() {
-            push(mask, &mut stack, start_x_l, start_x_r, start_point.y as usize, dir);
+            push(
+                mask,
+                &mut stack,
+                start_x_l,
+                start_x_r,
+                start_point.y as usize,
+                dir,
+            );
         }
 
         while let Some((mut xl, mut xr, y, dir)) = stack.pop() {
             let row = &mut self.pixels[y][..];
-            while xl > 0 && row[xl] != border_value && row[xl] != fill_value
-            {
+            while xl > 0 && row[xl] != border_value && row[xl] != fill_value {
                 xl -= 1;
             }
 
-            while xr < width - 1 && row[xr] != border_value && row[xr] != fill_value
-            {
+            while xr < width - 1 && row[xr] != border_value && row[xr] != fill_value {
                 xr += 1;
             }
 
             while xl < xr {
-                while xl <= xr && (row[xl] == border_value || row[xl] == fill_value)
-                {
+                while xl <= xr && (row[xl] == border_value || row[xl] == fill_value) {
                     xl += 1;
                 }
 
                 let x = xl;
 
-                while xl <= xr && row[xl] != border_value && row[xl] != fill_value
-                {
+                while xl <= xr && row[xl] != border_value && row[xl] != fill_value {
                     row[xl] = fill_value;
                     xl += 1;
                 }
@@ -257,7 +256,8 @@
                     .iter()
                     .map(|m| self.fill_row(center, vector.transform(m), value))
                     .sum::<usize>()
-            }).sum()
+            })
+            .sum()
     }
 
     pub fn draw_thick_line(&mut self, line: Line, radius: i32, value: T) -> usize {
--- a/rust/land_dump/src/main.rs	Tue Jan 25 23:46:11 2022 +0300
+++ b/rust/land_dump/src/main.rs	Thu Jan 27 03:51:13 2022 +0300
@@ -2,23 +2,21 @@
 use std::{
     fs::File,
     io::{BufWriter, Read},
-    path::{Path, PathBuf}
+    path::{Path, PathBuf},
 };
 use structopt::StructOpt;
 
 use integral_geometry::{Point, Rect, Size};
+use land2d::Land2D;
 use landgen::{
-    outline_template::OutlineTemplate,
-    template_based::TemplatedLandGenerator,
-    LandGenerationParameters,
-    LandGenerator
-};
-use mapgen::{
-    MapGenerator,
-    theme::{Theme, slice_u32_to_u8}
+    outline_template::OutlineTemplate, template_based::TemplatedLandGenerator,
+    LandGenerationParameters, LandGenerator,
 };
 use lfprng::LaggedFibonacciPRNG;
-use land2d::Land2D;
+use mapgen::{
+    theme::{slice_u32_to_u8, Theme},
+    MapGenerator,
+};
 
 #[derive(StructOpt, Debug)]
 #[structopt(name = "basic")]
@@ -36,7 +34,7 @@
     #[structopt(short = "t", long = "template-type")]
     template_type: Option<String>,
     #[structopt(short = "z", long = "theme-dir")]
-    theme_dir: Option<String>
+    theme_dir: Option<String>,
 }
 
 fn template() -> OutlineTemplate {
@@ -60,7 +58,8 @@
     skip_bezier: bool,
     file_name: &Path,
 ) -> std::io::Result<Land2D<u8>> {
-    let params = LandGenerationParameters::new(0 as u8, 255, distance_divisor, skip_distort, skip_bezier);
+    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);
     let land = landgen.generate_land(&params, &mut prng);
@@ -87,40 +86,39 @@
     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);
+    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();
+    writer
+        .write_image_data(slice_u32_to_u8(texture.as_slice()))
+        .unwrap();
 }
 
 fn main() {
     let opt = Opt::from_args();
     println!("{:?}", opt);
 
-    let template =
-        if let Some(path) = opt.templates_file {
-            let mut result = String::new();
-            File::open(path)
-                .expect("Unable to read templates file")
-                .read_to_string(&mut result);
+    let template = if let Some(path) = opt.templates_file {
+        let mut result = String::new();
+        File::open(path)
+            .expect("Unable to read templates file")
+            .read_to_string(&mut result);
 
-            let mut generator = MapGenerator::new();
+        let mut generator = MapGenerator::new();
 
-            let source =  &result[..];
+        let source = &result[..];
 
-            generator.import_yaml_templates(source);
+        generator.import_yaml_templates(source);
 
-            let template_type = &opt.template_type
-                .expect("No template type specified");
-            generator.get_template(template_type)
-                .expect(&format!("Template type {} not found", template_type))
-                .clone()
-        } else {
-            template()
-        };
+        let template_type = &opt.template_type.expect("No template type specified");
+        generator
+            .get_template(template_type)
+            .expect(&format!("Template type {} not found", template_type))
+            .clone()
+    } else {
+        template()
+    };
 
     if opt.dump_before_distort {
         dump(
@@ -155,10 +153,6 @@
     .unwrap();
 
     if let Some(dir) = opt.theme_dir {
-        texturize(
-            &Path::new(&dir),
-            &land,
-            &Path::new("out.texture.png")
-        );
+        texturize(&Path::new(&dir), &land, &Path::new("out.texture.png"));
     }
 }
--- a/rust/landgen/src/lib.rs	Tue Jan 25 23:46:11 2022 +0300
+++ b/rust/landgen/src/lib.rs	Thu Jan 27 03:51:13 2022 +0300
@@ -11,7 +11,13 @@
 }
 
 impl<T: Copy + PartialEq> LandGenerationParameters<T> {
-    pub fn new(zero: T, basic: T, distance_divisor: u32, skip_distort: bool, skip_bezier: bool) -> Self {
+    pub fn new(
+        zero: T,
+        basic: T,
+        distance_divisor: u32,
+        skip_distort: bool,
+        skip_bezier: bool,
+    ) -> Self {
         Self {
             zero,
             basic,
--- a/rust/landgen/src/outline.rs	Tue Jan 25 23:46:11 2022 +0300
+++ b/rust/landgen/src/outline.rs	Thu Jan 27 03:51:13 2022 +0300
@@ -1,7 +1,7 @@
 use itertools::Itertools;
 use std::cmp::min;
 
-use integral_geometry::{Line, Ray, Point, Polygon, Rect, Size};
+use integral_geometry::{Line, Point, Polygon, Ray, Rect, Size};
 use land2d::Land2D;
 
 use crate::outline_template::OutlineTemplate;
@@ -76,16 +76,14 @@
         fn solve_intersection(
             intersections_box: &Rect,
             ray: &Ray,
-            edge: &Line
-        ) -> Option<(i32, u32)>
-        {
+            edge: &Line,
+        ) -> Option<(i32, u32)> {
             let edge_dir = edge.scaled_direction();
             let aqpb = ray.direction.cross(edge_dir) as i64;
 
             if aqpb != 0 {
-                let mut iy =
-                    ((((edge.start.x - ray.start.x) as i64 * ray.direction.y as i64
-                        + ray.start.y as i64 * ray.direction.x as i64)
+                let mut iy = ((((edge.start.x - ray.start.x) as i64 * ray.direction.y as i64
+                    + ray.start.y as i64 * ray.direction.x as i64)
                     * edge_dir.y as i64
                     - edge.start.y as i64 * edge_dir.x as i64 * ray.direction.y as i64)
                     / aqpb) as i32;
@@ -147,7 +145,7 @@
             // same for the right border
             let right_intersection = Point::new(
                 map_box.right(),
-                mid_point.y + normal.tangent_mul(map_box.right() - mid_point.x)  ,
+                mid_point.y + normal.tangent_mul(map_box.right() - mid_point.x),
             );
             dist_right = (mid_point - right_intersection).integral_norm();
 
@@ -203,7 +201,9 @@
                 if intersects(&pi.ray_with_dir(normal), &segment) {
                     // ray from segment.start
                     if let Some((t, d)) = solve_intersection(
-                        &self.intersections_box, &normal_ray, &segment.start.line_to(pi),
+                        &self.intersections_box,
+                        &normal_ray,
+                        &segment.start.line_to(pi),
                     ) {
                         if t > 0 {
                             dist_right = min(dist_right, d);
@@ -214,7 +214,9 @@
 
                     // ray from segment.end
                     if let Some((t, d)) = solve_intersection(
-                        &self.intersections_box, &normal_ray, &segment.end.line_to(pi)
+                        &self.intersections_box,
+                        &normal_ray,
+                        &segment.end.line_to(pi),
                     ) {
                         if t > 0 {
                             dist_right = min(dist_right, d);
--- a/rust/landgen/src/template_based.rs	Tue Jan 25 23:46:11 2022 +0300
+++ b/rust/landgen/src/template_based.rs	Thu Jan 27 03:51:13 2022 +0300
@@ -1,11 +1,9 @@
+use crate::{
+    outline::OutlinePoints, outline_template::OutlineTemplate, LandGenerationParameters,
+    LandGenerator,
+};
 use integral_geometry::{Point, Size};
 use land2d::Land2D;
-use crate::{
-    LandGenerationParameters,
-    LandGenerator,
-    outline::OutlinePoints,
-    outline_template::OutlineTemplate
-};
 
 pub struct TemplatedLandGenerator {
     outline_template: OutlineTemplate,
@@ -28,7 +26,7 @@
         let mut points = OutlinePoints::from_outline_template(
             &self.outline_template,
             land.play_box(),
-            land.size(),
+            land.size().size(),
             random_numbers,
         );
 
--- a/rust/lib-hedgewars-engine/src/render/atlas.rs	Tue Jan 25 23:46:11 2022 +0300
+++ b/rust/lib-hedgewars-engine/src/render/atlas.rs	Thu Jan 27 03:51:13 2022 +0300
@@ -14,8 +14,8 @@
 impl Fit {
     fn new() -> Self {
         Self {
-            short_side: u32::max_value(),
-            long_side: u32::max_value(),
+            short_side: u32::MAX,
+            long_side: u32::MAX,
         }
     }
 
--- a/rust/lib-hedgewars-engine/src/time.rs	Tue Jan 25 23:46:11 2022 +0300
+++ b/rust/lib-hedgewars-engine/src/time.rs	Thu Jan 27 03:51:13 2022 +0300
@@ -1,8 +1,8 @@
+use hwphysics::common::{GearId, Millis};
 use std::{
     cmp::{Eq, Ord, Ordering, PartialEq, PartialOrd},
     collections::BinaryHeap,
 };
-use hwphysics::common::{GearId, Millis};
 
 pub type EventId = u16;
 
--- a/rust/lib-hedgewars-engine/src/world.rs	Tue Jan 25 23:46:11 2022 +0300
+++ b/rust/lib-hedgewars-engine/src/world.rs	Thu Jan 27 03:51:13 2022 +0300
@@ -100,7 +100,7 @@
         // based on old engine min_distance... dunno if this is the correct place tho
         let distance_divisor = (self.feature_size as u32).pow(2) / 8 + 10;
 
-        let params = LandGenerationParameters::new(0u8, u8::max_value(), distance_divisor, false, false);
+        let params = LandGenerationParameters::new(0u8, u8::MAX, distance_divisor, false, false);
         let landgen = TemplatedLandGenerator::new(template());
         self.preview = Some(landgen.generate_land(&params, &mut self.random_numbers_gen));
     }
@@ -110,12 +110,12 @@
     }
 
     pub fn init(&mut self, template: OutlineTemplate) {
-        let physics = hwp::World::new(template.size);
-
-        let params = LandGenerationParameters::new(0u32, u32::max_value(), 5, false, false);
+        let params = LandGenerationParameters::new(0u32, u32::MAX, 5, false, false);
         let landgen = TemplatedLandGenerator::new(template);
         let land = landgen.generate_land(&params, &mut self.random_numbers_gen);
 
+        let physics = hwp::World::new(land.size());
+
         self.game_state = Some(GameState::new(land, physics));
     }
 
--- a/rust/mapgen/src/lib.rs	Tue Jan 25 23:46:11 2022 +0300
+++ b/rust/mapgen/src/lib.rs	Thu Jan 27 03:51:13 2022 +0300
@@ -121,7 +121,7 @@
     where
         LandT: Copy + Default + PartialEq,
     {
-        let mut texture = Vec2D::new(land.size(), 0);
+        let mut texture = Vec2D::new(land.size().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()