Replace legacy DrawXxxCmd structs with RenderMessage variants for all
10 Rust-produced command types. Variable-length commands (LineStrip,
Polygon) use alloc_aux() for vertex data with explicit pointers in the
enum, avoiding layout coupling. Remove legacy structs and command_type
constants module.
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
refactor: introduce SpriteOp/SpriteFlags, rename SpriteId to KnownSpriteId
Replace raw u32 sprite_flags with typed SpriteOp (packed sprite index +
transform flags) and SpriteFlags (bitflags for the 13 known blit flags).
Follows the same pattern as SoundId/KnownSoundId in the audio system.
- SpriteId enum renamed to KnownSpriteId (non-exhaustive catalog)
- SpriteOp: #[repr(transparent)] newtype with index()/flags() accessors
- SpriteFlags: bitflags! type replacing raw 0x0080_0000-style masks
- Updated through the full pipeline: DrawSpriteCmd, RenderMessage,
vtable signature, dispatcher, and blit_sprite implementation
- Added bitflags 2 as direct dep (already transitive via windows crate)
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
feat: introduce RenderMessage enum for typed render queue commands
Add a strongly-typed RenderMessage enum that can be stored inline in the
existing RenderQueue buffer arena (zero allocation). TypedRenderCmd wraps
it with the standard command_type/layer prefix so sorting works unchanged.
The dispatcher handles both legacy byte-format and typed commands.
Also rename DrawSpriteCmd fields sprite_id->sprite_flags, frame->palette
to match the vtable signature used by the dispatcher.
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
refactor: dispatch via DisplayGfx::*_raw methods in queue_dispatch
Replaces the per-case `((*vtable).method)(display, ...)` open-coding
with the auto-generated `DisplayGfx::*_raw` methods produced by
`bind_DisplayGfxVtable!(DisplayGfx, base.vtable)`. The `_raw` methods
do the same `((*(*this).base.vtable).method)(this, args...)` dispatch
under the hood while keeping the noalias-safe raw-pointer signature.
Drops the explicit `vtable: *const DisplayGfxVtable` parameter from
all 14 per-case dispatcher functions and removes the `let vtable =
(*display).base.vtable` setup in the main loop. Net −34 lines.
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
feat: port RenderDrawingQueue dispatcher to pure Rust
Ports the per-frame render-queue dispatcher (0x542350, ~789k dispatches
per minute of gameplay) and its four leaf helpers — RQ_ClipCoordinates
(0x542BA0), RQ_ClipCoordinatesWithRef (0x542C70), RQ_TranslateCoordinates
(0x542B10, formerly mis-labelled RQ_GetCameraOffset_Maybe), and the
inline FixedDiv16_16 — to native Rust. The dispatcher's 14 cmd-type
cases dispatch through the DisplayGfx vtable to slots 11..22 via raw
vtable pointers, eliminating the last per-frame WA→DisplayGfx bridge.
Lesson #1 from the project memory bit again: the Ghidra decompile of
RQ_TranslateCoordinates lost the ECX register input entirely (only
showed in_EAX and unaff_EDI). Verified ECX = x_in from the prologue
disasm `AND ECX, 0xFFFF_0000` at 0x542B1A and from the dispatcher's
`MOV ECX, [ESI+0x8]` setup at every call site. Recorded as failure
mode #3 in feedback_ghidra_caller_frame_reads.md.
ClipContext, helpers, and all 14 case bodies use the existing Fixed
type (Fixed::floor / Fixed::div / Fixed::mul_raw)…