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: split render.rs, move game logic to core, type command structs
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: rename mislabeled tile-bitmap queue command and slot 11
Trying to trap DisplayGfx vtable slot 11 as dead code revealed it is in
fact reachable: RenderDrawingQueue case 0xD dispatches into it, and the
queue entries come from our own Rust trampoline for what was labelled
RQ_DrawPixel. Both names were wrong end-to-end — the function enqueues a
tile-cached bitmap draw (only known producer: CTaskLand::RenderLandscape),
not a single pixel.
Renames, byte-format unchanged:
WA 0x541D60: RQ_DrawPixel → RQ_EnqueueTiledBitmap
WA 0x56B8C0: DisplayGfx__CreateBitmap → DisplayGfx__DrawTiledBitmap
Rust DrawPixelCmd → DrawTiledBitmapCmd, with corrected field names
(x_pos/y_pos/color → y_fixed16/source_descriptor/x_fixed16)
command_type::DRAW_PIXEL → DRAW_TILED_BITMAP
trampoline_draw_pixel → trampoline_enqueue_tiled_bitmap
vtable slot 11 create_bitmap → draw_tiled_bitmap
The slot 11 docstring now captures the three-phase semantics (lazy
allocate tile surfaces, populate from source, clipped blit) so a future
port has a blueprint.
Co-Authored…
refactor: eliminate DDDisplay, make DisplayBase generic, rename DDDisplayWrapper
- Make DisplayBase<V: Vtable> generic over vtable type (like CTask<V>, BitGrid<V>)
- Eliminate DDDisplay wrapper type — DisplayGfx is now the direct this type
for all display vtable methods, removing constant as_gfx() casts
- DisplayGfx.base is now DisplayBase<*const DisplayVtable> (38-slot vtable)
- bind_DisplayVtable!(DisplayGfx, base.vtable) uses nested field path
- Rename DDDisplayVtable → DisplayVtable, dd_display.rs → display_vtable.rs
- Rename DDDisplayWrapper → RenderContext (manages framebuffer + dispatches
to renderer backends — the DD prefix was misleading since WA supports
multiple graphics backends), display_wrapper.rs → render_context.rs
- Update all address constants (DDISPLAY_* → DISPLAY_GFX_*, etc.)
- Rename 51 functions in Ghidra to match
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
fix: rename DRAW_SCALED to DRAW_CROSSHAIR, fix DrawCrosshairCmd fields
Command type 0xB is a crosshair draw, not a scaled sprite. The enqueue
function at 0x541ED0 writes [type, layer, color_fg, color_bg, x, y, 0],
dispatched by RenderDrawingQueue case 0xB to DDDisplay::draw_crosshair.
Also add DRAW_OUTLINED_PIXEL (0xC) constant.
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
fix: remove extra loading progress ticks, cargo fmt
Reduce from 4 to 2 DDGameWrapper__LoadingProgressTick calls, matching
the original constructor. Tick counter +0x04D8 now matches exactly
(0x334). All DDGameWrapper fields match the original.
Remaining headless checksum mismatch is likely due to headless display
handling differences (our headless display is non-null vs original's
NULL display parameter).
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
refactor: reorganize openwa-core into subdirectory modules