inferring more about the format

This commit is contained in:
lifning 2021-01-16 04:55:20 -08:00
parent 202f6cd640
commit c972b7a7c1
1 changed files with 18 additions and 10 deletions

View File

@ -17,14 +17,21 @@ fn string_binwrite_helper(pad_to_len: usize) -> impl Fn(&String) -> Vec<u8> {
}
}
// i'm having trouble thinking atm because noisy ps3 game being played next to me
// stats on _unknown1 and category:
// $ find . -name \*.one -exec bash -c "onear tf "{}" > "{}".txt" \;
// $ fd one.txt | xargs cat | sed 's/count: .*/..}/' | grep 'category' | sort | uniq -c
// 1 JodOne{_unknown1: 0xca, category: Default, ..}
// 11 JodOne{_unknown1: 0xca, category: landData, ..}
// 4 JodOne{_unknown1: 0xcb, category: landData, ..}
// 988 JodOne{_unknown1: 0xcc, category: Default, ..}
// 1579 JodOne{_unknown1: 0xcc, category: landData, ..}
#[derive(BinRead)]
#[derive(BinWrite)]
#[br(little, magic = b"ThisIsOneFile\0\0\0")]
#[binwrite(little)]
pub struct JodOne {
// usually 0xCC... format version maybe?
// usually 0xCC... archive creator version maybe?
// but i've seen 0xCA in Test04/disp/Test04.one and 0xCB in Test05/disp/stg2010_sun.one
_unknown1: u32,
// usually "Default" or "landData"
@ -33,6 +40,8 @@ pub struct JodOne {
pub category: String,
#[br(pad_after = 128)]
pub count: u32,
// always 0? is this part of the pad_after above?
pub _unknown2: u32,
#[br(count = count)]
pub entries: Vec<JodOneEntry>
}
@ -42,7 +51,6 @@ pub struct JodOne {
#[br(little, assert(id_again == id))]
#[binwrite(little)]
pub struct JodOneEntry {
pub _unknown1: u32,
pub id: u32,
pub size_cmp: u32,
pub is_compressed: u32,
@ -51,14 +59,14 @@ pub struct JodOneEntry {
#[br(count = size_cmp)]
#[binwrite(preprocessor(|x: &FilePtr<u32, Vec<u8>>| x.ptr))]
pub data: FilePtr<u32, Vec<u8>>,
#[br(pad_size_to = 188, map = string_binread_helper)]
#[binwrite(preprocessor(string_binwrite_helper(188)))]
#[br(pad_size_to = 192, map = string_binread_helper)]
#[binwrite(preprocessor(string_binwrite_helper(192)))]
pub name: String,
}
impl std::fmt::Debug for JodOne {
fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result {
write!(f, "JodOne{{_unknown1: 0x{:x}, category: {}, count: {}, ..}}", self._unknown1, self.category, self.count)
write!(f, "JodOne{{_unknown1: 0x{:x}, _unknown2: 0x{:x}, category: {}, count: {}, ..}}", self._unknown1, self._unknown2, self.category, self.count)
}
}
@ -66,8 +74,8 @@ impl std::fmt::Debug for JodOneEntry {
fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result {
write!(
f,
"JodOneEntry{{_unknown1: 0x{:x}, id: {}, is_compressed: {}, name: {:?}, size_cmp: {}, size_dec: {}, ..}}",
self._unknown1, self.id, self.is_compressed != 0, self.name.to_string(), self.size_cmp, self.size_dec,
"JodOneEntry{{id: {}, is_compressed: {}, name: {:?}, size_cmp: {}, size_dec: {}, ..}}",
self.id, self.is_compressed != 0, self.name.to_string(), self.size_cmp, self.size_dec,
)
}
}
@ -78,7 +86,6 @@ impl JodOne {
for (id, (path, data)) in inputs.enumerate() {
entries.push(JodOneEntry {
_unknown1: 0,
id: id as u32,
size_cmp: data.len() as u32,
is_compressed: 0,
@ -92,6 +99,7 @@ impl JodOne {
_unknown1: 0xCC,
category: category.unwrap_or("Default").to_string(),
count: 0,
_unknown2: 0x20,
entries: vec![]
}
}
@ -100,7 +108,7 @@ impl JodOne {
self.entries.into_iter().map(|entry| {
debug!("{:?}", entry);
let key = PathBuf::from(entry.name.replace('\\', std::path::MAIN_SEPARATOR.encode_utf8(&mut [0u8; 4])));
if entry.size_dec == 0 {
if entry.is_compressed == 0 || entry.size_dec == 0 {
(key, entry.data.into_inner())
} else {
let dec_buf = prs::Decompressor::new(entry.data.into_inner(), Some(entry.size_dec as usize)).decompress();