XPlor/definitions/wii/bnr.xscript

348 lines
8.8 KiB
Plaintext
Raw Normal View History

// Wii Opening.bnr Banner File Format
type wii_bnr [root, display="Wii Banner"] byteorder BE
{
criteria {
require _ext == "bnr" || _ext == "app";
require ascii(bytesat(0x40, 4)) == "IMET" || ascii(bytesat(0x80, 4)) == "IMET";
}
disc_imet = ascii(bytesat(0x40, 4));
nand_imet = ascii(bytesat(0x80, 4));
if (disc_imet == "IMET") {
format_type = "Disc";
ui("format_type", "Format");
padding_size = 0x40;
} else {
format_type = "NAND";
ui("format_type", "Format");
padding_size = 0x80;
}
_padding = read(padding_size);
imet_magic = ascii(read(4));
ui("imet_magic", "Magic");
u32 hash_size;
ui("hash_size", "Hash Size");
u32 imet_version;
ui("imet_version", "Version");
u32 icon_size;
ui("icon_size", "icon.bin Size");
u32 banner_size;
ui("banner_size", "banner.bin Size");
u32 sound_size;
ui("sound_size", "sound.bin Size");
u32 flag1;
ui("flag1", "Flag");
skip_tree("localized_names");
lang_idx = 0;
repeat(10) {
name_data = read(84);
ctx_set("_bnr_lang_idx", lang_idx);
name_child = name_data |> parse wii_bnr_name_row;
push("localized_names", name_child);
lang_idx = lang_idx + 1;
}
ui_table("localized_names", "localized_names", "Language,ChannelName");
_zeroes = read(588);
md5_hash = hex(read(16));
ui("md5_hash", "MD5 Hash");
u8_archive_offset = pos();
ui("u8_archive_offset", "U8 Archive Offset");
remaining = size() - pos();
if (remaining > 32) {
u8_magic_check = u32at(pos());
if (u8_magic_check == 0x55AA382D) {
archive_type = "U8 Archive";
ui("archive_type", "Archive Type");
u8_magic = hex(read(4));
ui("u8_magic", "U8 Magic");
u32 root_node_offset;
ui("root_node_offset", "Root Node Offset");
u32 header_size;
ui("header_size", "Header Size");
u32 data_offset;
ui("data_offset", "Data Offset");
_u8_reserved = read(16);
seek(u8_archive_offset + root_node_offset + 8);
u32 total_nodes;
ui("total_nodes", "Total Nodes");
seen_dirs = ",";
seen_offsets = ",";
seek(u8_archive_offset + root_node_offset);
node_idx = 0;
repeat(total_nodes) {
u8 node_type;
u8 name_off_hi;
u16 name_off_lo;
name_offset = (name_off_hi * 65536) + name_off_lo;
u32 node_data_offset;
u32 node_size;
string_table_offset = u8_archive_offset + root_node_offset + (total_nodes * 12);
saved_pos = pos();
seek(string_table_offset + name_offset);
node_name = cstring();
seek(saved_pos);
if (node_idx > 0) {
offset_key = "," + node_data_offset + ",";
if (node_type == 0 && node_size > 0 && node_name != "") {
is_dupe = contains(seen_offsets, offset_key);
if (is_dupe == 0) {
seen_offsets = seen_offsets + node_data_offset + ",";
file_pos = u8_archive_offset + node_data_offset;
if (file_pos + node_size <= size()) {
ctx_set("_bnr_node_name", node_name);
ctx_set("_bnr_node_size", node_size);
ctx_set("_bnr_file_offset", file_pos);
seek(file_pos);
file_data = read(node_size);
file_child = file_data |> parse wii_bnr_u8_file;
push("files", file_child);
}
}
} else if (node_type == 1 && node_name != "") {
dir_key = "," + node_name + ",";
is_dir_dupe = contains(seen_dirs, dir_key);
if (is_dir_dupe == 0) {
seen_dirs = seen_dirs + node_name + ",";
ctx_set("_bnr_node_name", node_name);
ctx_set("_bnr_node_size", node_size);
dummy = bytesat(0, 1);
dir_child = dummy |> parse wii_bnr_u8_directory;
push("directories", dir_child);
}
}
}
seek(saved_pos);
node_idx = node_idx + 1;
}
} else {
archive_type = "Unknown";
ui("archive_type", "Archive Type");
set_preview("data", read(remaining));
set_viewer("hex");
}
}
file_size = size();
ui("file_size", "Total File Size");
}
type wii_bnr_name_row [display="Name"] byteorder BE
{
set_hidden();
lang_idx = ctx_get("_bnr_lang_idx");
if (lang_idx == 0) { language = "Japanese"; }
else if (lang_idx == 1) { language = "English"; }
else if (lang_idx == 2) { language = "German"; }
else if (lang_idx == 3) { language = "French"; }
else if (lang_idx == 4) { language = "Spanish"; }
else if (lang_idx == 5) { language = "Italian"; }
else if (lang_idx == 6) { language = "Dutch"; }
else if (lang_idx == 7) { language = "Chinese (Simplified)"; }
else if (lang_idx == 8) { language = "Chinese (Traditional)"; }
else if (lang_idx == 9) { language = "Korean"; }
else { language = "Unknown"; }
channel_name = wstring_be();
Language = language;
ChannelName = channel_name;
}
type wii_bnr_u8_directory [display="Directory"] byteorder BE
{
node_name = ctx_get("_bnr_node_name");
node_size = ctx_get("_bnr_node_size");
set_name(node_name);
name = node_name;
ui("name", "Name");
next_sibling = node_size;
ui("next_sibling", "Next Sibling Index");
}
type wii_bnr_u8_file [display="File"] byteorder BE
{
node_name = ctx_get("_bnr_node_name");
set_name(node_name);
file_size = size();
ui("file_size", "Size");
if (size() >= 32) {
magic_check = ascii(bytesat(0, 4));
if (magic_check == "IMD5") {
imd5_magic = ascii(read(4));
ui("imd5_magic", "Magic");
u32 payload_size;
ui("payload_size", "Payload Size");
_imd5_zeroes = read(8);
imd5_md5 = hex(read(16));
ui("imd5_md5", "MD5 Hash");
if (pos() + 4 <= size()) {
inner_magic = ascii(bytesat(pos(), 4));
if (inner_magic == "LZ77") {
compression = "LZ77";
ui("compression", "Compression");
lz77_magic = ascii(read(4));
ui("lz77_magic", "LZ77 Magic");
u32 decompressed_size;
ui("decompressed_size", "Decompressed Size");
set_preview(node_name, read(size() - pos()));
set_viewer("hex");
} else if (inner_magic == "RIFF") {
// WAV audio inside IMD5 container (sound.bin)
compression = "None (WAV)";
ui("compression", "Compression");
wav_data = read(size() - pos());
wav_size = len(wav_data);
ui("wav_size", "WAV Size");
wav_name = "sound.wav";
if (ends_with(node_name, ".bin")) {
wav_name = substr(node_name, 0, len(node_name) - 4) + ".wav";
}
set_preview(wav_name, wav_data);
set_viewer("audio");
} else {
compression = "None";
ui("compression", "Compression");
set_preview(node_name, read(size() - pos()));
set_viewer("hex");
}
}
} else if (magic_check == "BNS ") {
parse_here("wii_bns");
} else {
seek(0);
set_preview(node_name, read(size()));
set_viewer("hex");
}
} else {
set_preview(node_name, read(size()));
set_viewer("hex");
}
}
type wii_bns [display="BNS Audio"] byteorder BE
{
magic = ascii(read(4));
ui("magic", "Magic");
u32 endian_check;
ui("endian_check", "Endian Check");
u32 bns_file_size;
ui("bns_file_size", "File Size");
u16 header_size;
ui("header_size", "Header Size");
u16 chunk_count;
ui("chunk_count", "Chunk Count");
chunk_idx = 0;
repeat(chunk_count) {
u32 chunk_offset;
ui("chunk_offset", "Chunk Offset");
u32 chunk_size;
ui("chunk_size", "Chunk Size");
ctx_set("_bns_chunk_" + chunk_idx + "_offset", chunk_offset);
ctx_set("_bns_chunk_" + chunk_idx + "_size", chunk_size);
chunk_idx = chunk_idx + 1;
}
total_size = size();
ui("total_size", "Total Size");
if (pos() < size()) { set_preview("audio.bns", read(size() - pos())); set_viewer("audio"); }
}
type wii_imd5 [display="IMD5 Container"] byteorder BE
{
magic = ascii(read(4));
ui("magic", "Magic");
u32 payload_size;
ui("payload_size", "Payload Size");
_zeroes = read(8);
md5_hash = hex(read(16));
ui("md5_hash", "MD5 Hash");
if (pos() + 4 <= size()) {
inner_magic = ascii(bytesat(pos(), 4));
if (inner_magic == "LZ77") {
compression = "LZ77";
ui("compression", "Compression");
lz77_magic = ascii(read(4));
ui("lz77_magic", "LZ77 Magic");
u32 decompressed_size;
ui("decompressed_size", "Decompressed Size");
set_preview("imd5_data.bin", read(size() - pos()));
set_viewer("hex");
} else {
compression = "None";
ui("compression", "Compression");
set_preview("imd5_data.bin", read(size() - pos()));
set_viewer("hex");
}
}
imd5_file_size = size();
ui("imd5_file_size", "Total File Size");
}