// PAK Archive format - THQ Australia Engine (Original Xbox) // Original Xbox uses little-endian with "kcap" magic, 12-byte entries type thqa_pak_xbox [display="THQA PAK (Xbox)"] byteorder LE { // Header (24 bytes) magic = ascii(read(4)); ui("magic", "Magic"); u32 version; ui("version", "Version"); u32 unknown_count; ui("unknown_count", "Unknown Count"); u32 file_size_header; ui("file_size_header", "File Size (Header)"); u32 filename_table_offset; ui("filename_table_offset", "Filename Table Offset"); u32 entry_count; ui("entry_count", "Entry Count"); // Validate and process entries if (entry_count > 0 && entry_count < 10000) { // First pass: read all entries idx = 0; repeat(entry_count) { u32 e_name_off; u32 e_data_off; u32 e_size; ctx_set("_thqa_xbox_entry_" + idx + "_name_off", e_name_off); ctx_set("_thqa_xbox_entry_" + idx + "_data_off", e_data_off); ctx_set("_thqa_xbox_entry_" + idx + "_size", e_size); idx = idx + 1; } // Second pass: process entries with filenames and data idx = 0; repeat(entry_count) { e_name_off = ctx_get("_thqa_xbox_entry_" + idx + "_name_off"); e_data_off = ctx_get("_thqa_xbox_entry_" + idx + "_data_off"); e_size = ctx_get("_thqa_xbox_entry_" + idx + "_size"); // Get filename seek(filename_table_offset + e_name_off); e_name = cstring(); // Only process entries with data if (e_size > 0 && e_data_off + e_size <= size()) { seek(e_data_off); file_data = read(e_size); // Export file write_file(e_name, file_data); // Pass filename to child via global ctx_set("_thqa_pak_entry_name", e_name); // Create child entry child = file_data |> parse thqa_pak_entry_le; push("entries", child); } idx = idx + 1; } } total_file_size = size(); ui("total_file_size", "Total File Size"); }