Split generation and painting phases, paint by old engine, use template filters transitional_engine
authorunC0Rr
Wed, 04 Jan 2023 11:56:58 +0100
branchtransitional_engine
changeset 15905 022ec6b916b7
parent 15904 33798b649d9c
child 15906 b4809653f9d6
Split generation and painting phases, paint by old engine, use template filters
hedgewars/uLand.pas
hedgewars/uLandUtils.pas
rust/land2d/src/lib.rs
rust/landgen/src/lib.rs
rust/landgen/src/template_based.rs
rust/lib-hwengine-future/src/lib.rs
--- a/hedgewars/uLand.pas	Wed Jan 04 10:42:21 2023 +0100
+++ b/hedgewars/uLand.pas	Wed Jan 04 11:56:58 2023 +0100
@@ -355,12 +355,12 @@
     uLandPainted.Draw;
 end;
 
-function SelectTemplate: LongInt;
+function SelectTemplate: shortstring;
 var l: LongInt;
 begin
-    SelectTemplate:= 0;
+    SelectTemplate:= '';
     if (cReducedQuality and rqLowRes) <> 0 then
-        SelectTemplate:= SmallTemplates[getrandom(Succ(High(SmallTemplates)))]
+        SelectTemplate:= 'small'
     else
         begin
         if cTemplateFilter = 0 then
@@ -375,20 +375,20 @@
 
             case cTemplateFilter of
             0: OutError('Error selecting TemplateFilter. Ask unC0Rr about what you did wrong', true);
-            1: SelectTemplate:= SmallTemplates[getrandom(TemplateCounts[cTemplateFilter])];
-            2: SelectTemplate:= MediumTemplates[getrandom(TemplateCounts[cTemplateFilter])];
-            3: SelectTemplate:= LargeTemplates[getrandom(TemplateCounts[cTemplateFilter])];
-            4: SelectTemplate:= CavernTemplates[getrandom(TemplateCounts[cTemplateFilter])];
-            5: SelectTemplate:= WackyTemplates[getrandom(TemplateCounts[cTemplateFilter])];
+            1: SelectTemplate:= 'small';
+            2: SelectTemplate:= 'medium';
+            3: SelectTemplate:= 'large';
+            4: SelectTemplate:= 'cavern';
+            5: SelectTemplate:= 'wacky';
     // For lua only!
             6: begin
-               SelectTemplate:= min(LuaTemplateNumber,High(EdgeTemplates));
+               SelectTemplate:= 'small';
                GetRandom(2) // burn 1
                end
             end
         end;
 
-    WriteLnToConsole('Selected template #'+inttostr(SelectTemplate)+' using filter #'+inttostr(cTemplateFilter));
+    WriteLnToConsole('Using template filter '+SelectTemplate);
 end;
 
 procedure LandSurface2LandPixels(Surface: PSDL_Surface);
@@ -793,7 +793,7 @@
         begin
         WriteLnToConsole('Generating land...');
         case cMapGen of
-            mgRandom: CreateTemplatedLand(cFeatureSize, cSeed, PathPrefix, Theme);
+            mgRandom: GenerateTemplatedLand(cFeatureSize, cSeed, SelectTemplate, PathPrefix);
             mgMaze  : begin ResizeLand(4096,2048); GenMaze; end;
             mgPerlin: begin ResizeLand(4096,2048); GenPerlin; end;
             mgDrawn : GenDrawnMap;
@@ -801,7 +801,7 @@
         else
             OutError('Unknown mapgen', true);
         end;
-        if (cMapGen <> mgForts) and (cMapGen <> mgRandom) then
+        if (cMapGen <> mgForts) then
             GenLandSurface
         end;
 
@@ -948,7 +948,7 @@
 begin
     WriteLnToConsole('Generating preview...');
     case cMapGen of
-        mgRandom: CreateTemplatedLand(cFeatureSize, cSeed, PathPrefix, Theme);
+        mgRandom: GenerateTemplatedLand(cFeatureSize, cSeed, SelectTemplate, PathPrefix);
         mgMaze: begin ResizeLand(4096,2048); GenMaze; end;
         mgPerlin: begin ResizeLand(4096,2048); GenPerlin; end;
         mgDrawn: begin GenDrawnMap; end;
@@ -1007,7 +1007,7 @@
 begin
     WriteLnToConsole('Generating preview...');
     case cMapGen of
