# HG changeset patch # User unC0Rr # Date 1725985291 -7200 # Node ID 1860852892c031888204dfc9c27b937471e12e63 # Parent 31cc1e45027344efc77346a2a7aee194ebbbb000 Use rust implementation of maze generator in engine diff -r 31cc1e450273 -r 1860852892c0 hedgewars/uLand.pas --- a/hedgewars/uLand.pas Tue Sep 10 13:56:51 2024 +0200 +++ b/hedgewars/uLand.pas Tue Sep 10 18:21:31 2024 +0200 @@ -32,7 +32,7 @@ implementation uses uConsole, uStore, uRandom, uLandObjects, uIO, uLandTexture, uVariables, uUtils, uCommands, adler32, uDebug, uLandPainted, uTextures, - uLandGenMaze, uPhysFSLayer, uScript, uLandGenPerlin, + uPhysFSLayer, uScript, uLandGenPerlin, uLandUtils, uRenderUtils; var digest: shortstring; @@ -794,7 +794,7 @@ WriteLnToConsole('Generating land...'); case cMapGen of mgRandom: GenerateOutlineTemplatedLand(cFeatureSize, cSeed, SelectTemplate, PathPrefix); - mgMaze : begin ResizeLand(4096,2048); GenMaze; end; + mgMaze : GenerateMazeLand(cFeatureSize, cSeed, SelectTemplate, PathPrefix); mgPerlin: begin ResizeLand(4096,2048); GenPerlin; end; mgDrawn : GenDrawnMap; mgForts : begin GameFlags:= (GameFlags or gfDivideTeams); MakeFortsMap(); end; @@ -950,7 +950,7 @@ WriteLnToConsole('Generating preview...'); case cMapGen of mgRandom: GenerateOutlineTemplatedLand(cFeatureSize, cSeed, SelectTemplate, PathPrefix); - mgMaze: begin ResizeLand(4096,2048); GenMaze; end; + mgMaze: GenerateMazeLand(cFeatureSize, cSeed, SelectTemplate, PathPrefix); mgPerlin: begin ResizeLand(4096,2048); GenPerlin; end; mgDrawn: begin GenDrawnMap; end; mgForts: MakeFortsPreview(); @@ -1010,7 +1010,7 @@ WriteLnToConsole('Generating preview...'); case cMapGen of mgRandom: GenerateOutlineTemplatedLand(cFeatureSize, cSeed, SelectTemplate, PathPrefix); - mgMaze: begin ResizeLand(4096,2048); GenMaze; end; + mgMaze: GenerateMazeLand(cFeatureSize, cSeed, SelectTemplate, PathPrefix); mgPerlin: begin ResizeLand(4096,2048); GenPerlin; end; mgDrawn: begin GenDrawnMap; end; mgForts: MakeFortsPreview; diff -r 31cc1e450273 -r 1860852892c0 hedgewars/uLandUtils.pas --- a/hedgewars/uLandUtils.pas Tue Sep 10 13:56:51 2024 +0200 +++ b/hedgewars/uLandUtils.pas Tue Sep 10 18:21:31 2024 +0200 @@ -4,6 +4,7 @@ procedure GenerateOutlineTemplatedLand(featureSize: Longword; seed, templateType: shortstring; dataPath: ansistring); procedure GenerateWfcTemplatedLand(featureSize: Longword; seed, templateType: shortstring; dataPath: ansistring); +procedure GenerateMazeLand(featureSize: Longword; seed, templateType: shortstring; dataPath: ansistring); procedure ResizeLand(width, height: LongWord); procedure DisposeLand(); procedure InitWorldEdges(); @@ -38,6 +39,7 @@ function generate_outline_templated_game_field(feature_size: Longword; seed, template_type, data_path: PChar): pointer; cdecl; external; function generate_wfc_templated_game_field(feature_size: Longword; seed, template_type, data_path: PChar): pointer; cdecl; external; +function generate_maze_game_field(feature_size: Longword; seed, template_type, data_path: PChar): pointer; cdecl; external; procedure apply_theme(game_field: pointer; data_path, theme_name: PChar); cdecl; external; var gameField: pointer; @@ -127,6 +129,31 @@ initScreenSpaceVars(); end; +procedure GenerateMazeLand(featureSize: Longword; seed, templateType: shortstring; dataPath: ansistring); +begin + seed[byte(seed[0]) + 1]:= #0; + templateType[byte(templateType[0]) + 1]:= #0; + + gameField:= generate_maze_game_field(featureSize, @seed[1], @templateType[1], PChar(dataPath)); + get_game_field_parameters(gameField, LAND_WIDTH, LAND_HEIGHT, playWidth, playHeight); + + MaxHedgehogs:= 32; + hasGirders:= true; + + leftX:= (LAND_WIDTH - playWidth) div 2; + rightX:= Pred(leftX + playWidth); + topY:= LAND_HEIGHT - playHeight; + cWaterLine:= LAND_HEIGHT; + + // let's assume those are powers of two + LAND_WIDTH_MASK:= not(LAND_WIDTH-1); + LAND_HEIGHT_MASK:= not(LAND_HEIGHT-1); + + SetLength(LandDirty, (LAND_HEIGHT div 32), (LAND_WIDTH div 32)); + + initScreenSpaceVars(); +end; + procedure ResizeLand(width, height: LongWord); var potW, potH: LongInt; begin diff -r 31cc1e450273 -r 1860852892c0 rust/landgen/src/maze.rs --- a/rust/landgen/src/maze.rs Tue Sep 10 13:56:51 2024 +0200 +++ b/rust/landgen/src/maze.rs Tue Sep 10 18:21:31 2024 +0200 @@ -4,12 +4,12 @@ use land2d::Land2D; pub struct MazeTemplate { - width: usize, - height: usize, - cell_size: usize, - inverted: bool, - distortion_limiting_factor: u32, - braidness: usize, + pub width: usize, + pub height: usize, + pub cell_size: usize, + pub inverted: bool, + pub distortion_limiting_factor: u32, + pub braidness: usize, } pub struct MazeLandGenerator { @@ -48,7 +48,7 @@ let mut step_done = vec![false; num_steps]; let mut last_cell = vec![Point::diag(0); num_steps]; let mut came_from_pos = vec![0; num_steps]; - let mut came_from = vec![vec![Point::diag(0); num_cells.area()]; num_steps]; + let mut came_from = vec![vec![Point::diag(0); num_steps]; num_cells.area()]; let mut done = false; let mut seen_list = vec![vec![None as Option; seen_cells.width]; seen_cells.height]; @@ -66,22 +66,21 @@ / num_steps; last_cell[current_step] = Point::new( (x + current_step * seen_cells.width / num_steps) as i32, - random_numbers.next().unwrap_or_default() as i32 / num_steps as i32, + random_numbers.next().unwrap_or_default() as i32 % seen_cells.height as i32, ); } let see_cell = |current_step: usize, start_dir: Point, seen_list: &mut Vec>>, x_walls: &mut Vec>, y_walls: &mut Vec>, last_cell: &mut Vec, came_from: &mut Vec>, came_from_pos: &mut Vec| { + let mut dir = start_dir; loop { - let p = last_cell[current_step]; - seen_list[p.y as usize][p.x as usize] = Some(current_step); - - let mut dir = start_dir; + let p = dbg!(last_cell[current_step]); + seen_list[p.y as usize][p.x as usize] = Some(dbg!(current_step)); let next_dir_clockwise = true;//random_numbers.next().unwrap_or_default() % 2 == 0; for _ in 0..5 { - let sp = p + dir; + let sp = dbg!(p) + dbg!(dir); let when_seen = if sp.x < 0 || sp.x >= seen_cells.width as i32 @@ -130,9 +129,10 @@ if dir.x == 1 { y_walls[p.y as usize][p.x as usize] = false; } - last_cell[current_step] = p + dir; + last_cell[current_step] = dbg!(sp); came_from_pos[current_step] += 1; came_from[came_from_pos[current_step] as usize][current_step] = p; + return true; } _ => { return true; @@ -277,7 +277,7 @@ OutlinePoints { islands, - fill_points: vec![], + fill_points: vec![Point::new(1, 1 + off_y)], size: *size, play_box, intersections_box, diff -r 31cc1e450273 -r 1860852892c0 rust/lib-hwengine-future/src/lib.rs --- a/rust/lib-hwengine-future/src/lib.rs Tue Sep 10 13:56:51 2024 +0200 +++ b/rust/lib-hwengine-future/src/lib.rs Tue Sep 10 18:21:31 2024 +0200 @@ -2,6 +2,7 @@ use landgen::{ outline_template_based::outline_template::OutlineTemplate, + maze::MazeTemplate, wavefront_collapse::generator::TemplateDescription as WfcTemplate, LandGenerationParameters, LandGenerator, }; @@ -126,6 +127,45 @@ } #[no_mangle] +pub extern "C" fn generate_maze_game_field( + feature_size: u32, + seed: *const i8, + template_type: *const i8, + data_path: *const i8, +) -> *mut GameField { + let data_path: &str = unsafe { CStr::from_ptr(data_path) }.to_str().unwrap(); + let data_path = Path::new(&data_path); + + let seed: &str = unsafe { CStr::from_ptr(seed) }.to_str().unwrap(); + let template_type: &str = unsafe { CStr::from_ptr(template_type) }.to_str().unwrap(); + + let mut random_numbers_gen = LaggedFibonacciPRNG::new(seed.as_bytes()); + + let map_gen = MapGenerator::::new(data_path); + let distance_divisor = feature_size.pow(2) / 8 + 10; + let params = LandGenerationParameters::new(0u16, 0x8000u16, distance_divisor, false, false); + let template = MazeTemplate { + width: 4096, + height: 2048, + cell_size: 80, + inverted: false, + distortion_limiting_factor: 100, + braidness: 10, + }; + let landgen = map_gen.build_generator(template); + let collision = landgen.generate_land(¶ms, &mut random_numbers_gen); + let size = collision.size().size(); + + let game_field = Box::new(GameField { + collision, + pixels: land2d::Land2D::new(&size, 0), + landgen_parameters: Some(params), + }); + + Box::leak(game_field) +} + +#[no_mangle] pub extern "C" fn apply_theme( game_field: &mut GameField, data_path: *const i8, diff -r 31cc1e450273 -r 1860852892c0 rust/mapgen/src/lib.rs --- a/rust/mapgen/src/lib.rs Tue Sep 10 13:56:51 2024 +0200 +++ b/rust/mapgen/src/lib.rs Tue Sep 10 18:21:31 2024 +0200 @@ -4,6 +4,8 @@ use self::theme::Theme; use crate::template::outline::TemplateCollectionDesc as OutlineTemplateCollectionDesc; use crate::template::wavefront_collapse::TemplateCollectionDesc as WfcTemplateCollectionDesc; +use crate::template::maze::TemplateCollectionDesc as MazeTemplateCollectionDesc; + use std::path::{Path, PathBuf}; use land2d::Land2D; @@ -187,7 +189,7 @@ .map(|(size, indices)| { ( TemplateType(size), - indices.iter().map(|i| (&templates[*i]).into()).collect(), + indices.indices.iter().map(|i| (&templates[*i]).into()).collect(), ) }) .collect(); diff -r 31cc1e450273 -r 1860852892c0 rust/mapgen/src/template/mod.rs --- a/rust/mapgen/src/template/mod.rs Tue Sep 10 13:56:51 2024 +0200 +++ b/rust/mapgen/src/template/mod.rs Tue Sep 10 18:21:31 2024 +0200 @@ -1,2 +1,3 @@ pub mod outline; pub mod wavefront_collapse; +pub mod maze;