218 lines
4.8 KiB
Plaintext
218 lines
4.8 KiB
Plaintext
|
|
// RAD Resource Descriptor Format - THQ Australia Engine
|
||
|
|
// Big-endian version (Xbox 360, Wii): "rad0" magic
|
||
|
|
// Little-endian version (Original Xbox): "0dar" magic
|
||
|
|
|
||
|
|
// Big-endian RAD (Xbox 360, Wii)
|
||
|
|
type thqa_rad [root, display="THQA RAD Resource"] byteorder BE
|
||
|
|
{
|
||
|
|
criteria {
|
||
|
|
require ascii(bytesat(0, 4)) == "rad0";
|
||
|
|
}
|
||
|
|
|
||
|
|
// Header (24 bytes)
|
||
|
|
magic = ascii(read(4));
|
||
|
|
|
||
|
|
ui("magic", "Magic");
|
||
|
|
u32 flags;
|
||
|
|
|
||
|
|
ui("flags", "Flags");
|
||
|
|
u32 data_size;
|
||
|
|
|
||
|
|
ui("data_size", "Data Section Size");
|
||
|
|
u32 header_size;
|
||
|
|
|
||
|
|
ui("header_size", "Header Size");
|
||
|
|
u32 section_info_offset;
|
||
|
|
|
||
|
|
ui("section_info_offset", "Section Info Offset");
|
||
|
|
u32 ptch_section_offset;
|
||
|
|
|
||
|
|
ui("ptch_section_offset", "Ptch Section Offset");
|
||
|
|
|
||
|
|
// Read null-terminated filename
|
||
|
|
filename = cstring();
|
||
|
|
|
||
|
|
ui("filename", "Filename");
|
||
|
|
set_name(filename);
|
||
|
|
|
||
|
|
// Read null-terminated section name
|
||
|
|
section_name = cstring();
|
||
|
|
|
||
|
|
ui("section_name", "Section Name");
|
||
|
|
|
||
|
|
// Extract embedded data section if present
|
||
|
|
if (data_size > 0 && header_size < section_info_offset) {
|
||
|
|
seek(header_size);
|
||
|
|
|
||
|
|
data_magic = ascii(bytesat(header_size, 4));
|
||
|
|
|
||
|
|
if (data_magic == "g4rc") {
|
||
|
|
data_block = read(data_size);
|
||
|
|
ctx_set("_thqa_rad_data_name", filename + " [Data]");
|
||
|
|
data_child = data_block |> parse thqa_rad_g4rc_data;
|
||
|
|
push("resources", data_child);
|
||
|
|
} else if (data_magic == "dsrc") {
|
||
|
|
data_block = read(data_size);
|
||
|
|
ctx_set("_thqa_rad_data_name", filename + " [DSRC]");
|
||
|
|
data_child = data_block |> parse thqa_rad_dsrc_data;
|
||
|
|
push("resources", data_child);
|
||
|
|
} else {
|
||
|
|
data_block = read(data_size);
|
||
|
|
ctx_set("_thqa_rad_data_name", filename + " [Raw Data]");
|
||
|
|
data_child = data_block |> parse thqa_rad_raw_data;
|
||
|
|
push("resources", data_child);
|
||
|
|
}
|
||
|
|
}
|
||
|
|
|
||
|
|
// Seek to section info block
|
||
|
|
seek(section_info_offset);
|
||
|
|
u32 info_flags;
|
||
|
|
|
||
|
|
ui("info_flags", "Info Flags");
|
||
|
|
u32 info_reserved1;
|
||
|
|
|
||
|
|
ui("info_reserved1", "Info Reserved 1");
|
||
|
|
u32 info_reserved2;
|
||
|
|
|
||
|
|
ui("info_reserved2", "Info Reserved 2");
|
||
|
|
u32 info_count1;
|
||
|
|
|
||
|
|
ui("info_count1", "Info Count 1");
|
||
|
|
u32 info_count2;
|
||
|
|
|
||
|
|
ui("info_count2", "Info Count 2");
|
||
|
|
u32 info_data_size;
|
||
|
|
|
||
|
|
ui("info_data_size", "Info Data Size");
|
||
|
|
u32 info_total_size;
|
||
|
|
|
||
|
|
ui("info_total_size", "Info Total Size");
|
||
|
|
|
||
|
|
// Seek to ptch section
|
||
|
|
seek(ptch_section_offset);
|
||
|
|
ptch_marker = ascii(read(4));
|
||
|
|
|
||
|
|
ui("ptch_marker", "Ptch Marker");
|
||
|
|
u32 ptch_reserved1;
|
||
|
|
|
||
|
|
ui("ptch_reserved1", "Ptch Reserved 1");
|
||
|
|
u32 ptch_reserved2;
|
||
|
|
|
||
|
|
ui("ptch_reserved2", "Ptch Reserved 2");
|
||
|
|
u32 ptch_offset_count;
|
||
|
|
|
||
|
|
ui("ptch_offset_count", "Ptch Offset Count");
|
||
|
|
|
||
|
|
if (ptch_offset_count > 0 && ptch_offset_count < 10000) {
|
||
|
|
repeat(ptch_offset_count) {
|
||
|
|
u32 _offset;
|
||
|
|
}
|
||
|
|
}
|
||
|
|
|
||
|
|
// Look for expl/done sections
|
||
|
|
if (pos() + 4 <= size()) {
|
||
|
|
next_marker = ascii(read(4));
|
||
|
|
if (next_marker == "expl") {
|
||
|
|
expl_marker = next_marker;
|
||
|
|
|
||
|
|
ui("expl_marker", "Expl Marker");
|
||
|
|
u32 expl_reserved1;
|
||
|
|
|
||
|
|
ui("expl_reserved1", "Expl Reserved 1");
|
||
|
|
u32 expl_flags;
|
||
|
|
|
||
|
|
ui("expl_flags", "Expl Flags");
|
||
|
|
} else if (next_marker == "done") {
|
||
|
|
done_marker = next_marker;
|
||
|
|
|
||
|
|
ui("done_marker", "Done Marker");
|
||
|
|
}
|
||
|
|
}
|
||
|
|
|
||
|
|
file_size_total = size();
|
||
|
|
|
||
|
|
|
||
|
|
ui("file_size_total", "Total File Size");
|
||
|
|
}
|
||
|
|
|
||
|
|
// Little-endian RAD (Original Xbox)
|
||
|
|
type thqa_rad_le [root, display="THQA RAD Resource"] byteorder LE
|
||
|
|
{
|
||
|
|
criteria {
|
||
|
|
require ascii(bytesat(0, 4)) == "0dar";
|
||
|
|
}
|
||
|
|
|
||
|
|
magic = ascii(read(4));
|
||
|
|
|
||
|
|
|
||
|
|
ui("magic", "Magic");
|
||
|
|
u32 flags;
|
||
|
|
|
||
|
|
ui("flags", "Flags");
|
||
|
|
u32 data_size;
|
||
|
|
|
||
|
|
ui("data_size", "Data Size");
|
||
|
|
u32 header_size;
|
||
|
|
|
||
|
|
ui("header_size", "Header Size");
|
||
|
|
u32 strings_offset;
|
||
|
|
|
||
|
|
ui("strings_offset", "Strings Offset");
|
||
|
|
u32 strings_size;
|
||
|
|
|
||
|
|
ui("strings_size", "Strings Size");
|
||
|
|
|
||
|
|
// Read resource name
|
||
|
|
if (strings_offset > 0 && strings_offset < size()) {
|
||
|
|
seek(strings_offset);
|
||
|
|
resource_name = cstring();
|
||
|
|
|
||
|
|
ui("resource_name", "Resource Name");
|
||
|
|
set_name(resource_name);
|
||
|
|
}
|
||
|
|
|
||
|
|
// Look for patch blocks
|
||
|
|
seek(header_size);
|
||
|
|
if (pos() + 4 <= size()) {
|
||
|
|
block_magic = ascii(bytesat(pos(), 4));
|
||
|
|
if (block_magic == "hctp") {
|
||
|
|
patch_magic = ascii(read(4));
|
||
|
|
|
||
|
|
ui("patch_magic", "Patch Magic");
|
||
|
|
}
|
||
|
|
}
|
||
|
|
|
||
|
|
file_size = size();
|
||
|
|
|
||
|
|
|
||
|
|
ui("file_size", "Total File Size");
|
||
|
|
}
|
||
|
|
|
||
|
|
// Helper types for RAD data blocks
|
||
|
|
type thqa_rad_g4rc_data [display="RAD G4RC Data"] byteorder BE
|
||
|
|
{
|
||
|
|
set_name(ctx_get("_thqa_rad_data_name"));
|
||
|
|
data_size = size();
|
||
|
|
|
||
|
|
ui("data_size", "Size");
|
||
|
|
data = read(size());
|
||
|
|
}
|
||
|
|
|
||
|
|
type thqa_rad_dsrc_data [display="RAD DSRC Data"] byteorder BE
|
||
|
|
{
|
||
|
|
set_name(ctx_get("_thqa_rad_data_name"));
|
||
|
|
data_size = size();
|
||
|
|
|
||
|
|
ui("data_size", "Size");
|
||
|
|
data = read(size());
|
||
|
|
}
|
||
|
|
|
||
|
|
type thqa_rad_raw_data [display="RAD Raw Data"] byteorder BE
|
||
|
|
{
|
||
|
|
set_name(ctx_get("_thqa_rad_data_name"));
|
||
|
|
data_size = size();
|
||
|
|
|
||
|
|
ui("data_size", "Size");
|
||
|
|
data = read(size());
|
||
|
|
}
|