Download docs/re-notes/render-queue.md from nmarshall/wormz-a: direct link, hf CLI and curl.
- Browser
- Download file 5.06 kB
-
https://huggingface.co/nmarshall/wormz-a/resolve/059b36558bcd8bc502ecc6e9986ed77a3f2bd2ca/docs/re-notes/render-queue.md
- Command line
-
hf download hf://nmarshall/wormz-a@059b36558bcd8bc502ecc6e9986ed77a3f2bd2ca/docs/re-notes/render-queue.md
-
curl -L -o render-queue.md https://huggingface.co/nmarshall/wormz-a/resolve/059b36558bcd8bc502ecc6e9986ed77a3f2bd2ca/docs/re-notes/render-queue.md
RenderQueue System
Overview
WA.exe uses a deferred rendering queue. Game logic enqueues draw commands into a per-frame buffer, then RQ_RenderDrawingQueue (0x542350) processes them all at once, sorted by priority/layer.
The RenderQueue lives at DDGame+0x524 (see ddgame_offsets::RENDER_QUEUE).
RenderQueue struct (0x12008 bytes)
| Offset | Size | Field |
|---|---|---|
| 0x00000 | 4 | buffer_offset — write position (grows downward from 0x10000) |
| 0x00004 | 0x10000 | _buffer — command data storage |
| 0x10004 | 4 | entry_count — number of enqueued commands |
| 0x10008 | 0x2000 | entry_ptrs[0x800] — pointers to command entries |
Max 2048 (0x800) entries per frame. Buffer grows downward; each alloc subtracts from buffer_offset.
Command Types (0–14)
The dequeue function uses a switch on command type (first DWORD of each entry).
Enqueue functions (standalone, all ported to Rust)
| Type | Function | Address | DDDisplay vtable | Purpose |
|---|---|---|---|---|
| 0 | RQ_DrawRect | 0x541F40 | [0x48] | Filled rectangle (clipped) |
| 1 | RQ_DrawBitmapGlobal | 0x542170 | [0x50] | Bitmap at world position |
| 2 | RQ_DrawTextboxLocal | 0x542200 | [0x50] | Text box (optional clipping) |
| 4 | RQ_DrawSpriteGlobal | 0x541FE0 | [0x4C] | Sprite at world position |
| 5 | RQ_DrawSpriteLocal | 0x542060 | [0x4C] | Sprite at screen position (camera-adjusted) |
| 6 | RQ_DrawSpriteOffset | 0x5420E0 | [0x4C] | Sprite with optional clipping/rotation |
| 8 | RQ_DrawLineStrip | 0x541DD0 | [0x38] | Connected line segments (variable-size) |
| 9 | RQ_DrawPolygon | 0x541E50 | [0x34] | Filled polygon edges (variable-size) |
| 0xB | RQ_DrawScaled | 0x541ED0 | [0x40] | Scaled sprite |
| 0xD | RQ_DrawPixel | 0x541D60 | [0x2C] | Single pixel |
| 0xE | RQ_DrawClippedSprite_Maybe | 0x5422A0 | [0x58] | Sprite with complex clipping (like type 6 but different vtable slot) |
Types without standalone enqueue functions
These types exist in the dequeue switch but have no standalone enqueue function in the binary. Their enqueue code is either inlined at call sites or unused in WA 3.8.1.
| Type | DDDisplay vtable | Dequeue behavior |
|---|---|---|
| 3 | [0x54] | Coord-clipped, 5 params |
| 7 | [0x30] | Direct command struct pass, 3 params |
| 10 | [0x3C] | Camera-adjusted + pixel offset, 6 params |
| 12 | [0x44] | Like type 0xB but different vtable slot |
DDDisplay Drawing Vtable
The dequeue function dispatches draw calls through a DDDisplay vtable. Slot offsets:
| Offset | Method | Used by types |
|---|---|---|
| 0x2C | PutPixel | 0xD |
| 0x30 | (unknown) | 7 |
| 0x34 | DrawPolygonEdge | 9 |
| 0x38 | DrawLineSegment | 8 |
| 0x3C | (unknown) | 10 |
| 0x40 | DrawScaledSprite | 0xB |
| 0x44 | (unknown) | 12 |
| 0x48 | DrawClippedRect | 0 |
| 0x4C | DrawSprite | 4, 5, 6 |
| 0x50 | DrawBitmap | 1, 2 |
| 0x54 | (unknown) | 3 |
| 0x58 | DrawClippedSprite | 0xE |
Helper Functions
| Address | Name | Purpose |
|---|---|---|
| 0x542B10 | RQ_GetCameraOffset_Maybe | Returns camera/viewport offset for screen-space conversion |
| 0x542BA0 | RQ_ClipCoordinates | Main 16.16 fixed-point coordinate clipping |
| 0x542C70 | RQ_ClipWithRefOffset_Maybe | Clipping with reference offset transform (type 6 flag 0x04) |
| 0x542D50 | RQ_TransformWithZoom_Maybe | Coordinate transformation with zoom/scale |
| 0x542E60 | RQ_SmoothInterpolate_Maybe | Linear interpolation with threshold (smooth scrolling) |
| 0x542F10 | RQ_UpdateClipBounds_Maybe | Viewport bounding box constraint updater |
| 0x542F70 | RQ_SaturateClipBounds_Maybe | Clipping with overflow saturation |
Render Pipeline
| Address | Name | Role |
|---|---|---|
| 0x56E040 | RenderFrame_Maybe | Top-level render frame dispatcher |
| 0x533DC0 | GameRender_Maybe | Core game render: resets queue, processes scene, calls RQ_RenderDrawingQueue |
| 0x535000 | RenderTerrain_Maybe | Terrain/landscape viewport rendering |
| 0x534F20 | RenderHUD_Maybe | HUD/timer display |
| 0x534E00 | RenderTurnStatus_Maybe | Turn state/status text |
| 0x533C80 | PaletteManage_Maybe | Palette/color management |
| 0x533A80 | PaletteAnimate_Maybe | Palette animation/cycling (3 color palettes) |
Higher-Level Drawing Functions
These are not RenderQueue enqueue methods but call them:
| Address | Name | Notes |
|---|---|---|
| 0x500720 | DrawBungeeTrail | Uses DrawSpriteLocal + DrawPolygon/DrawLineStrip |
| 0x5197D0 | DrawCrosshairLine | Uses DrawPolygon + DrawSpriteLocal |
Dequeue Processing (0x542350)
RQ_RenderDrawingQueue sorts entries by priority field (DWORD at entry+4) via qsort, then iterates in reverse order (highest priority last = drawn on top). Each command is dispatched through the type switch, with coordinate clipping applied before calling the DDDisplay vtable method.
Fixed-point coordinates (16.16) are right-shifted to pixel values (>> 0x10) before passing to DDDisplay methods.