XPlor/definitions/thqa/pak_xbox.xscript

64 lines
1.8 KiB
Plaintext
Raw Permalink Normal View History

// PAK Archive format - THQ Australia Engine (Original Xbox)
// Original Xbox uses little-endian with "kcap" magic, 12-byte entries
// Inherits byteorder from parent (thqa_pak_le)
type thqa_pak_xbox ui("THQA PAK (Xbox)")
{
// Header (24 bytes)
magic = ascii(read(4)) ui("Magic");
u32 version ui("Version");
u32 unknown_count ui("Unknown Count");
u32 file_size_header ui("File Size (Header)");
u32 filename_table_offset ui("Filename Table Offset");
u32 entry_count ui("Entry Count");
// Validate and process entries
if (entry_count > 0 && entry_count < 10000) {
// First pass: read all entries
idx = 0;
repeat(entry_count) {
u32 e_name_off;
u32 e_data_off;
u32 e_size;
ctx_set("_thqa_xbox_entry_" + idx + "_name_off", e_name_off);
ctx_set("_thqa_xbox_entry_" + idx + "_data_off", e_data_off);
ctx_set("_thqa_xbox_entry_" + idx + "_size", e_size);
idx = idx + 1;
}
// Second pass: process entries with filenames and data
idx = 0;
repeat(entry_count) {
e_name_off = ctx_get("_thqa_xbox_entry_" + idx + "_name_off");
e_data_off = ctx_get("_thqa_xbox_entry_" + idx + "_data_off");
e_size = ctx_get("_thqa_xbox_entry_" + idx + "_size");
// Get filename
seek(filename_table_offset + e_name_off);
e_name = cstring();
// Only process entries with data
if (e_size > 0 && e_data_off + e_size <= size()) {
seek(e_data_off);
file_data = read(e_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_le;
push("entries", child);
}
idx = idx + 1;
}
}
total_file_size = size() ui("Total File Size");
}