XPlor/definitions/thqa/pak_wii.xscript
njohnson f0030ea6f2 Add new format definitions for FMOD, THQ, Volition, and Wii
- FMOD: FSB audio bank format support
- THQ: PAK archives, G4RC textures, RAD video, STR strings, GML scripts
- Volition: VPP archives, PEG textures, ASM container format
- Wii: BNR banner format with metadata extraction

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-01-11 12:10:58 -05:00

78 lines
1.7 KiB
Plaintext

// PAK Archive format - THQ Australia Engine (Wii)
// Wii version uses version 1, big-endian, 16-byte entries
type thqa_pak_wii [display="THQA PAK (Wii)"] byteorder BE
{
// Header (24 bytes)
magic = ascii(read(4));
ui("magic", "Magic");
u32 version;
ui("version", "Version");
u32 entry_table_offset;
ui("entry_table_offset", "Entry Table Offset");
u32 metadata_size;
ui("metadata_size", "Metadata Size");
u32 entry_table_size;
ui("entry_table_size", "Entry Table Size");
u32 entry_count;
ui("entry_count", "Entry Count");
// Calculate derived values
entry_size = entry_table_size / entry_count;
ui("entry_size", "Entry Size");
filename_table_offset = entry_table_offset + entry_table_size;
ui("filename_table_offset", "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 (16 bytes each for Wii)
u32 e_offset;
u32 e_size;
u32 e_name_off;
u32 e_unknown;
saved_pos = pos();
// Get filename
seek(filename_table_offset + e_name_off);
e_name = cstring();
// Extract file data
if (e_size > 0 && e_offset + e_size <= size()) {
seek(e_offset);
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_be;
push("entries", child);
}
seek(saved_pos);
entry_idx = entry_idx + 1;
}
}
file_size = size();
ui("file_size", "Total File Size");
}