type menudef [display="Menu Definition"] { // MenuDef_t structure from OpenAssetTools IW3_Assets.h // Fixed part: 272 bytes total // ============ WindowDef_t embedded (156 bytes) ============ window = parse_here("windowdef") [display="Window"]; // ============ Menu Properties ============ i32 font_ptr [ui, readonly, display="Font Ptr"]; i32 full_screen [ui, readonly, display="Full Screen"]; i32 item_count [ui, readonly, display="Item Count"]; i32 font_index [ui, readonly, display="Font Index"]; i32 cursor_item [ui, readonly, display="Cursor Item"]; i32 fade_cycle [ui, readonly, display="Fade Cycle"]; // Fade values (16 bytes) f32 fade_clamp [ui, readonly, display="Fade Clamp"]; f32 fade_amount [ui, readonly, display="Fade Amount"]; f32 fade_in_amount [ui, readonly, display="Fade In Amount"]; f32 blur_radius [ui, readonly, display="Blur Radius"]; // Event handler pointers i32 on_open_ptr [ui, readonly, display="OnOpen Ptr"]; i32 on_close_ptr [ui, readonly, display="OnClose Ptr"]; i32 on_esc_ptr [ui, readonly, display="OnESC Ptr"]; i32 on_key_ptr [ui, readonly, display="OnKey Ptr"]; // Visible expression (statement_s = 8 bytes) visible_exp = parse_here("statement") [display="Visible Exp"]; // More pointers i32 allowed_binding_ptr [ui, readonly, display="Allowed Binding Ptr"]; i32 sound_name_ptr [ui, readonly, display="Sound Name Ptr"]; i32 image_track [ui, readonly, display="Image Track"]; // Focus color (16 bytes) f32 focus_color_r [ui, readonly, display="Focus R"]; f32 focus_color_g [ui, readonly, display="Focus G"]; f32 focus_color_b [ui, readonly, display="Focus B"]; f32 focus_color_a [ui, readonly, display="Focus A"]; // Disable color (16 bytes) f32 disable_color_r [ui, readonly, display="Disable R"]; f32 disable_color_g [ui, readonly, display="Disable G"]; f32 disable_color_b [ui, readonly, display="Disable B"]; f32 disable_color_a [ui, readonly, display="Disable A"]; // Rect expressions (2 x statement_s = 16 bytes) rect_x_exp = parse_here("statement") [display="Rect X Exp"]; rect_y_exp = parse_here("statement") [display="Rect Y Exp"]; // Items pointer i32 items_ptr [ui, readonly, display="Items Ptr"]; // ============================================================ // INLINE DATA PARSING (exact order from zone file streaming) // ============================================================ // 1. Window name (if name_ptr == -1) _win_name_ptr = get(window, "name_ptr"); if (_win_name_ptr == -1) { name = cstring() [ui, readonly, display="Name"]; _name = name; } // 2. Window group (if group_ptr == -1) _win_group_ptr = get(window, "group_ptr"); if (_win_group_ptr == -1) { group = cstring() [ui, readonly, display="Group"]; } // 3. Window background Material (if background_ptr == -1) _win_bg_ptr = get(window, "background_ptr"); if (_win_bg_ptr == -1) { background = parse_here("material") [display="Background"]; } // 4. Font (if font_ptr == -1) if (font_ptr == -1) { font = cstring() [ui, readonly, display="Font"]; } // 5. OnOpen script (if on_open_ptr == -1) if (on_open_ptr == -1) { on_open = cstring() [ui, readonly, display="OnOpen"]; } // 6. OnClose script (if on_close_ptr == -1) if (on_close_ptr == -1) { on_close = cstring() [ui, readonly, display="OnClose"]; } // 7. OnESC script (if on_esc_ptr == -1) if (on_esc_ptr == -1) { on_esc = cstring() [ui, readonly, display="OnESC"]; } // 8. OnKey handler chain (if on_key_ptr == -1) if (on_key_ptr == -1) { on_key = parse_here("itemkeyhandler") [display="OnKey"]; } // 9. Visible expression entries (if entries_ptr == -1) _vis_num = get(visible_exp, "num_entries"); _vis_ptr = get(visible_exp, "entries_ptr"); if (_vis_ptr == -1 && _vis_num > 0 ) { // Read pointer array _vis_ptr_size = _vis_num * 4; _vis_ptrs = read(_vis_ptr_size) [display="Visible Entry Ptrs"]; // Parse each expression entry repeat(_vis_num) { _vis_entry = parse_here("expressionentry") [display="Visible Entry"]; } } // 10. Allowed binding (if allowed_binding_ptr == -1) if (allowed_binding_ptr == -1) { allowed_binding = cstring() [ui, readonly, display="Allowed Binding"]; } // 11. Sound name (if sound_name_ptr == -1) if (sound_name_ptr == -1) { sound_name = cstring() [ui, readonly, display="Sound Name"]; } // 12. Rect X expression entries (if entries_ptr == -1) _rx_num = get(rect_x_exp, "num_entries"); _rx_ptr = get(rect_x_exp, "entries_ptr"); if (_rx_ptr == -1 && _rx_num > 0 ) { _rx_ptr_size = _rx_num * 4; _rx_ptrs = read(_rx_ptr_size) [display="Rect X Entry Ptrs"]; repeat(_rx_num) { _rx_entry = parse_here("expressionentry") [display="Rect X Entry"]; } } // 13. Rect Y expression entries (if entries_ptr == -1) _ry_num = get(rect_y_exp, "num_entries"); _ry_ptr = get(rect_y_exp, "entries_ptr"); if (_ry_ptr == -1 && _ry_num > 0 ) { _ry_ptr_size = _ry_num * 4; _ry_ptrs = read(_ry_ptr_size) [display="Rect Y Entry Ptrs"]; repeat(_ry_num) { _ry_entry = parse_here("expressionentry") [display="Rect Y Entry"]; } } // 14. Items array (if items_ptr == -1 and item_count > 0) if (items_ptr == -1 && item_count > 0 ) { // Array of item_count pointers (4 bytes each) _items_ptr_size = item_count * 4; _items_ptrs = read(_items_ptr_size) [display="Item Ptrs"]; // Then item_count itemdefs follow (each -1 pointer means inline) repeat(item_count) { _item = parse_here("itemdef") [display="Item"]; } } }