1#![allow(clippy::arc_with_non_send_sync)]
5
6use crate::havok::byte_reader::ByteReader;
7use crate::havok::object::{
8 HavokInteger, HavokObject, HavokObjectType, HavokObjectTypeMember, HavokRootObject, HavokValue,
9 HavokValueType,
10};
11use crate::havok::slice_ext::SliceByteOrderExt;
12use core::cell::RefCell;
13use std::collections::HashMap;
14use std::sync::Arc;
15
16#[repr(i8)]
17enum HavokTagType {
18 Eof = -1,
19 Invalid = 0,
20 FileInfo = 1,
21 Type = 2,
22 Object = 3,
23 ObjectRemember = 4,
24 Backref = 5,
25 ObjectNull = 6,
26 FileEnd = 7,
27}
28
29impl HavokTagType {
30 pub fn from_raw(raw: u8) -> Self {
31 match raw {
32 255 => HavokTagType::Eof,
33 0 => HavokTagType::Invalid,
34 1 => HavokTagType::FileInfo,
35 2 => HavokTagType::Type,
36 3 => HavokTagType::Object,
37 4 => HavokTagType::ObjectRemember,
38 5 => HavokTagType::Backref,
39 6 => HavokTagType::ObjectNull,
40 7 => HavokTagType::FileEnd,
41 _ => panic!(),
42 }
43 }
44}
45
46pub struct HavokBinaryTagFileReader<'a> {
47 file_version: u8,
48 remembered_strings: Vec<Arc<str>>,
49 remembered_types: Vec<Arc<HavokObjectType>>,
50 remembered_objects: Vec<Arc<RefCell<HavokObject>>>,
51 objects: Vec<Arc<RefCell<HavokObject>>>,
52 reader: ByteReader<'a>,
53}
54
55impl<'a> HavokBinaryTagFileReader<'a> {
56 pub fn read(data: &'a [u8]) -> HavokRootObject {
57 let mut reader = Self::new(ByteReader::new(data));
58
59 reader.do_read()
60 }
61
62 fn new(reader: ByteReader<'a>) -> Self {
63 let file_version = 0;
64 let remembered_strings = vec![Arc::from("string"), Arc::from("")];
65 let remembered_types = vec![Arc::new(HavokObjectType::new(
66 Arc::from("object"),
67 None,
68 Vec::new(),
69 ))];
70 let remembered_objects = Vec::new();
71 let objects = Vec::new();
72
73 Self {
74 file_version,
75 remembered_strings,
76 remembered_types,
77 remembered_objects,
78 objects,
79 reader,
80 }
81 }
82
83 fn do_read(&mut self) -> HavokRootObject {
84 let signature1 = self.reader.read_bytes(4).to_int_le::<u32>();
85 let signature2 = self.reader.read_bytes(4).to_int_le::<u32>();
86 if signature1 != 0xCAB0_0D1E || signature2 != 0xD011_FACE {
87 panic!()
88 }
89
90 loop {
91 let tag_type = HavokTagType::from_raw(self.read_packed_int() as u8);
92 match tag_type {
93 HavokTagType::FileInfo => {
94 self.file_version = self.read_packed_int() as u8;
95 assert_eq!(self.file_version, 3, "Unimplemented version");
96 self.remembered_objects
97 .push(Arc::new(RefCell::new(HavokObject::new(
98 self.remembered_types[0].clone(),
99 HashMap::new(),
100 ))))
101 }
102 HavokTagType::Type => {
103 let object_type = self.read_type();
104 self.remembered_types.push(Arc::new(object_type));
105 }
106 HavokTagType::Backref => panic!(),
107 HavokTagType::ObjectRemember => {
108 let object = Arc::new(RefCell::new(self.read_object()));
109
110 self.remembered_objects.push(object.clone());
111 self.objects.push(object);
112 }
113 HavokTagType::FileEnd => {
114 break;
115 }
116 _ => panic!(),
117 }
118 }
119
120 for object in &self.objects {
122 self.fill_object_reference(&mut object.borrow_mut());
123 }
124
125 HavokRootObject::new(self.remembered_objects[1].clone())
126 }
127
128 fn read_object(&mut self) -> HavokObject {
129 let object_type_index = self.read_packed_int();
130 let object_type = self.remembered_types[object_type_index as usize].clone();
131
132 let members = object_type.members();
133 let data_existence = self.read_bit_field(members.len());
134
135 let data = members
136 .into_iter()
137 .enumerate()
138 .map(|(index, member)| {
139 let value = if data_existence[index] {
140 self.read_object_member_value(member)
141 } else {
142 Self::default_value(member.type_)
143 };
144 (index, value)
145 })
146 .collect::<HashMap<_, _>>();
147
148 HavokObject::new(object_type.clone(), data)
149 }
150
151 fn read_object_member_value(&mut self, member: &HavokObjectTypeMember) -> HavokValue {
152 if member.type_.is_array() {
153 let array_len = self.read_packed_int();
154 if member.type_.base_type() == HavokValueType::OBJECT && member.class_name.is_none() {
155 panic!()
156 }
157
158 HavokValue::Array(self.read_array(member, array_len as usize))
159 } else {
160 match member.type_ {
161 HavokValueType::BYTE => HavokValue::Integer(self.reader.read() as i32),
162 HavokValueType::INT => HavokValue::Integer(self.read_packed_int()),
163 HavokValueType::REAL => HavokValue::Real(self.reader.read_f32_le()),
164 HavokValueType::STRING => HavokValue::String(self.read_string()),
165 HavokValueType::OBJECT => {
166 HavokValue::ObjectReference(self.read_packed_int() as usize)
167 }
168 _ => panic!("unimplemented {}", member.type_.bits()),
169 }
170 }
171 }
172
173 fn read_array(&mut self, member: &HavokObjectTypeMember, array_len: usize) -> Vec<HavokValue> {
174 let base_type = member.type_.base_type();
175 match base_type {
176 HavokValueType::STRING => (0..array_len)
177 .map(|_| HavokValue::String(self.read_string()))
178 .collect::<Vec<_>>(),
179 HavokValueType::STRUCT => {
180 let target_type = self.find_type(member.class_name.as_ref().unwrap());
181 let data_existence = self.read_bit_field(target_type.member_count());
182
183 let mut result_objects = Vec::new();
184 for _ in 0..array_len {
185 let object = Arc::new(RefCell::new(HavokObject::new(
186 target_type.clone(),
187 HashMap::new(),
188 )));
189
190 result_objects.push(object.clone());
191 self.objects.push(object);
192 }
193
194 for (member_index, member) in target_type.members().into_iter().enumerate() {
196 if data_existence[member_index] {
197 if member.type_.is_tuple() {
198 panic!()
199 } else {
200 let data = self.read_array(member, array_len);
201 for (index, item) in data.into_iter().enumerate() {
202 result_objects[index].borrow_mut().set(member_index, item);
203 }
204 }
205 }
206 }
207
208 result_objects
209 .into_iter()
210 .map(HavokValue::Object)
211 .collect::<Vec<_>>()
212 }
213 HavokValueType::OBJECT => (0..array_len)
214 .map(|_| {
215 let object_index = self.read_packed_int();
216
217 HavokValue::ObjectReference(object_index as usize)
218 })
219 .collect::<Vec<_>>(),
220 HavokValueType::BYTE => (0..array_len)
221 .map(|_| HavokValue::Integer(self.reader.read() as HavokInteger))
222 .collect::<Vec<_>>(),
223 HavokValueType::INT => {
224 if self.file_version >= 3 {
225 self.read_packed_int(); }
227 (0..array_len)
228 .map(|_| HavokValue::Integer(self.read_packed_int()))
229 .collect::<Vec<_>>()
230 }
231 HavokValueType::REAL => (0..array_len)
232 .map(|_| HavokValue::Real(self.reader.read_f32_le()))
233 .collect::<Vec<_>>(),
234 HavokValueType::VEC4
235 | HavokValueType::VEC8
236 | HavokValueType::VEC12
237 | HavokValueType::VEC16 => {
238 let vec_size = member.type_.base_type().vec_size() as usize;
239 (0..array_len)
240 .map(|_| {
241 HavokValue::Vec(
242 (0..vec_size)
243 .map(|_| self.reader.read_f32_le())
244 .collect::<Vec<_>>(),
245 )
246 })
247 .collect::<Vec<_>>()
248 }
249 _ => panic!(
250 "unimplemented {} {}",
251 member.type_.bits(),
252 member.type_.base_type().bits()
253 ),
254 }
255 }
256
257 fn read_type(&mut self) -> HavokObjectType {
258 let name = self.read_string();
259 let _version = self.read_packed_int();
260 let parent = self.read_packed_int();
261 let member_count = self.read_packed_int();
262
263 let parent = self.remembered_types[parent as usize].clone();
264 let members = (0..member_count)
265 .map(|_| {
266 let member_name = self.read_string();
267 let type_ = HavokValueType::from_bits(self.read_packed_int() as u32).unwrap();
268
269 let tuple_size = if type_.is_tuple() {
270 self.read_packed_int()
271 } else {
272 0
273 };
274 let type_name = if type_.base_type() == HavokValueType::OBJECT
275 || type_.base_type() == HavokValueType::STRUCT
276 {
277 Some(self.read_string())
278 } else {
279 None
280 };
281
282 HavokObjectTypeMember::new(member_name, type_, tuple_size as u32, type_name)
283 })
284 .collect::<Vec<_>>();
285
286 HavokObjectType::new(name, Some(parent), members)
287 }
288
289 fn read_string(&mut self) -> Arc<str> {
290 let length = self.read_packed_int();
291 if length < 0 {
292 return self.remembered_strings[-length as usize].clone();
293 }
294
295 let result = Arc::from(
296 std::str::from_utf8(self.reader.read_bytes(length as usize))
297 .unwrap()
298 .to_owned(),
299 );
300 self.remembered_strings.push(Arc::clone(&result));
301
302 result
303 }
304
305 fn read_bit_field(&mut self, count: usize) -> Vec<bool> {
306 let bytes_to_read = ((count + 7) & 0xffff_fff8) / 8;
307 let bytes = self.reader.read_bytes(bytes_to_read);
308
309 let mut result = Vec::with_capacity(count);
310 for byte in bytes {
311 let mut byte = *byte;
312 for _ in 0..8 {
313 result.push((byte & 1) == 1);
314 byte >>= 1;
315
316 if result.len() == count {
317 break;
318 }
319 }
320 }
321
322 result
323 }
324
325 fn read_packed_int(&mut self) -> HavokInteger {
326 let mut byte = self.reader.read();
327
328 let mut result = ((byte & 0x7f) >> 1) as u32;
329 let neg = byte & 1;
330
331 let mut shift = 6;
332 while byte & 0x80 != 0 {
333 byte = self.reader.read();
334
335 result |= ((byte as u32) & 0xffff_ff7f) << shift;
336 shift += 7;
337 }
338 if neg == 1 {
339 -(result as HavokInteger)
340 } else {
341 result as HavokInteger
342 }
343 }
344
345 fn find_type(&self, type_name: &str) -> Arc<HavokObjectType> {
346 self.remembered_types
347 .iter()
348 .find(|&x| &*x.name == type_name)
349 .unwrap()
350 .clone()
351 }
352
353 fn fill_object_reference(&self, object: &mut HavokObject) {
354 let mut values_to_update = Vec::new();
355 for (index, mut value) in object.members_mut() {
356 match &mut value {
357 HavokValue::ObjectReference(x) => {
358 let object_ref = &self.remembered_objects[*x];
359 values_to_update.push((*index, HavokValue::Object(object_ref.clone())));
360 }
361 HavokValue::Array(x) => {
362 x.iter_mut().for_each(|item| {
363 if let HavokValue::ObjectReference(x) = item {
364 let object_ref = &self.remembered_objects[*x];
365
366 *item = HavokValue::Object(object_ref.clone())
367 }
368 });
369 }
370 _ => {}
371 }
372 }
373
374 for (index, value) in values_to_update {
375 object.set(index, value);
376 }
377 }
378
379 fn default_value(type_: HavokValueType) -> HavokValue {
380 if type_.is_vec() {
381 HavokValue::Array(
382 (0..type_.vec_size())
383 .map(|_| Self::default_value(type_.base_type()))
384 .collect::<Vec<_>>(),
385 )
386 } else if type_.is_array() || type_.is_tuple() {
387 HavokValue::Array(Vec::new())
388 } else {
389 match type_ {
390 HavokValueType::EMPTY => HavokValue::Integer(HavokInteger::default()),
391 HavokValueType::BYTE => HavokValue::Integer(HavokInteger::default()),
392 HavokValueType::INT => HavokValue::Integer(HavokInteger::default()),
393 HavokValueType::OBJECT => HavokValue::ObjectReference(0),
394 _ => panic!("unimplemented {}", type_.bits()),
395 }
396 }
397 }
398}