1use std::io::{Cursor, Seek, SeekFrom};
5
6use crate::ByteSpan;
7use binrw::BinRead;
8use binrw::binrw;
9
10#[binrw]
11#[br(little)]
12#[repr(C)]
13#[derive(Debug, Clone, Copy)]
14pub struct RacialScalingParameters {
15 pub male_min_size: f32,
17 pub male_max_size: f32,
19
20 pub male_min_tail: f32,
22 pub male_max_tail: f32,
24
25 pub female_min_size: f32,
27 pub female_max_size: f32,
29
30 pub female_min_tail: f32,
32 pub female_max_tail: f32,
34
35 pub bust_min_x: f32,
37 pub bust_min_y: f32,
39 pub bust_min_z: f32,
41
42 pub bust_max_x: f32,
44 pub bust_max_y: f32,
46 pub bust_max_z: f32,
48}
49
50#[derive(Debug)]
51pub struct CMP {
52 pub parameters: Vec<RacialScalingParameters>,
54}
55
56impl CMP {
57 pub fn from_existing(buffer: ByteSpan) -> Option<CMP> {
59 let mut cursor = Cursor::new(buffer);
60
61 cursor.seek(SeekFrom::Start(0x2a800)).ok()?;
62
63 let rem = buffer.len() - cursor.position() as usize;
64 let entries = rem / std::mem::size_of::<RacialScalingParameters>();
65
66 let mut parameters = vec![];
67
68 for _ in 0..entries {
69 parameters.push(RacialScalingParameters::read(&mut cursor).ok()?);
70 }
71
72 Some(CMP { parameters })
73 }
74}
75
76#[cfg(test)]
77mod tests {
78 use std::fs::read;
79 use std::path::PathBuf;
80
81 use super::*;
82
83 #[test]
84 fn test_invalid() {
85 let mut d = PathBuf::from(env!("CARGO_MANIFEST_DIR"));
86 d.push("resources/tests");
87 d.push("random");
88
89 CMP::from_existing(&read(d).unwrap());
91 }
92}