XPlor/definitions/thqa/pak_xenon.xscript

65 lines
1.7 KiB
Plaintext
Raw Permalink Normal View History

// PAK Archive format - THQ Australia Engine (Xbox 360)
// Xbox 360 version uses version 2, big-endian, 24-byte entries
// Inherits byteorder from parent (thqa_pak)
type thqa_pak_xenon ui("THQA PAK (Xbox 360)")
{
// Header (24 bytes)
magic = ascii(read(4)) ui("Magic");
u32 version ui("Version");
u32 entry_table_offset ui("Entry Table Offset");
u32 metadata_size ui("Metadata Size");
u32 entry_table_size ui("Entry Table Size");
u32 entry_count ui("Entry Count");
// Calculate derived values
entry_size = entry_table_size / entry_count ui("Entry Size");
filename_table_offset = entry_table_offset + entry_table_size ui("Filename Table Offset");
// Seek to entry table and read entries
seek(entry_table_offset);
if (entry_count > 0 && entry_count < 10000) {
entry_idx = 0;
repeat(entry_count) {
// Read entry fields (24 bytes each)
u32 e_offset;
u32 e_decomp_size;
u32 e_comp_size;
u32 e_name_off;
u32 e_unknown;
e_compress = ascii(read(4));
saved_pos = pos();
// Get filename
seek(filename_table_offset + e_name_off);
e_name = cstring();
// Extract file data
seek(e_offset);
if (e_compress == "zlib") {
raw_data = read(e_comp_size);
file_data = raw_data |> zlib;
} else {
file_data = read(e_decomp_size);
}
// Export file
write_file(e_name, file_data);
// Pass filename to child via global
ctx_set("_thqa_pak_entry_name", e_name);
// Create child entry
child = file_data |> parse thqa_pak_entry_be;
push("entries", child);
seek(saved_pos);
entry_idx = entry_idx + 1;
}
}
file_size = size() ui("Total File Size");
}