comparison formats/src/th06/std.rs @ 774:d08eb4c9fce3

formats: Upgrade nom to version 8
author Link Mauve <linkmauve@linkmauve.fr>
date Mon, 29 Sep 2025 11:10:15 +0000
parents 21b186be2590
children 94033091458b
comparison
equal deleted inserted replaced
773:317e93b7d586 774:d08eb4c9fce3
1 //! STD background format support. 1 //! STD background format support.
2 2
3 use nom::{ 3 use nom::{
4 IResult, 4 IResult,
5 Parser,
5 bytes::complete::tag, 6 bytes::complete::tag,
6 number::complete::{le_u8, le_u16, le_u32, le_i32, le_f32}, 7 number::complete::{le_u8, le_u16, le_u32, le_i32, le_f32},
7 sequence::tuple,
8 combinator::map, 8 combinator::map,
9 multi::{many0, count}, 9 multi::{many0, count},
10 error::ErrorKind, 10 error::ErrorKind,
11 Err, 11 Err,
12 }; 12 };
162 4 => fn StartInterpolatingFog(frame: u32, _unused: i32, _unused: i32), 162 4 => fn StartInterpolatingFog(frame: u32, _unused: i32, _unused: i32),
163 5 => fn Unknown(_unused: i32, _unused: i32, _unused: i32), 163 5 => fn Unknown(_unused: i32, _unused: i32, _unused: i32),
164 } 164 }
165 165
166 fn parse_quad(i: &[u8]) -> IResult<&[u8], Quad> { 166 fn parse_quad(i: &[u8]) -> IResult<&[u8], Quad> {
167 let (i, (unk1, size)) = tuple((le_u16, le_u16))(i)?; 167 let (i, (unk1, size)) = (le_u16, le_u16).parse(i)?;
168 if unk1 == 0xffff { 168 if unk1 == 0xffff {
169 return Err(Err::Error(nom::error::Error::new(i, ErrorKind::Eof))); 169 return Err(Err::Error(nom::error::Error::new(i, ErrorKind::Eof)));
170 } 170 }
171 // TODO: replace this assert with a custom error. 171 // TODO: replace this assert with a custom error.
172 assert_eq!(size, 0x1c); 172 assert_eq!(size, 0x1c);
173 let (i, (anm_script, _, x, y, z, width, height)) = tuple((le_u16, tag(b"\0\0"), le_f32, le_f32, le_f32, le_f32, le_f32))(i)?; 173 let (i, (anm_script, _, x, y, z, width, height)) = (le_u16, tag(&b"\0\0"[..]), le_f32, le_f32, le_f32, le_f32, le_f32).parse(i)?;
174 let quad = Quad { 174 let quad = Quad {
175 anm_script, 175 anm_script,
176 pos: Position { x, y, z }, 176 pos: Position { x, y, z },
177 size_override: Box2D { width, height }, 177 size_override: Box2D { width, height },
178 }; 178 };
179 Ok((i, quad)) 179 Ok((i, quad))
180 } 180 }
181 181
182 fn parse_model(i: &[u8]) -> IResult<&[u8], Model> { 182 fn parse_model(i: &[u8]) -> IResult<&[u8], Model> {
183 let (i, (_id, unknown, x, y, z, width, height, depth, quads)) = tuple((le_u16, le_u16, le_f32, le_f32, le_f32, le_f32, le_f32, le_f32, many0(parse_quad)))(i)?; 183 let (i, (_id, unknown, x, y, z, width, height, depth, quads)) = (le_u16, le_u16, le_f32, le_f32, le_f32, le_f32, le_f32, le_f32, many0(parse_quad)).parse(i)?;
184 let bounding_box = [x, y, z, width, height, depth]; 184 let bounding_box = [x, y, z, width, height, depth];
185 let model = Model { 185 let model = Model {
186 unknown, 186 unknown,
187 bounding_box, 187 bounding_box,
188 quads, 188 quads,
189 }; 189 };
190 Ok((i, model)) 190 Ok((i, model))
191 } 191 }
192 192
193 fn parse_instance(i: &[u8]) -> IResult<&[u8], Instance> { 193 fn parse_instance(i: &[u8]) -> IResult<&[u8], Instance> {
194 let (i, (id, unknown, x, y, z)) = tuple((le_u16, le_u16, le_f32, le_f32, le_f32))(i)?; 194 let (i, (id, unknown, x, y, z)) = (le_u16, le_u16, le_f32, le_f32, le_f32).parse(i)?;
195 if id == 0xffff && unknown == 0xffff { 195 if id == 0xffff && unknown == 0xffff {
196 return Err(Err::Error(nom::error::Error::new(i, ErrorKind::Eof))); 196 return Err(Err::Error(nom::error::Error::new(i, ErrorKind::Eof)));
197 } 197 }
198 // TODO: replace this assert with a custom error. 198 // TODO: replace this assert with a custom error.
199 assert_eq!(unknown, 0x100); 199 assert_eq!(unknown, 0x100);
203 }; 203 };
204 Ok((i, instance)) 204 Ok((i, instance))
205 } 205 }
206 206
207 fn parse_instruction(i: &[u8]) -> IResult<&[u8], Call> { 207 fn parse_instruction(i: &[u8]) -> IResult<&[u8], Call> {
208 let (i, (time, opcode, size)) = tuple((le_u32, le_u16, le_u16))(i)?; 208 let (i, (time, opcode, size)) = (le_u32, le_u16, le_u16).parse(i)?;
209 if time == 0xffffffff && opcode == 0xffff && size == 0xffff { 209 if time == 0xffffffff && opcode == 0xffff && size == 0xffff {
210 return Err(Err::Error(nom::error::Error::new(i, ErrorKind::Eof))); 210 return Err(Err::Error(nom::error::Error::new(i, ErrorKind::Eof)));
211 } 211 }
212 // TODO: replace this assert with a custom error. 212 // TODO: replace this assert with a custom error.
213 assert_eq!(size, 12); 213 assert_eq!(size, 12);
218 } 218 }
219 219
220 fn parse_stage(input: &[u8]) -> IResult<&[u8], Stage> { 220 fn parse_stage(input: &[u8]) -> IResult<&[u8], Stage> {
221 let i = &input[..]; 221 let i = &input[..];
222 222
223 let (i, (num_models, _num_faces, object_instances_offset, script_offset, _, name, music_names, music_paths)) = tuple(( 223 let (i, (num_models, _num_faces, object_instances_offset, script_offset, _, name, music_names, music_paths)) = (
224 le_u16, le_u16, le_u32, le_u32, tag(b"\0\0\0\0"), 224 le_u16, le_u16, le_u32, le_u32, tag(&b"\0\0\0\0"[..]),
225 le_String, 225 le_String,
226 map(tuple((le_String, le_String, le_String, le_String)), |(a, b, c, d)| [a, b, c, d]), 226 map((le_String, le_String, le_String, le_String), |(a, b, c, d)| [a, b, c, d]),
227 map(tuple((le_String, le_String, le_String, le_String)), |(a, b, c, d)| [a, b, c, d]) 227 map((le_String, le_String, le_String, le_String), |(a, b, c, d)| [a, b, c, d])
228 ))(i)?; 228 ).parse(i)?;
229 let musics = music_names.iter().zip(&music_paths).map(|(name, path)| if name == " " { None } else { Some((name.clone(), path.clone())) }).collect(); 229 let musics = music_names.iter().zip(&music_paths).map(|(name, path)| if name == " " { None } else { Some((name.clone(), path.clone())) }).collect();
230 230
231 let (_, offsets) = count(le_u32, num_models as usize)(i)?; 231 let (_, offsets) = count(le_u32, num_models as usize).parse(i)?;
232 232
233 let mut models = vec![]; 233 let mut models = vec![];
234 for offset in offsets { 234 for offset in offsets {
235 let (_, model) = parse_model(&input[offset as usize..])?; 235 let (_, model) = parse_model(&input[offset as usize..])?;
236 models.push(model); 236 models.push(model);
237 } 237 }
238 238
239 let (_, instances) = many0(parse_instance)(&input[object_instances_offset as usize..])?; 239 let (_, instances) = many0(parse_instance).parse(&input[object_instances_offset as usize..])?;
240 let (_, script) = many0(parse_instruction)(&input[script_offset as usize..])?; 240 let (_, script) = many0(parse_instruction).parse(&input[script_offset as usize..])?;
241 241
242 let stage = Stage { 242 let stage = Stage {
243 name, 243 name,
244 musics, 244 musics,
245 models, 245 models,