Replace the FFI-based headless DisplayBase construction with pure Rust:
new_headless() allocates and initializes all fields (slot_table, sentinel,
sprite cache chain: 0x28 wrapper -> 0x3C buffer ctrl -> 0x80020 buffer)
without calling WA's constructor.
Must use WA's vtable pointer (not our own copy) because WA checks vtable
address identity. Patch WA's headless vtable destructor slot in-place to
a Rust version that correctly frees the Rust-allocated sprite cache.
Extract patch_vtable() utility to openwa-core::vtable for reuse.
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>