193 lines
5.3 KiB
Plaintext
193 lines
5.3 KiB
Plaintext
|
|
// String Table format - THQ Australia Engine
|
||
|
|
// Magic: "bats"
|
||
|
|
// Avatar/Wii: 12-byte entries, ASCII strings
|
||
|
|
// SpongeBob/Xbox: 16-byte entries, UTF-16LE strings
|
||
|
|
|
||
|
|
// Avatar-style string table (12-byte entries, ASCII)
|
||
|
|
type thqa_str [root, display="String Table"] byteorder LE
|
||
|
|
{
|
||
|
|
criteria {
|
||
|
|
require ascii(bytesat(0, 4)) == "bats";
|
||
|
|
}
|
||
|
|
|
||
|
|
magic = ascii(read(4));
|
||
|
|
|
||
|
|
|
||
|
|
ui("magic", "Magic");
|
||
|
|
u32 language_code;
|
||
|
|
|
||
|
|
ui("language_code", "Language Code");
|
||
|
|
u32 entry_count;
|
||
|
|
|
||
|
|
ui("entry_count", "Entry Count");
|
||
|
|
|
||
|
|
// Entries are 12 bytes each
|
||
|
|
entries_end = 12 + (entry_count * 12);
|
||
|
|
string_data_start = entries_end + 8;
|
||
|
|
|
||
|
|
// First pass: collect all string offsets
|
||
|
|
idx = 0;
|
||
|
|
repeat(entry_count) {
|
||
|
|
u16 e_string_id;
|
||
|
|
u16 e_lang;
|
||
|
|
u32 e_string_offset;
|
||
|
|
u32 e_reference;
|
||
|
|
|
||
|
|
ctx_set("_thqa_str_entry_" + idx + "_id", e_string_id);
|
||
|
|
ctx_set("_thqa_str_entry_" + idx + "_lang", e_lang);
|
||
|
|
ctx_set("_thqa_str_entry_" + idx + "_offset", e_string_offset);
|
||
|
|
ctx_set("_thqa_str_entry_" + idx + "_ref", e_reference);
|
||
|
|
|
||
|
|
idx = idx + 1;
|
||
|
|
}
|
||
|
|
|
||
|
|
// Skip srts marker and size
|
||
|
|
skip(8);
|
||
|
|
|
||
|
|
// Second pass: read strings and create table rows
|
||
|
|
idx = 0;
|
||
|
|
repeat(entry_count) {
|
||
|
|
e_string_id = ctx_get("_thqa_str_entry_" + idx + "_id");
|
||
|
|
e_lang = ctx_get("_thqa_str_entry_" + idx + "_lang");
|
||
|
|
e_string_offset = ctx_get("_thqa_str_entry_" + idx + "_offset");
|
||
|
|
e_reference = ctx_get("_thqa_str_entry_" + idx + "_ref");
|
||
|
|
|
||
|
|
seek(string_data_start + e_string_offset);
|
||
|
|
str_value = cstring();
|
||
|
|
|
||
|
|
// Store values for child type
|
||
|
|
ctx_set("_thqa_str_value", str_value);
|
||
|
|
ctx_set("_thqa_str_id", e_string_id);
|
||
|
|
ctx_set("_thqa_str_lang", e_lang);
|
||
|
|
ctx_set("_thqa_str_ref", e_reference);
|
||
|
|
|
||
|
|
// Create row via child type (fields become table columns)
|
||
|
|
dummy_byte = bytesat(0, 1);
|
||
|
|
entry_child = dummy_byte |> parse thqa_str_row;
|
||
|
|
push("strings", entry_child);
|
||
|
|
|
||
|
|
idx = idx + 1;
|
||
|
|
}
|
||
|
|
|
||
|
|
// Table display with columns matching child type field names
|
||
|
|
// skip_tree() prevents tree children (table-only display)
|
||
|
|
skip_tree("strings");
|
||
|
|
ui_table("strings", "Strings", "ID,Lang,Ref,Value");
|
||
|
|
|
||
|
|
seek(entries_end);
|
||
|
|
srts_marker = ascii(read(4));
|
||
|
|
ui("srts_marker", "String Marker");
|
||
|
|
u32 string_data_size;
|
||
|
|
ui("string_data_size", "String Data Size");
|
||
|
|
|
||
|
|
total_strings = entry_count;
|
||
|
|
ui("total_strings", "Total Strings");
|
||
|
|
file_size = size();
|
||
|
|
ui("file_size", "File Size");
|
||
|
|
}
|
||
|
|
|
||
|
|
// SpongeBob/Xbox-style string table (16-byte entries, UTF-16LE)
|
||
|
|
type thqa_str_le [root, display="String Table"] byteorder LE
|
||
|
|
{
|
||
|
|
criteria {
|
||
|
|
require ascii(bytesat(0, 4)) == "bats";
|
||
|
|
}
|
||
|
|
|
||
|
|
magic = ascii(read(4));
|
||
|
|
|
||
|
|
|
||
|
|
ui("magic", "Magic");
|
||
|
|
u32 version;
|
||
|
|
|
||
|
|
ui("version", "Version");
|
||
|
|
u32 entry_count;
|
||
|
|
|
||
|
|
ui("entry_count", "Entry Count");
|
||
|
|
|
||
|
|
// Entries are 16 bytes each
|
||
|
|
entries_end = 12 + (entry_count * 16);
|
||
|
|
string_data_start = entries_end + 8;
|
||
|
|
|
||
|
|
// First pass: collect all entry data
|
||
|
|
idx = 0;
|
||
|
|
repeat(entry_count) {
|
||
|
|
u16 e_string_id;
|
||
|
|
u16 e_type;
|
||
|
|
u32 e_string_offset;
|
||
|
|
u32 e_unknown;
|
||
|
|
f32 e_float_val;
|
||
|
|
|
||
|
|
ctx_set("_thqa_str_le_" + idx + "_id", e_string_id);
|
||
|
|
ctx_set("_thqa_str_le_" + idx + "_type", e_type);
|
||
|
|
ctx_set("_thqa_str_le_" + idx + "_offset", e_string_offset);
|
||
|
|
ctx_set("_thqa_str_le_" + idx + "_float", e_float_val);
|
||
|
|
|
||
|
|
idx = idx + 1;
|
||
|
|
}
|
||
|
|
|
||
|
|
// Skip srts marker and size
|
||
|
|
skip(8);
|
||
|
|
|
||
|
|
// Second pass: read UTF-16LE strings and create table rows
|
||
|
|
idx = 0;
|
||
|
|
repeat(entry_count) {
|
||
|
|
e_string_id = ctx_get("_thqa_str_le_" + idx + "_id");
|
||
|
|
e_type = ctx_get("_thqa_str_le_" + idx + "_type");
|
||
|
|
e_string_offset = ctx_get("_thqa_str_le_" + idx + "_offset");
|
||
|
|
e_float_val = ctx_get("_thqa_str_le_" + idx + "_float");
|
||
|
|
|
||
|
|
seek(string_data_start + e_string_offset);
|
||
|
|
str_value = wstring();
|
||
|
|
|
||
|
|
// Store values for child type
|
||
|
|
ctx_set("_thqa_str_value", str_value);
|
||
|
|
ctx_set("_thqa_str_id", e_string_id);
|
||
|
|
ctx_set("_thqa_str_type", e_type);
|
||
|
|
|
||
|
|
// Create row via child type (fields become table columns)
|
||
|
|
dummy_byte = bytesat(0, 1);
|
||
|
|
entry_child = dummy_byte |> parse thqa_str_le_row;
|
||
|
|
push("strings", entry_child);
|
||
|
|
|
||
|
|
idx = idx + 1;
|
||
|
|
}
|
||
|
|
|
||
|
|
// Table display with columns matching child type field names
|
||
|
|
// skip_tree() prevents tree children (table-only display)
|
||
|
|
skip_tree("strings");
|
||
|
|
ui_table("strings", "Strings", "ID,Type,Value");
|
||
|
|
|
||
|
|
seek(entries_end);
|
||
|
|
srts_marker = ascii(read(4));
|
||
|
|
ui("srts_marker", "String Marker");
|
||
|
|
u32 string_data_size;
|
||
|
|
ui("string_data_size", "String Data Size");
|
||
|
|
|
||
|
|
total_strings = entry_count;
|
||
|
|
ui("total_strings", "Total Strings");
|
||
|
|
file_size = size();
|
||
|
|
ui("file_size", "File Size");
|
||
|
|
}
|
||
|
|
|
||
|
|
// Row type for Avatar string table - field names match column names
|
||
|
|
// set_hidden() prevents tree children while keeping table data
|
||
|
|
type thqa_str_row [display="String"] byteorder LE
|
||
|
|
{
|
||
|
|
set_hidden();
|
||
|
|
ID = ctx_get("_thqa_str_id");
|
||
|
|
Lang = ctx_get("_thqa_str_lang");
|
||
|
|
Ref = ctx_get("_thqa_str_ref");
|
||
|
|
// Replace Cyrillic button placeholders with readable Xbox button names
|
||
|
|
Value = replace_xbox_buttons(ctx_get("_thqa_str_value"));
|
||
|
|
}
|
||
|
|
|
||
|
|
// Row type for SpongeBob string table - field names match column names
|
||
|
|
type thqa_str_le_row [display="String"] byteorder LE
|
||
|
|
{
|
||
|
|
set_hidden();
|
||
|
|
ID = ctx_get("_thqa_str_id");
|
||
|
|
Type = ctx_get("_thqa_str_type");
|
||
|
|
// Replace Cyrillic button placeholders with readable Xbox button names
|
||
|
|
Value = replace_xbox_buttons(ctx_get("_thqa_str_value"));
|
||
|
|
}
|