XPlor/definitions/thqa/str.xscript

171 lines
5.0 KiB
Plaintext
Raw Permalink Normal View History

// 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 ui("String Table", root) byteorder LE
{
criteria {
require ascii(bytesat(0, 4)) == "bats";
}
magic = ascii(read(4)) ui("Magic");
u32 language_code ui("Language Code");
u32 entry_count ui("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("String Marker");
u32 string_data_size ui("String Data Size");
total_strings = entry_count ui("Total Strings");
file_size = size() ui("File Size");
}
// SpongeBob/Xbox-style string table (16-byte entries, UTF-16LE)
type thqa_str_le ui("String Table", root) byteorder LE
{
criteria {
require ascii(bytesat(0, 4)) == "bats";
}
magic = ascii(read(4)) ui("Magic");
u32 version ui("Version");
u32 entry_count ui("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("String Marker");
u32 string_data_size ui("String Data Size");
total_strings = entry_count ui("Total Strings");
file_size = size() ui("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 ui("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 ui("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"));
}