-        mgRandom: CreateTemplatedLand(cFeatureSize, cSeed, PathPrefix, Theme);
+        mgRandom: GenerateTemplatedLand(cFeatureSize, cSeed, SelectTemplate, PathPrefix);
         mgMaze: begin ResizeLand(4096,2048); GenMaze; end;
         mgPerlin: begin ResizeLand(4096,2048); GenPerlin; end;
         mgDrawn: begin GenDrawnMap; end;
--- a/hedgewars/uLandUtils.pas	Wed Jan 04 10:42:21 2023 +0100
+++ b/hedgewars/uLandUtils.pas	Wed Jan 04 11:56:58 2023 +0100
@@ -2,7 +2,7 @@
 interface
 uses SDLh;
 
-procedure CreateTemplatedLand(featureSize: Longword; seed, dataPath, theme: shortstring);
+procedure GenerateTemplatedLand(featureSize: Longword; seed, templateType, dataPath: shortstring);
 procedure ResizeLand(width, height: LongWord);
 procedure DisposeLand();
 procedure InitWorldEdges();
@@ -23,7 +23,7 @@
 const LibFutureName = 'hwengine_future';
 
 function  create_empty_game_field(width, height: Longword): pointer; cdecl; external LibFutureName;
-procedure get_game_field_parameters(game_field: pointer; var width: LongInt; var height: LongInt); cdecl; external LibFutureName;
+procedure get_game_field_parameters(game_field: pointer; var width: LongInt; var height: LongInt; var play_width: LongInt; var play_height: LongInt); cdecl; external LibFutureName;
 procedure dispose_game_field(game_field: pointer); cdecl; external LibFutureName;
 
 function  land_get(game_field: pointer; x, y: LongInt): Word; cdecl; external LibFutureName;
@@ -35,7 +35,8 @@
 procedure land_pixel_set(game_field: pointer; x, y: LongInt; value: Longword); cdecl; external LibFutureName;
 function  land_pixel_row(game_field: pointer; row: LongInt): PLongwordArray; cdecl; external LibFutureName;
 
-function  generate_templated_game_field(feature_size: Longword; seed, data_path, theme_name: PChar): pointer; cdecl; external LibFutureName;
+function  generate_templated_game_field(feature_size: Longword; seed, template_type, data_path: PChar): pointer; cdecl; external LibFutureName;
+procedure apply_theme(game_field: pointer; data_path, theme_name: PChar); cdecl; external LibFutureName;
 
 var gameField: pointer;
 
@@ -74,13 +75,21 @@
     LandPixelRow:= land_pixel_row(gameField, row)
 end;
 
-procedure CreateTemplatedLand(featureSize: Longword; seed, dataPath, theme: shortstring);
+procedure GenerateTemplatedLand(featureSize: Longword; seed, templateType, dataPath: shortstring);
 begin
     seed[byte(seed[0]) + 1]:= #0;
-    theme[byte(theme[0]) + 1]:= #0;
+    templateType[byte(templateType[0]) + 1]:= #0;
+
+    gameField:= generate_templated_game_field(featureSize, @seed[1], @templateType[1], Str2PChar(dataPath));
+    get_game_field_parameters(gameField, LAND_WIDTH, LAND_HEIGHT, playWidth, playHeight);
 
-    gameField:= generate_templated_game_field(featureSize, @seed[1], Str2PChar(dataPath), @theme[1]);
-    get_game_field_parameters(gameField, LAND_WIDTH, LAND_HEIGHT);
+    MaxHedgehogs:= 32;
+    hasGirders:= true;
+
+    leftX:= (LAND_WIDTH - playWidth) div 2;
+    rightX:= Pred(leftX + playWidth);
+    topY:= LAND_HEIGHT - playHeight;
+
 
     // let's assume those are powers of two
     LAND_WIDTH_MASK:= not(LAND_WIDTH-1);
