--- a/.gitignore Wed Jan 04 10:40:40 2023 +0100
+++ b/.gitignore Wed Jan 04 10:42:21 2023 +0100
@@ -32,7 +32,7 @@
misc/libphysfs/Xcode/build/
misc/libphyslayer/Xcode/build/
moc_*.cxx_parameters
-relre:^release\/
+relre:^release/
*.log
*.cmd
*.diff
--- a/hedgewars/uLand.pas Wed Jan 04 10:40:40 2023 +0100
+++ b/hedgewars/uLand.pas Wed Jan 04 10:42:21 2023 +0100
@@ -793,7 +793,7 @@
begin
WriteLnToConsole('Generating land...');
case cMapGen of
- mgRandom: GenTemplated(EdgeTemplates[SelectTemplate]);
+ mgRandom: CreateTemplatedLand(cFeatureSize, cSeed, PathPrefix, Theme);
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 then
+ if (cMapGen <> mgForts) and (cMapGen <> mgRandom) then
GenLandSurface
end;
@@ -948,7 +948,7 @@
begin
WriteLnToConsole('Generating preview...');
case cMapGen of
- mgRandom: GenTemplated(EdgeTemplates[SelectTemplate]);
+ mgRandom: CreateTemplatedLand(cFeatureSize, cSeed, PathPrefix, Theme);
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: GenTemplated(EdgeTemplates[SelectTemplate]);
+ mgRandom: CreateTemplatedLand(cFeatureSize, cSeed, PathPrefix, Theme);
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:40:40 2023 +0100
+++ b/hedgewars/uLandUtils.pas Wed Jan 04 10:42:21 2023 +0100
@@ -2,6 +2,7 @@
interface
uses SDLh;
+procedure CreateTemplatedLand(featureSize: Longword; seed, dataPath, theme: shortstring);
procedure ResizeLand(width, height: LongWord);
procedure DisposeLand();
procedure InitWorldEdges();
@@ -20,8 +21,11 @@
uses uUtils, uConsts, uVariables, uTypes;
const LibFutureName = 'hwengine_future';
-function create_game_field(width, height: Longword): pointer; cdecl; external LibFutureName;
+
+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 dispose_game_field(game_field: pointer); cdecl; external LibFutureName;
+
function land_get(game_field: pointer; x, y: LongInt): Word; cdecl; external LibFutureName;
procedure land_set(game_field: pointer; x, y: LongInt; value: Word); cdecl; external LibFutureName;
function land_row(game_field: pointer; row: LongInt): PWordArray; cdecl; external LibFutureName;
@@ -31,6 +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;
+
var gameField: pointer;
function LandGet(y, x: LongInt): Word;
@@ -68,6 +74,23 @@
LandPixelRow:= land_pixel_row(gameField, row)
end;
+procedure CreateTemplatedLand(featureSize: Longword; seed, dataPath, theme: shortstring);
+begin
+ seed[byte(seed[0]) + 1]:= #0;
+ theme[byte(theme[0]) + 1]:= #0;
+
+ gameField:= generate_templated_game_field(featureSize, @seed[1], Str2PChar(dataPath), @theme[1]);
+ get_game_field_parameters(gameField, LAND_WIDTH, 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
@@ -81,7 +104,7 @@
LAND_HEIGHT_MASK:= not(LAND_HEIGHT-1);
cWaterLine:= LAND_HEIGHT;
- gameField:= create_game_field(LAND_WIDTH, LAND_HEIGHT);
+ gameField:= create_empty_game_field(LAND_WIDTH, LAND_HEIGHT);
SetLength(LandDirty, (LAND_HEIGHT div 32), (LAND_WIDTH div 32));
// 0.5 is already approaching on unplayable
if (width div 4096 >= 2) or (height div 2048 >= 2) then cMaxZoomLevel:= cMaxZoomLevel/2;
--- a/rust/land2d/src/lib.rs Wed Jan 04 10:40:40 2023 +0100
+++ b/rust/land2d/src/lib.rs Wed Jan 04 10:42:21 2023 +0100
@@ -1,5 +1,5 @@
use std::{cmp, ops::Index, ops::IndexMut};
-
+use vec2d::Vec2D;
use integral_geometry::{ArcPoints, EquidistantPoints, Line, Point, PotSize, Rect, Size, SizeMask};
pub struct Land2D<T> {
@@ -295,6 +295,23 @@
}
}
+impl<T> From<Vec2D<T>> for Land2D<T> {
+ fn from(vec: Vec2D<T>) -> Self {
+ let actual_size = vec.size();
+ let pot_size = actual_size.next_power_of_two();
+
+ assert_eq!(actual_size, pot_size.size());
+
+ let top_left = Point::new(0, 0);
+ let play_box = Rect::from_size(top_left, actual_size);
+ Self {
+ play_box,
+ pixels: vec,
+ mask: pot_size.to_mask(),
+ }
+ }
+}
+
#[cfg(test)]
mod tests {
use super::*;
--- a/rust/lib-hwengine-future/Cargo.toml Wed Jan 04 10:40:40 2023 +0100
+++ b/rust/lib-hwengine-future/Cargo.toml Wed Jan 04 10:42:21 2023 +0100
@@ -9,6 +9,9 @@
[dependencies]
land2d = { path = "../land2d" }
integral-geometry = { path = "../integral-geometry" }
+mapgen = { path = "../mapgen" }
+landgen = { path = "../landgen" }
+lfprng = { path = "../lfprng" }
[lib]
name = "hwengine_future"
--- a/rust/lib-hwengine-future/src/lib.rs Wed Jan 04 10:40:40 2023 +0100
+++ b/rust/lib-hwengine-future/src/lib.rs Wed Jan 04 10:42:21 2023 +0100
@@ -1,5 +1,10 @@
use integral_geometry::{Point, Size};
use land2d;
+use landgen::{template_based::TemplatedLandGenerator, LandGenerationParameters, LandGenerator};
+use lfprng::LaggedFibonacciPRNG;
+use mapgen::{theme::Theme, MapGenerator};
+use std::fs;
+use std::{ffi::CStr, path::Path};
#[repr(C)]
pub struct GameField {
@@ -8,7 +13,19 @@
}
#[no_mangle]
-pub extern "C" fn create_game_field(width: u32, height: u32) -> *mut GameField {
+pub extern "C" fn get_game_field_parameters(
+ game_field: &GameField,
+ width: *mut i32,
+ height: *mut i32,
+) {
+ unsafe {
+ *width = game_field.collision.width() as i32;
+ *height = game_field.collision.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),
@@ -18,6 +35,53 @@
}
#[no_mangle]
+pub extern "C" fn generate_templated_game_field(
+ feature_size: u32,
+ seed: *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 mut random_numbers_gen = LaggedFibonacciPRNG::new(seed.as_bytes());
+
+ let yaml_templates =
+ fs::read_to_string(data_path.join(Path::new("map_templates.yaml")).as_path())
+ .expect("Error reading map templates file");
+ let mut map_gen = MapGenerator::new();
+ map_gen.import_yaml_templates(&yaml_templates);
+
+ 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)
+ .expect("Error reading map templates file")
+ .clone();
+ let landgen = TemplatedLandGenerator::new(template);
+ let collision = landgen.generate_land(¶ms, &mut random_numbers_gen);
+
+ let theme = Theme::load(
+ data_path
+ .join(Path::new("Themes"))
+ .join(Path::new(theme_name))
+ .as_path(),
+ )
+ .unwrap();
+ let pixels = map_gen.make_texture(&collision, ¶ms, &theme);
+
+ let game_field = Box::new(GameField {
+ collision,
+ pixels: pixels.into(),
+ });
+
+ Box::leak(game_field)
+}
+
+#[no_mangle]
pub extern "C" fn land_get(game_field: &mut GameField, x: i32, y: i32) -> u16 {
game_field.collision.map(y, x, |p| *p)
}