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>
90 lines
2.6 KiB
Plaintext
90 lines
2.6 KiB
Plaintext
// Volition Animation Format (.anim_pc)
|
|
// Used by: Saints Row 3/4, Red Faction series
|
|
// Crunched animation with keyframe data
|
|
|
|
type volition_anim ui("Volition Animation", root) byteorder LE
|
|
{
|
|
criteria {
|
|
require _ext == "anim_pc" || _ext == "anim_xbox2" || _ext == "anim_ps3";
|
|
// Basic sanity: version byte should be reasonable (1-50)
|
|
ver = u8at(4);
|
|
require ver > 0 && ver < 50;
|
|
}
|
|
|
|
is_xbox = ends_with(_ext, "xbox2");
|
|
is_ps3 = ends_with(_ext, "ps3");
|
|
|
|
if (is_xbox || is_ps3) {
|
|
set_name("Animation (Console)");
|
|
parse_here("volition_anim_be");
|
|
} else {
|
|
set_name("Animation (PC)");
|
|
parse_here("volition_anim_impl");
|
|
}
|
|
}
|
|
|
|
type volition_anim_be ui("Animation") byteorder BE
|
|
{
|
|
parse_here("volition_anim_impl");
|
|
}
|
|
|
|
type volition_anim_impl ui("Animation")
|
|
{
|
|
i32 anim_id ui("Animation ID");
|
|
u8 version ui("Version");
|
|
u8 flags ui("Flags");
|
|
u16 end_frame ui("End Frame");
|
|
u8 ramp_in ui("Ramp In");
|
|
u8 ramp_out ui("Ramp Out");
|
|
u8 num_bones ui("Bone Count");
|
|
u8 num_rig_bones ui("Rig Bone Count");
|
|
|
|
// Total rotation quaternion
|
|
f32 rot_x ui("Total Rot X");
|
|
f32 rot_y ui("Total Rot Y");
|
|
f32 rot_z ui("Total Rot Z");
|
|
f32 rot_w ui("Total Rot W");
|
|
|
|
// Total translation
|
|
f32 trans_x ui("Total Trans X");
|
|
f32 trans_y ui("Total Trans Y");
|
|
f32 trans_z ui("Total Trans Z");
|
|
|
|
// Decode flags
|
|
has_packed = (flags & 0x01) != 0;
|
|
has_time_shorts = (flags & 0x02) != 0;
|
|
has_delta_times = (flags & 0x04) != 0;
|
|
has_motion = (flags & 0x08) != 0;
|
|
has_morph = (flags & 0x10) != 0;
|
|
has_long_trans = (flags & 0x20) != 0;
|
|
has_weight_keys = (flags & 0x40) != 0;
|
|
has_short_counts = (flags & 0x80) != 0;
|
|
|
|
flags_desc = "";
|
|
if (has_packed) { flags_desc = flags_desc + "PACKED "; }
|
|
if (has_time_shorts) { flags_desc = flags_desc + "TIME_SHORTS "; }
|
|
if (has_delta_times) { flags_desc = flags_desc + "DELTA_TIMES "; }
|
|
if (has_motion) { flags_desc = flags_desc + "MOTION "; }
|
|
if (has_morph) { flags_desc = flags_desc + "MORPH "; }
|
|
if (has_long_trans) { flags_desc = flags_desc + "LONG_TRANS "; }
|
|
if (has_weight_keys) { flags_desc = flags_desc + "WEIGHT_KEYS "; }
|
|
if (has_short_counts) { flags_desc = flags_desc + "SHORT_COUNTS "; }
|
|
flag_display = trim(flags_desc) ui("Flag Names");
|
|
|
|
file_size = size() ui("File Size");
|
|
}
|
|
|
|
// Nested type for VPP
|
|
type volition_anim_nested ui("Animation") 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_anim_be");
|
|
} else {
|
|
parse_here("volition_anim_impl");
|
|
}
|
|
}
|