--- a/rust/land2d/src/lib.rs	Wed Jan 04 10:42:21 2023 +0100
+++ b/rust/land2d/src/lib.rs	Wed Jan 04 11:56:58 2023 +0100
@@ -9,13 +9,13 @@
 }
 
 impl<T: Copy + PartialEq> Land2D<T> {
-    pub fn new(play_size: Size, fill_value: T) -> Self {
+    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,
         );
-        let play_box = Rect::from_size(top_left, play_size);
+        let play_box = Rect::from_size(top_left, *play_size);
         Self {
             play_box,
             pixels: vec2d::Vec2D::new(real_size.size(), fill_value),
--- a/rust/landgen/src/lib.rs	Wed Jan 04 10:42:21 2023 +0100
+++ b/rust/landgen/src/lib.rs	Wed Jan 04 11:56:58 2023 +0100
@@ -2,6 +2,7 @@
 pub mod outline_template;
 pub mod template_based;
 
+#[derive(Clone, Copy)]
 pub struct LandGenerationParameters<T> {
     zero: T,
     basic: T,
--- a/rust/landgen/src/template_based.rs	Wed Jan 04 10:42:21 2023 +0100
+++ b/rust/landgen/src/template_based.rs	Wed Jan 04 11:56:58 2023 +0100
@@ -21,7 +21,7 @@
         parameters: &LandGenerationParameters<T>,
         random_numbers: &mut I,
     ) -> Land2D<T> {
-        let mut land = Land2D::new(self.outline_template.size, parameters.basic);
+        let mut land = Land2D::new(&self.outline_template.size, parameters.basic);
 
         let mut points = OutlinePoints::from_outline_template(
             &self.outline_template,
--- a/rust/lib-hwengine-future/src/lib.rs	Wed Jan 04 10:42:21 2023 +0100
+++ b/rust/lib-hwengine-future/src/lib.rs	Wed Jan 04 11:56:58 2023 +0100
@@ -10,6 +10,7 @@
 pub struct GameField {
     collision: land2d::Land2D<u16>,
     pixels: land2d::Land2D<u32>,
+    landgen_parameters: Option<LandGenerationParameters<u16>>,
 }
 
 #[no_mangle]
@@ -17,18 +18,24 @@
     game_field: &GameField,
     width: *mut i32,
     height: *mut i32,
+    play_width: *mut i32,
+    play_height: *mut i32,
 ) {
     unsafe {
         *width = game_field.collision.width() as i32;
         *height = game_field.collision.height() as i32;
+
+        *play_width = game_field.collision.play_width() as i32;
+        *play_height = game_field.collision.play_height() as i32;
     }
 }
 
 #[no_mangle]
 pub extern "C" fn create_empty_game_field(width: u32, height: u32) -> *mut GameField {
     let game_field = Box::new(GameField {
-        collision: land2d::Land2D::new(Size::new(width as usize, height as usize), 0),
-        pixels: land2d::Land2D::new(Size::new(width as usize, height as usize), 0),
+        collision: land2d::Land2D::new(&Size::new(width as usize, height as usize), 0),
+        pixels: land2d::Land2D::new(&Size::new(width as usize, height as usize), 0),
+        landgen_parameters: None,
     });
 
     Box::leak(game_field)
@@ -38,14 +45,14 @@
 pub extern "C" fn generate_templated_game_field(
     feature_size: u32,
     seed: *const i8,
+    template_type: *const i8,
     data_path: *const i8,
-    theme_name: *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 theme_name: &str = unsafe { CStr::from_ptr(theme_name) }.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());
 
@@ -58,11 +65,33 @@
     let distance_divisor = feature_size.pow(2) / 8 + 10;
     let params = LandGenerationParameters::new(0u16, 0x8000u16, distance_divisor, false, false);
     let template = map_gen
-        .get_template("medium", &mut random_numbers_gen)
+        .get_template(template_type, &mut random_numbers_gen)
         .expect("Error reading map templates file")
         .clone();
     let landgen = TemplatedLandGenerator::new(template);
     let collision = landgen.generate_land(&params, &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,
+    theme_name: *const i8,
+) {
+    let data_path: &str = unsafe { CStr::from_ptr(data_path) }.to_str().unwrap();
+    let data_path = Path::new(&data_path);
+
+    let theme_name: &str = unsafe { CStr::from_ptr(theme_name) }.to_str().unwrap();
+    let map_gen = MapGenerator::new();
 
     let theme = Theme::load(
         data_path
@@ -71,14 +100,13 @@
             .as_path(),
     )
     .unwrap();
-    let pixels = map_gen.make_texture(&collision, &params, &theme);
 
-    let game_field = Box::new(GameField {
-        collision,
-        pixels: pixels.into(),
-    });
+    let params = game_field
+        .landgen_parameters
+        .expect("Land generator parameters specified");
+    let pixels = map_gen.make_texture(&game_field.collision, &params, &theme);
 
-    Box::leak(game_field)
+    game_field.pixels = pixels.into();
 }
 
 #[no_mangle]