diff --git a/crates/jmrenamer/src/main.rs b/crates/jmrenamer/src/main.rs index 603314f..861361a 100644 --- a/crates/jmrenamer/src/main.rs +++ b/crates/jmrenamer/src/main.rs @@ -50,12 +50,14 @@ fn hashed_dat_filename(filename: &str) -> String { fn main() -> io::Result<()> { - // A relatively simple idiot-check. + // A relatively simple idiot-check. Later on utilities might have a shared library + // of code which validates game root stuff and can open it up/etc. if !Path::new("DATA").is_dir() { println!("This program should be run in the root of an extracted copy."); std::process::exit(1); } + // Go through the clearname table and rename files in the DATA directory for clearname in FILENAME_TABLE.iter() { let dat_filename = hashed_dat_filename(clearname); let dat_src = format!("DATA/{}", dat_filename); diff --git a/hexpat/package.hexpat b/hexpat/package.hexpat index a8369dd..0a0f932 100644 --- a/hexpat/package.hexpat +++ b/hexpat/package.hexpat @@ -30,12 +30,9 @@ struct Lzss_Header { //} }; -// Data strutures actually part of the file: - -// "PGRP" entry. +// "PGRP" chunk. // // This marks the start of a "package group". -// Whatever that is. struct JMMT_PGRP { u32 magic; u32 groupNameCrc; // This is in the string table @@ -43,52 +40,55 @@ struct JMMT_PGRP { u32 pad; // seemingly always 0xCDCDCDCD }; -// "PFIL" entry. +// "PFIL" chunk. // -// This represents a file block, -// which can itself represent either a whole file (> 65535 bytes), -// or part of a file (which will need to be stiched together). +// This represents a file chunk, +// which can itself represent either a whole file (when it is > 65536 bytes), +// or part of a file (which will need to be stiched together from multiple chunks). struct JMMT_PFIL { u32 magic; - u32 unk[2]; // Don't know what these are? + u32 unk; // These two seem to stay the same for every PFIL + u32 unk2; // Sequence number of the chunk. // This repressents the order of each chunk, // presumably so order can just be whatever. // - // However the game seems to order chunks for files + // However the packaging tool seems to leave files // in order, and doesn't start/interleave other files - // in between. So this is a nice waste of 16 bits. - u16 chunkSequenceNumber; + // in between. This is definitely still useful, but + // not quite as much. + u16 chunkNumber; // Amount of chunks which need to be read - // from to read this file completely. + // from to complete this file. // // 1 means this file starts and ends on this chunk. u16 chunkAmount; // This is a CRC32 hash of the path of this file. // - // Hashed with jmmt::HashString() (in the jmmt_tools repo). + // Hashed with jmmt::HashString(). u32 filenameCrc; - u32 unk2[7]; // more unknown stuff I don't care/know about + u32 unk3[7]; // These stay the same per file chunk. Could be hashes // Uncompressed size of this file chunk. Has a maximum of 65535 bytes. u32 chunkSize; // Offset where this file chunk should start, // inside of a larger buffer. - u32 blockOffset; + u32 bufferOffset; - // ? - u32 unk3; + // Compressed size of the chunk. + u32 compressedSize; // Offset inside of the package file where // the compressed data blob starts. u32 dataOffset; + // Total file size. u32 fileSize; // TECH LZSS header. @@ -98,12 +98,10 @@ struct JMMT_PFIL { // Debug information. This doesn't print literally everything, // just the useful stuff to look at it. if(1) { - std::print(" Chunk seqNum: {}, Filename CRC: {:0x}, File Size: {}, Chunk Size: {}, Block Offset: {}, Data Offset: {}", chunkSequenceNumber, filenameCrc, fileSize, chunkSize, blockOffset, dataOffset); + std::print("Hash: {:0x}, Seqnum: {}, ZOff: {}, FileSize: {}, ChunkSize: {}(z {}), BufferOff: {},", + filenameCrc, chunkNumber, dataOffset, fileSize, + chunkSize, compressedSize, bufferOffset ); } - - //if(lzHeader.cByteId == 0x91) - // std::print("file has a valid lzss header"); - }; // This is a wrapper so we can easily do the chunk viewing in imhex. @@ -113,10 +111,10 @@ struct PFIL_WRAPPER { JMMT_PFIL pfilChunkZero; if(pfilChunkZero.chunkAmount != 1) { - std::print("This file has {} chunks", pfilChunkZero.chunkAmount); + //std::print("This file has {} chunks", pfilChunkZero.chunkAmount); JMMT_PFIL pfilChunkExtra[pfilChunkZero.chunkAmount - 1]; } else { - std::print("File ended with 1 chunk"); + //std::print("File ended with 1 chunk"); } }; @@ -126,6 +124,5 @@ struct PFIL_WRAPPER { // Group header. JMMT_PGRP grp @ 0xd1c30; -// This isn't right (as one PFIL chunk doesn't actually have to mean one file), -// but it works for testing and trying to understand the format. -PFIL_WRAPPER files[grp.nrfiles] @ $; \ No newline at end of file +// All pfil objects. The wrapper expands out other pfil chunks automatically. Pretty cool. +PFIL_WRAPPER files[grp.nrfiles] @ $;