type material [display="Material"] { // Material struct - PC COD4 format (80 bytes header) // Verified against old XPlor C++ code and COD4x_Server source // ============ MaterialInfo (24 bytes) ============ // Name pointer (4 bytes) i32 material_name_ptr [ui, readonly, display="Material Name Ptr"]; // Info bytes (4 bytes): game_flags, sort_key, atlas counts u8 game_flags [ui, readonly, display="Game Flags"]; u8 sort_key [ui, readonly, display="Sort Key"]; u8 texture_atlas_row_count [ui, readonly, display="Texture Atlas Row Count"]; u8 texture_atlas_column_count [ui, readonly, display="Texture Atlas Column Count"]; // Draw surface - 8 bytes (uint64_t packed bitfield) draw_surf = read(8) [ui, readonly, display="Draw Surf"]; // Surface type bits (4 bytes) u32 surface_type_bits [ui, readonly, display="Surface Type Bits"]; // Hash index + padding (4 bytes) u16 hash_index [ui, readonly, display="Hash Index"]; skip(2); // ============ Material body (56 bytes) ============ // State bits entry array - 34 bytes (TECHNIQUE_COUNT = 34) state_bits_entry = read(34) [ui, readonly, display="State Bits Entry"]; // Counts (6 bytes: 5 fields + 1 padding) u8 texture_count [ui, readonly, display="Texture Count"]; u8 constant_count [ui, readonly, display="Constant Count"]; u8 state_bits_count [ui, readonly, display="State Bits Count"]; u8 state_flags [ui, readonly, display="State Flags"]; u8 camera_region [ui, readonly, display="Camera Region"]; skip(1); // Pointers (16 bytes) i32 technique_set_ptr [ui, readonly, display="Technique Set Ptr"]; i32 texture_table_ptr [ui, readonly, display="Texture Table Ptr"]; i32 constant_table_ptr [ui, readonly, display="Constant Table Ptr"]; i32 state_bits_table_ptr [ui, readonly, display="State Bits Table Ptr"]; // ============ Inline data (after header) ============ // Material name string (parse if inline) if (material_name_ptr == -1) { material_name = cstring() [ui, readonly, display="Material Name"]; _name = material_name; } // Parse technique set if inline if (technique_set_ptr == -1) { technique_set = parse_here("materialtechniqueset"); } // Parse texture defs if inline if (texture_table_ptr == -1 && texture_count > 0) { texture_defs = 0; repeat(texture_count) { _texture_def = parse_here("materialtexturedef"); texture_defs = push("texture_defs", _texture_def); } } // Parse constant defs if inline if (constant_table_ptr == -1 && constant_count > 0) { constant_defs = 0; repeat(constant_count) { _constant_def = parse_here("materialconstantdef"); constant_defs = push("constant_defs", _constant_def); } } // Parse state bits if inline if (state_bits_table_ptr == -1 && state_bits_count > 0) { state_bits = 0; repeat(state_bits_count) { _state_bit = parse_here("gfxstatebits"); state_bits = push("state_bits", _state_bit); } } }