25 |
25 |
26 #[derive(Clone)] |
26 #[derive(Clone)] |
27 pub struct TileDescription { |
27 pub struct TileDescription { |
28 pub name: String, |
28 pub name: String, |
29 pub edges: EdgesDescription, |
29 pub edges: EdgesDescription, |
|
30 pub is_negative: bool, |
30 pub can_flip: bool, |
31 pub can_flip: bool, |
31 pub can_mirror: bool, |
32 pub can_mirror: bool, |
32 pub can_rotate90: bool, |
33 pub can_rotate90: bool, |
33 pub can_rotate180: bool, |
34 pub can_rotate180: bool, |
34 pub can_rotate270: bool, |
35 pub can_rotate270: bool, |
35 } |
36 } |
36 |
37 |
|
38 #[derive(Clone)] |
37 pub struct TemplateDescription { |
39 pub struct TemplateDescription { |
38 pub size: Size, |
40 pub size: Size, |
39 pub tiles: Vec<TileDescription>, |
41 pub tiles: Vec<TileDescription>, |
40 } |
42 } |
41 |
43 |
48 Self { template } |
50 Self { template } |
49 } |
51 } |
50 |
52 |
51 fn load_image_tiles<T: Copy + PartialEq + Default>( |
53 fn load_image_tiles<T: Copy + PartialEq + Default>( |
52 parameters: &LandGenerationParameters<T>, |
54 parameters: &LandGenerationParameters<T>, |
53 path: &Path, |
55 tile_description: &TileDescription, |
54 ) -> Result<Vec<TileImage<T, String>>> { |
56 ) -> Result<Vec<TileImage<T, String>>> { |
55 let mut result = Vec::new(); |
57 let mut result = Vec::new(); |
56 |
58 |
57 let file = File::open(path)?; |
59 let file = File::open( |
|
60 Path::new("../share/hedgewars/Data/Tiles") |
|
61 .join(&tile_description.name) |
|
62 .as_path(), |
|
63 )?; |
58 let decoder = Decoder::new(BufReader::new(file)); |
64 let decoder = Decoder::new(BufReader::new(file)); |
59 let mut reader = decoder.read_info().unwrap(); |
65 let mut reader = decoder.read_info().unwrap(); |
60 |
66 |
61 let info = reader.info(); |
67 let info = reader.info(); |
62 let mut tiles_image = vec2d::Vec2D::new( |
68 let mut tiles_image = vec2d::Vec2D::new( |
66 |
72 |
67 let mut buf = vec![0; reader.output_buffer_size()]; |
73 let mut buf = vec![0; reader.output_buffer_size()]; |
68 let info = reader.next_frame(&mut buf).unwrap(); |
74 let info = reader.next_frame(&mut buf).unwrap(); |
69 let bytes = &buf[..info.buffer_size()]; |
75 let bytes = &buf[..info.buffer_size()]; |
70 |
76 |
71 let mut tiles_image_pixels = tiles_image.as_mut_slice().into_iter(); |
77 let mut tiles_image_pixels = tiles_image.as_mut_slice().iter_mut(); |
72 |
78 |
73 for line in bytes.chunks_exact(info.line_size) { |
79 let (zero, basic) = if tile_description.is_negative { |
74 for value in line.chunks_exact(info.color_type.samples()) { |
80 (parameters.basic(), parameters.zero()) |
75 *tiles_image_pixels |
81 } else { |
76 .next() |
82 (parameters.zero(), parameters.basic()) |
77 .expect("vec2d size matching image dimensions") = |
83 }; |
78 if value.into_iter().all(|p| *p == 0) { |
84 |
79 parameters.zero |
85 match info.color_type.samples() { |
80 } else { |
86 1 => { |
81 parameters.basic |
87 for line in bytes.chunks_exact(info.line_size) { |
82 }; |
88 for value in line.iter() { |
83 } |
89 *tiles_image_pixels |
84 } |
90 .next() |
85 |
91 .expect("vec2d size matching image dimensions") = |
86 let top_edge = Edge::new("ef".to_owned(), false); |
92 if *value == 0 { zero } else { basic }; |
87 let right_edge = top_edge.reversed(); |
93 } |
88 let bottom_edge = Edge::new("ee".to_owned(), true); |
94 } |
89 let left_edge = bottom_edge.clone(); |
95 } |
90 |
96 a => { |
91 let tile = |
97 for line in bytes.chunks_exact(info.line_size) { |
92 TileImage::<T, String>::new(tiles_image, top_edge, right_edge, bottom_edge, left_edge); |
98 for value in line.chunks_exact(a) { |
|
99 print!("{:?},", value); |
|
100 *tiles_image_pixels |
|
101 .next() |
|
102 .expect("vec2d size matching image dimensions") = |
|
103 if value[0] == 0u8 { |
|
104 zero |
|
105 } else { |
|
106 basic |
|
107 }; |
|
108 } |
|
109 } |
|
110 } |
|
111 } |
|
112 |
|
113 let edges: Vec<Edge<String>> = [ |
|
114 &tile_description.edges.top, |
|
115 &tile_description.edges.right, |
|
116 &tile_description.edges.bottom, |
|
117 &tile_description.edges.left, |
|
118 ] |
|
119 .iter() |
|
120 .map(|descr| { |
|
121 let edge = Edge::new(descr.name.clone(), descr.symmetrical.unwrap_or_default()); |
|
122 |
|
123 if descr.reversed.unwrap_or_default() { |
|
124 edge.reversed() |
|
125 } else { |
|
126 edge |
|
127 } |
|
128 }) |
|
129 .collect(); |
|
130 |
|
131 let [top_edge, right_edge, bottom_edge, left_edge] = edges.as_slice() else { |
|
132 unreachable!() |
|
133 }; |
|
134 |
|
135 let tile = TileImage::<T, String>::new( |
|
136 tiles_image, |
|
137 top_edge.clone(), |
|
138 right_edge.clone(), |
|
139 bottom_edge.clone(), |
|
140 left_edge.clone(), |
|
141 ); |
93 |
142 |
94 result.push(tile.clone()); |
143 result.push(tile.clone()); |
95 result.push(tile.flipped()); |
144 |
96 result.push(tile.mirrored()); |
145 if tile_description.can_flip { |
97 result.push(tile.mirrored().flipped()); |
146 result.push(tile.flipped()); |
98 result.push(tile.rotated90()); |
147 } |
99 result.push(tile.rotated180()); |
148 if tile_description.can_mirror { |
100 result.push(tile.rotated270()); |
149 result.push(tile.mirrored()); |
|
150 } |
|
151 if tile_description.can_flip && tile_description.can_mirror { |
|
152 result.push(tile.mirrored().flipped()); |
|
153 } |
|
154 |
|
155 if tile_description.can_rotate90 { |
|
156 result.push(tile.rotated90()); |
|
157 } |
|
158 if tile_description.can_rotate180 { |
|
159 result.push(tile.rotated180()); |
|
160 } |
|
161 if tile_description.can_rotate270 { |
|
162 result.push(tile.rotated270()); |
|
163 } |
101 |
164 |
102 Ok(result) |
165 Ok(result) |
103 } |
166 } |
104 |
167 |
105 pub fn load_template<T: Copy + PartialEq + Default>( |
168 pub fn load_template<T: Copy + PartialEq + Default>( |
106 &self, |
169 &self, |
107 parameters: &LandGenerationParameters<T>, |
170 parameters: &LandGenerationParameters<T>, |
108 ) -> Vec<TileImage<T, String>> { |
171 ) -> Vec<TileImage<T, String>> { |
109 let mut result = Vec::new(); |
172 let mut result = Vec::new(); |
110 |
173 |
111 if let Ok(mut tiles) = Self::load_image_tiles(parameters, Path::new("sample.png")) { |
174 for tile_description in self.template.tiles.iter() { |
112 result.append(&mut tiles); |
175 if let Ok(mut tiles) = Self::load_image_tiles(parameters, tile_description) { |
|
176 result.append(&mut tiles); |
|
177 } |
113 } |
178 } |
114 |
179 |
115 result |
180 result |
116 } |
181 } |
117 } |
182 } |