// 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()); }