dcx: playing with tag()
This commit is contained in:
parent
72cc3fecb6
commit
5fcd484f86
|
@ -48,12 +48,18 @@ fn main() {
|
||||||
.arg(Arg::with_name("value")
|
.arg(Arg::with_name("value")
|
||||||
.takes_value(true)
|
.takes_value(true)
|
||||||
.required(true)))
|
.required(true)))
|
||||||
|
.subcommand(SubCommand::with_name("dcx")
|
||||||
|
.about("?TODO?")
|
||||||
|
.arg(Arg::with_name("file")
|
||||||
|
.takes_value(true)
|
||||||
|
.required(true)))
|
||||||
.get_matches();
|
.get_matches();
|
||||||
|
|
||||||
process::exit(match matches.subcommand() {
|
process::exit(match matches.subcommand() {
|
||||||
("bhd", Some(s)) => { cmd_bhd(s) }
|
("bhd", Some(s)) => { cmd_bhd(s) }
|
||||||
("bhds", Some(s)) => { cmd_bhds(s) }
|
("bhds", Some(s)) => { cmd_bhds(s) }
|
||||||
("hash", Some(s)) => { cmd_hash(s) }
|
("hash", Some(s)) => { cmd_hash(s) }
|
||||||
|
("dcx", Some(s)) => { cmd_dcx(s) }
|
||||||
_ => { 0 }
|
_ => { 0 }
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
@ -124,3 +130,11 @@ fn cmd_hash(args: &ArgMatches) -> i32 {
|
||||||
println!("{}", name_hashes::hash_as_string(name_hashes::hash(&value)));
|
println!("{}", name_hashes::hash_as_string(name_hashes::hash(&value)));
|
||||||
0
|
0
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fn cmd_dcx(args: &ArgMatches) -> i32 {
|
||||||
|
let file_path: &str = args.value_of("file").unwrap();
|
||||||
|
match unpackers::dcx::extract_dcx(file_path) {
|
||||||
|
Err(e) => { eprintln!("Failed to extract DCX: {:?}", e); return 1 }
|
||||||
|
_ => { 0 }
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
|
@ -1,11 +1,12 @@
|
||||||
pub mod name_hashes;
|
pub mod name_hashes;
|
||||||
pub mod parsers {
|
pub mod parsers {
|
||||||
pub mod bhd;
|
pub mod bhd;
|
||||||
|
pub mod dcx;
|
||||||
}
|
}
|
||||||
pub mod unpackers {
|
pub mod unpackers {
|
||||||
pub mod bhd;
|
pub mod bhd;
|
||||||
|
pub mod dcx;
|
||||||
}
|
}
|
||||||
pub mod utils {
|
pub mod utils {
|
||||||
pub mod fs;
|
pub mod fs;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -1,12 +1,12 @@
|
||||||
use nom::combinator::verify;
|
use nom::IResult;
|
||||||
|
use nom::bytes::complete::tag;
|
||||||
use nom::multi::count;
|
use nom::multi::count;
|
||||||
use nom::number::complete::*;
|
use nom::number::complete::*;
|
||||||
use nom::sequence::tuple;
|
use nom::sequence::tuple;
|
||||||
use nom::IResult;
|
|
||||||
|
|
||||||
#[derive(Debug)]
|
#[derive(Debug)]
|
||||||
pub struct BhdHeader {
|
pub struct BhdHeader {
|
||||||
pub magic: u32,
|
pub magic: Vec<u8>,
|
||||||
pub unk04: i8, // PC=0, PS3=-1
|
pub unk04: i8, // PC=0, PS3=-1
|
||||||
pub unk05: i8,
|
pub unk05: i8,
|
||||||
pub unk06: i8,
|
pub unk06: i8,
|
||||||
|
@ -21,7 +21,7 @@ const MAGIC: u32 = 0x35444842;
|
||||||
|
|
||||||
fn parse_header(i: &[u8]) -> IResult<&[u8], BhdHeader> {
|
fn parse_header(i: &[u8]) -> IResult<&[u8], BhdHeader> {
|
||||||
let (i, (magic, flags, unk08, file_len, num_buckets, ofs_buckets)) = tuple((
|
let (i, (magic, flags, unk08, file_len, num_buckets, ofs_buckets)) = tuple((
|
||||||
verify(le_u32, |m| *m == MAGIC),
|
tag(b"BHD5"),
|
||||||
count(le_i8, 4),
|
count(le_i8, 4),
|
||||||
le_u32,
|
le_u32,
|
||||||
le_u32,
|
le_u32,
|
||||||
|
@ -31,7 +31,7 @@ fn parse_header(i: &[u8]) -> IResult<&[u8], BhdHeader> {
|
||||||
Ok((
|
Ok((
|
||||||
i,
|
i,
|
||||||
BhdHeader {
|
BhdHeader {
|
||||||
magic,
|
magic: magic.to_vec(),
|
||||||
unk04: flags[0],
|
unk04: flags[0],
|
||||||
unk05: flags[1],
|
unk05: flags[1],
|
||||||
unk06: flags[2],
|
unk06: flags[2],
|
||||||
|
|
109
src/parsers/dcx.rs
Normal file
109
src/parsers/dcx.rs
Normal file
|
@ -0,0 +1,109 @@
|
||||||
|
//typedef struct {
|
||||||
|
// int unk00; Assert(unk00 == 0);
|
||||||
|
// int dataOffset;
|
||||||
|
// int dataLength;
|
||||||
|
// int unk0C; Assert(unk0C == 1);
|
||||||
|
//} Block <bgcolor=cLtGreen, optimize=false>;
|
||||||
|
//
|
||||||
|
//typedef struct {
|
||||||
|
// char dcx[4]; Assert(dcx == "DCX\0");
|
||||||
|
// int unk04; Assert(unk04 == 0x10000 || unk04 == 0x11000);
|
||||||
|
// int unk08; Assert(unk08 == 0x18);
|
||||||
|
// int unk0C; Assert(unk0C == 0x24);
|
||||||
|
// int unk10; Assert(unk10 == 0x24 || unk10 == 0x44);
|
||||||
|
// int unk14; // In EDGE, size from 0x20 to end of block headers
|
||||||
|
// char dcs[4]; Assert(dcs == "DCS\0");
|
||||||
|
// uint uncompressedSize <format=hex>;
|
||||||
|
// uint compressedSize <format=hex>;
|
||||||
|
// char dcp[4]; Assert(dcp == "DCP\0");
|
||||||
|
// char format[4]; Assert(format == "DFLT" || format == "EDGE" || format == "KRAK");
|
||||||
|
// int unk2C; Assert(unk2C == 0x20);
|
||||||
|
// byte unk30; Assert(unk30 == 6|| unk30 == 8 || unk30 == 9);
|
||||||
|
// byte unk31 <hidden=true>; Assert(unk31 == 0);
|
||||||
|
// byte unk32 <hidden=true>; Assert(unk32 == 0);
|
||||||
|
// byte unk33 <hidden=true>; Assert(unk33 == 0);
|
||||||
|
// int unk34; Assert(unk34 == 0 || unk34 == 0x10000); // Block size for EDGE?
|
||||||
|
// int unk38; Assert(unk38 == 0);
|
||||||
|
// int unk3C; Assert(unk3C == 0);
|
||||||
|
// int unk40;
|
||||||
|
// char dca[4]; Assert(dca == "DCA\0");
|
||||||
|
// int dcaSize; // From before "DCA" to dca end
|
||||||
|
//
|
||||||
|
// if (format == "EDGE") {
|
||||||
|
// char egdt[4]; Assert(egdt == "EgdT");
|
||||||
|
// int unk50; Assert(unk50 == 0x10100);
|
||||||
|
// int unk54; Assert(unk54 == 0x24);
|
||||||
|
// int unk58; Assert(unk58 == 0x10);
|
||||||
|
// int unk5C; Assert(unk5C == 0x10000);
|
||||||
|
// int lastBlockUncompressedSize;
|
||||||
|
// int egdtSize; // From before "EgdT" to dca end
|
||||||
|
// int blockCount;
|
||||||
|
// int unk6C; Assert(unk6C == 0x100000);
|
||||||
|
// Block blocks[blockCount];
|
||||||
|
// }
|
||||||
|
//} Header <bgcolor=cLtRed>;
|
||||||
|
|
||||||
|
use nom::IResult;
|
||||||
|
use nom::bytes::complete::tag;
|
||||||
|
use nom::multi::count;
|
||||||
|
use nom::number::complete::*;
|
||||||
|
use nom::sequence::tuple;
|
||||||
|
|
||||||
|
#[derive(Debug)]
|
||||||
|
pub struct DcxHeader {
|
||||||
|
pub magic: Vec<u8>,
|
||||||
|
pub unk04: u32,
|
||||||
|
pub ofs_dcs: u32,
|
||||||
|
pub ofs_dcp: u32,
|
||||||
|
pub unk10: u32,
|
||||||
|
pub unk14: u32,
|
||||||
|
}
|
||||||
|
|
||||||
|
const HEADER_MAGIC: u32 = 0x00504344;
|
||||||
|
|
||||||
|
fn parse_header(i: &[u8]) -> IResult<&[u8], DcxHeader> {
|
||||||
|
let (i, (magic, unk04, ofs_dcs, ofs_dcp, unk10, unk14)) = tuple((
|
||||||
|
tag(b"DCX\0"),
|
||||||
|
be_u32,
|
||||||
|
be_u32,
|
||||||
|
be_u32,
|
||||||
|
be_u32,
|
||||||
|
be_u32,
|
||||||
|
))(i)?;
|
||||||
|
Ok((i, DcxHeader { magic: magic.to_vec(), unk04, ofs_dcs, ofs_dcp, unk10, unk14 }))
|
||||||
|
}
|
||||||
|
|
||||||
|
#[derive(Debug)]
|
||||||
|
pub struct DcxSizes {
|
||||||
|
pub magic: u32,
|
||||||
|
pub uncompressed_size: u32,
|
||||||
|
pub compressed_size: u32,
|
||||||
|
}
|
||||||
|
|
||||||
|
#[allow(non_snake_case)]
|
||||||
|
#[derive(Debug)]
|
||||||
|
pub struct DcxParams {
|
||||||
|
pub magic: u32,
|
||||||
|
pub method: [u8; 4],
|
||||||
|
pub ofs_dca: u32,
|
||||||
|
pub unk0C: u32,
|
||||||
|
pub unk10: u32,
|
||||||
|
pub unk14: u32,
|
||||||
|
pub unk18: u32,
|
||||||
|
pub unk1C: u32,
|
||||||
|
}
|
||||||
|
|
||||||
|
#[derive(Debug)]
|
||||||
|
pub struct Dcx {
|
||||||
|
pub header: DcxHeader,
|
||||||
|
pub sizes: DcxSizes,
|
||||||
|
pub params: DcxParams,
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn parse(i: &[u8]) -> IResult<&[u8], u8> {
|
||||||
|
let (i, header) = parse_header(i).unwrap();
|
||||||
|
println!("{:?}", header);
|
||||||
|
Ok((i, 0))
|
||||||
|
|
||||||
|
//Ok((i, Dcx { header: None, sizes: None, params: None }))
|
||||||
|
}
|
13
src/unpackers/dcx.rs
Normal file
13
src/unpackers/dcx.rs
Normal file
|
@ -0,0 +1,13 @@
|
||||||
|
use std::fs;
|
||||||
|
use std::io::{self, Read};
|
||||||
|
|
||||||
|
use crate::parsers::dcx;
|
||||||
|
|
||||||
|
pub fn extract_dcx(dcx_path: &str) -> Result<(), io::Error> {
|
||||||
|
let mut dcx_file = fs::File::open(dcx_path)?;
|
||||||
|
let file_len = dcx_file.metadata()?.len() as usize;
|
||||||
|
let mut dcx_data = vec![0u8; file_len];
|
||||||
|
dcx_file.read_exact(&mut dcx_data)?;
|
||||||
|
dcx::parse(&dcx_data);
|
||||||
|
Ok(())
|
||||||
|
}
|
Reference in a new issue