XPlor/definitions/volition/audio.xscript
njohnson 908100f487 Enhance Volition format definitions for Saints Row series
Major improvements to VPP, PEG, and ASM parsers:

vpp.xscript:
- Support all VPP versions (4-10) for Saints Row 1-4 and Red Faction
- Add container type detection (str2, packfile, etc.)
- Improved compression handling (zlib, LZO, auto-detection)
- Better recursive parsing of nested archives

peg.xscript:
- Full PEG texture container parsing
- Support for multiple texture formats (DXT1, DXT3, DXT5, etc.)
- Xbox 360 and PC format variants

asm.xscript:
- Animation state machine container parsing

New format definitions:
- anim.xscript: Animation data
- audio.xscript: Audio containers (bank files)
- mesh.xscript: 3D mesh geometry
- morph.xscript: Morph targets
- rig.xscript: Skeletal rigs
- sim.xscript: Simulation data
- zone.xscript: Level zone data

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-01-12 20:53:59 -05:00

87 lines
2.3 KiB
Plaintext

// Wwise Audio Bank Format (.bnk_pc)
// Used by: Saints Row 3/4, many Wwise-based games
// Section-based: BKHD (header), DIDX (index), DATA (audio), HIRC (hierarchy)
type volition_bnk ui("Wwise Audio Bank", root) byteorder LE
{
criteria {
require _ext == "bnk_pc" || _ext == "bnk_xbox2" || _ext == "bnk_ps3";
// Check for BKHD magic
require ascii(bytesat(0, 4)) == "BKHD";
}
is_xbox = ends_with(_ext, "xbox2");
is_ps3 = ends_with(_ext, "ps3");
if (is_xbox || is_ps3) {
set_name("Audio Bank (Console)");
parse_here("volition_bnk_be");
} else {
set_name("Audio Bank (PC)");
parse_here("volition_bnk_impl");
}
}
type volition_bnk_be ui("Audio Bank") byteorder BE
{
parse_here("volition_bnk_impl");
}
type volition_bnk_impl ui("Audio Bank")
{
wem_count = 0;
data_size = 0;
hirc_objects = 0;
// Parse sections until EOF
while (pos() < size() - 8) {
section_magic = ascii(read(4));
u32 section_size;
if (section_magic == "BKHD") {
u32 wwise_version ui("Wwise Version");
u32 bank_id ui("Bank ID");
// Skip rest of BKHD section
remaining = section_size - 8;
if (remaining > 0) { skip(remaining); }
} else if (section_magic == "DIDX") {
// Data index - count WEM entries (12 bytes each)
wem_count = section_size / 12;
skip(section_size);
} else if (section_magic == "DATA") {
data_size = section_size;
skip(section_size);
} else if (section_magic == "HIRC") {
u32 hirc_count;
hirc_objects = hirc_count;
skip(section_size - 4);
} else if (section_magic == "STID") {
u32 stid_type;
u32 string_count ui("String Count");
skip(section_size - 8);
} else {
// Unknown section - skip
skip(section_size);
}
}
embedded_wem = wem_count ui("Embedded WEM Files");
audio_objects = hirc_objects ui("Audio Objects");
audio_data_size = data_size ui("Audio Data Size");
total_size = size() ui("File Size");
}
// Nested type for VPP
type volition_bnk_nested ui("Audio Bank") byteorder LE
{
file_name = ctx_get("_vpp_file_name");
set_name(file_name);
is_xbox = ctx_get("_vpp_is_xbox");
is_ps3 = ctx_get("_vpp_is_ps3");
if (is_xbox || is_ps3) {
parse_here("volition_bnk_be");
} else {
parse_here("volition_bnk_impl");
}
}