refactor: add RQ_ prefix to render queue addresses, label pipeline in Ghidra
Browse filesRename all RenderQueue enqueue function constants with RQ_ prefix for
consistency (e.g., DRAW_PIXEL -> RQ_DRAW_PIXEL). Add 20 new address
constants for helpers, pipeline functions, and the type 0xE enqueue.
Label 25 functions in Ghidra including 7 RQ helpers and 7 render
pipeline functions. Document complete render queue system in
docs/re-notes/render-queue.md.
Research findings:
- All 11 standalone enqueue functions identified (types 0-14 switch,
but types 3/7/10/12 have no standalone enqueue — inlined or unused)
- DDDisplay vtable drawing method map (12 slots at 0x2C-0x58)
- Render pipeline: RenderFrame -> GameRender -> RQ_RenderDrawingQueue
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
crates/openwa-harness/src/lib.rs
CHANGED
|
@@ -409,7 +409,7 @@ mod tests {
|
|
| 409 |
("FireWeapon", va::FIRE_WEAPON),
|
| 410 |
("InitWeaponTable", va::INIT_WEAPON_TABLE),
|
| 411 |
("BlitScreen", va::BLIT_SCREEN),
|
| 412 |
-
("RenderDrawingQueue", va::
|
| 413 |
("DrawLandscape", va::DRAW_LANDSCAPE),
|
| 414 |
("ConstructPCLandscape", va::CONSTRUCT_PC_LANDSCAPE),
|
| 415 |
("ConstructDSSound", va::CONSTRUCT_DS_SOUND),
|
|
|
|
| 409 |
("FireWeapon", va::FIRE_WEAPON),
|
| 410 |
("InitWeaponTable", va::INIT_WEAPON_TABLE),
|
| 411 |
("BlitScreen", va::BLIT_SCREEN),
|
| 412 |
+
("RenderDrawingQueue", va::RQ_RENDER_DRAWING_QUEUE),
|
| 413 |
("DrawLandscape", va::DRAW_LANDSCAPE),
|
| 414 |
("ConstructPCLandscape", va::CONSTRUCT_PC_LANDSCAPE),
|
| 415 |
("ConstructDSSound", va::CONSTRUCT_DS_SOUND),
|
crates/openwa-types/src/address.rs
CHANGED
|
@@ -158,16 +158,37 @@ pub mod va {
|
|
| 158 |
pub const CONSTRUCT_DD_DISPLAY: u32 = 0x0056_9D00;
|
| 159 |
pub const CONSTRUCT_FRAME_BUFFER: u32 = 0x005A_2430;
|
| 160 |
pub const BLIT_SCREEN: u32 = 0x005A_2020;
|
| 161 |
-
pub const
|
| 162 |
pub const DRAW_LANDSCAPE: u32 = 0x005A_2790;
|
| 163 |
-
pub const
|
| 164 |
-
pub const
|
| 165 |
-
pub const
|
| 166 |
-
pub const
|
| 167 |
-
pub const
|
| 168 |
-
pub const
|
| 169 |
-
pub const
|
| 170 |
-
pub const
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 171 |
pub const LOAD_SPRITE: u32 = 0x0052_3400;
|
| 172 |
pub const CONSTRUCT_OPENGL_CPU: u32 = 0x005A_0850;
|
| 173 |
pub const OPENGL_INIT: u32 = 0x0059_F000;
|
|
@@ -200,9 +221,6 @@ pub mod va {
|
|
| 200 |
/// ProcessSprite — usercall EAX=sprite_ptr, 1 stack param (raw_data_ptr).
|
| 201 |
/// Parses .spr binary format: palette, frames, bitmap data.
|
| 202 |
pub const PROCESS_SPRITE: u32 = 0x004F_AB80;
|
| 203 |
-
/// DrawSpriteLocal — thiscall + EAX=y_pos (usercall), 4 stack params.
|
| 204 |
-
/// Enqueues draw command type 5 (screen-space). See DrawSpriteGlobal (type 4).
|
| 205 |
-
pub const DRAW_SPRITE_LOCAL: u32 = 0x0054_2060;
|
| 206 |
|
| 207 |
// === Landscape ===
|
| 208 |
|
|
@@ -388,8 +406,6 @@ pub mod va {
|
|
| 388 |
pub const DDDISPLAY_CONSTRUCT_TEXTBOX: u32 = 0x004F_AF00;
|
| 389 |
/// SetTextboxText — stdcall(textbox, msg, textcolor, color1, color2, a6, a7, opacity)
|
| 390 |
pub const SET_TEXTBOX_TEXT: u32 = 0x004F_B070;
|
| 391 |
-
/// DrawTextboxLocal — draws textbox at screen position
|
| 392 |
-
pub const DRAW_TEXTBOX_LOCAL: u32 = 0x0054_2200;
|
| 393 |
|
| 394 |
// === Global variables (in .data) ===
|
| 395 |
|
|
|
|
| 158 |
pub const CONSTRUCT_DD_DISPLAY: u32 = 0x0056_9D00;
|
| 159 |
pub const CONSTRUCT_FRAME_BUFFER: u32 = 0x005A_2430;
|
| 160 |
pub const BLIT_SCREEN: u32 = 0x005A_2020;
|
| 161 |
+
pub const RQ_RENDER_DRAWING_QUEUE: u32 = 0x0054_2350;
|
| 162 |
pub const DRAW_LANDSCAPE: u32 = 0x005A_2790;
|
| 163 |
+
pub const RQ_DRAW_PIXEL: u32 = 0x0054_1D60;
|
| 164 |
+
pub const RQ_DRAW_LINE_STRIP: u32 = 0x0054_1DD0;
|
| 165 |
+
pub const RQ_DRAW_POLYGON: u32 = 0x0054_1E50;
|
| 166 |
+
pub const RQ_DRAW_SCALED: u32 = 0x0054_1ED0;
|
| 167 |
+
pub const RQ_DRAW_RECT: u32 = 0x0054_1F40;
|
| 168 |
+
pub const RQ_DRAW_SPRITE_GLOBAL: u32 = 0x0054_1FE0;
|
| 169 |
+
pub const RQ_DRAW_SPRITE_LOCAL: u32 = 0x0054_2060;
|
| 170 |
+
pub const RQ_DRAW_SPRITE_OFFSET: u32 = 0x0054_20E0;
|
| 171 |
+
pub const RQ_DRAW_BITMAP_GLOBAL: u32 = 0x0054_2170;
|
| 172 |
+
pub const RQ_DRAW_TEXTBOX_LOCAL: u32 = 0x0054_2200;
|
| 173 |
+
pub const RQ_DRAW_CLIPPED_SPRITE_MAYBE: u32 = 0x0054_22A0;
|
| 174 |
+
|
| 175 |
+
// RenderQueue helpers
|
| 176 |
+
pub const RQ_CLIP_COORDINATES: u32 = 0x0054_2BA0;
|
| 177 |
+
pub const RQ_GET_CAMERA_OFFSET_MAYBE: u32 = 0x0054_2B10;
|
| 178 |
+
pub const RQ_CLIP_WITH_REF_OFFSET_MAYBE: u32 = 0x0054_2C70;
|
| 179 |
+
pub const RQ_TRANSFORM_WITH_ZOOM_MAYBE: u32 = 0x0054_2D50;
|
| 180 |
+
pub const RQ_SMOOTH_INTERPOLATE_MAYBE: u32 = 0x0054_2E60;
|
| 181 |
+
pub const RQ_UPDATE_CLIP_BOUNDS_MAYBE: u32 = 0x0054_2F10;
|
| 182 |
+
pub const RQ_SATURATE_CLIP_BOUNDS_MAYBE: u32 = 0x0054_2F70;
|
| 183 |
+
|
| 184 |
+
// Render pipeline
|
| 185 |
+
pub const RENDER_FRAME_MAYBE: u32 = 0x0056_E040;
|
| 186 |
+
pub const GAME_RENDER_MAYBE: u32 = 0x0053_3DC0;
|
| 187 |
+
pub const RENDER_TERRAIN_MAYBE: u32 = 0x0053_5000;
|
| 188 |
+
pub const RENDER_HUD_MAYBE: u32 = 0x0053_4F20;
|
| 189 |
+
pub const RENDER_TURN_STATUS_MAYBE: u32 = 0x0053_4E00;
|
| 190 |
+
pub const PALETTE_MANAGE_MAYBE: u32 = 0x0053_3C80;
|
| 191 |
+
pub const PALETTE_ANIMATE_MAYBE: u32 = 0x0053_3A80;
|
| 192 |
pub const LOAD_SPRITE: u32 = 0x0052_3400;
|
| 193 |
pub const CONSTRUCT_OPENGL_CPU: u32 = 0x005A_0850;
|
| 194 |
pub const OPENGL_INIT: u32 = 0x0059_F000;
|
|
|
|
| 221 |
/// ProcessSprite — usercall EAX=sprite_ptr, 1 stack param (raw_data_ptr).
|
| 222 |
/// Parses .spr binary format: palette, frames, bitmap data.
|
| 223 |
pub const PROCESS_SPRITE: u32 = 0x004F_AB80;
|
|
|
|
|
|
|
|
|
|
| 224 |
|
| 225 |
// === Landscape ===
|
| 226 |
|
|
|
|
| 406 |
pub const DDDISPLAY_CONSTRUCT_TEXTBOX: u32 = 0x004F_AF00;
|
| 407 |
/// SetTextboxText — stdcall(textbox, msg, textcolor, color1, color2, a6, a7, opacity)
|
| 408 |
pub const SET_TEXTBOX_TEXT: u32 = 0x004F_B070;
|
|
|
|
|
|
|
| 409 |
|
| 410 |
// === Global variables (in .data) ===
|
| 411 |
|
crates/openwa-wormkit/src/replacements/render.rs
CHANGED
|
@@ -605,61 +605,61 @@ pub fn install() -> Result<(), String> {
|
|
| 605 |
unsafe {
|
| 606 |
let _ = hook::install(
|
| 607 |
"DrawPixel",
|
| 608 |
-
va::
|
| 609 |
trampoline_draw_pixel as *const (),
|
| 610 |
)?;
|
| 611 |
|
| 612 |
let _ = hook::install(
|
| 613 |
"DrawLineStrip",
|
| 614 |
-
va::
|
| 615 |
trampoline_draw_line_strip as *const (),
|
| 616 |
)?;
|
| 617 |
|
| 618 |
let _ = hook::install(
|
| 619 |
"DrawPolygon",
|
| 620 |
-
va::
|
| 621 |
trampoline_draw_polygon as *const (),
|
| 622 |
)?;
|
| 623 |
|
| 624 |
let _ = hook::install(
|
| 625 |
"DrawScaled",
|
| 626 |
-
va::
|
| 627 |
trampoline_draw_scaled as *const (),
|
| 628 |
)?;
|
| 629 |
|
| 630 |
let _ = hook::install(
|
| 631 |
"DrawRect",
|
| 632 |
-
va::
|
| 633 |
trampoline_draw_rect as *const (),
|
| 634 |
)?;
|
| 635 |
|
| 636 |
let _ = hook::install(
|
| 637 |
"DrawSpriteGlobal",
|
| 638 |
-
va::
|
| 639 |
trampoline_draw_sprite_global as *const (),
|
| 640 |
)?;
|
| 641 |
|
| 642 |
let _ = hook::install(
|
| 643 |
"DrawSpriteLocal",
|
| 644 |
-
va::
|
| 645 |
trampoline_draw_sprite_local as *const (),
|
| 646 |
)?;
|
| 647 |
|
| 648 |
let _ = hook::install(
|
| 649 |
"DrawSpriteOffset",
|
| 650 |
-
va::
|
| 651 |
trampoline_draw_sprite_offset as *const (),
|
| 652 |
)?;
|
| 653 |
|
| 654 |
let _ = hook::install(
|
| 655 |
"DrawBitmapGlobal",
|
| 656 |
-
va::
|
| 657 |
trampoline_draw_bitmap_global as *const (),
|
| 658 |
)?;
|
| 659 |
|
| 660 |
let _ = hook::install(
|
| 661 |
"DrawTextboxLocal",
|
| 662 |
-
va::
|
| 663 |
trampoline_draw_textbox_local as *const (),
|
| 664 |
)?;
|
| 665 |
|
|
|
|
| 605 |
unsafe {
|
| 606 |
let _ = hook::install(
|
| 607 |
"DrawPixel",
|
| 608 |
+
va::RQ_DRAW_PIXEL,
|
| 609 |
trampoline_draw_pixel as *const (),
|
| 610 |
)?;
|
| 611 |
|
| 612 |
let _ = hook::install(
|
| 613 |
"DrawLineStrip",
|
| 614 |
+
va::RQ_DRAW_LINE_STRIP,
|
| 615 |
trampoline_draw_line_strip as *const (),
|
| 616 |
)?;
|
| 617 |
|
| 618 |
let _ = hook::install(
|
| 619 |
"DrawPolygon",
|
| 620 |
+
va::RQ_DRAW_POLYGON,
|
| 621 |
trampoline_draw_polygon as *const (),
|
| 622 |
)?;
|
| 623 |
|
| 624 |
let _ = hook::install(
|
| 625 |
"DrawScaled",
|
| 626 |
+
va::RQ_DRAW_SCALED,
|
| 627 |
trampoline_draw_scaled as *const (),
|
| 628 |
)?;
|
| 629 |
|
| 630 |
let _ = hook::install(
|
| 631 |
"DrawRect",
|
| 632 |
+
va::RQ_DRAW_RECT,
|
| 633 |
trampoline_draw_rect as *const (),
|
| 634 |
)?;
|
| 635 |
|
| 636 |
let _ = hook::install(
|
| 637 |
"DrawSpriteGlobal",
|
| 638 |
+
va::RQ_DRAW_SPRITE_GLOBAL,
|
| 639 |
trampoline_draw_sprite_global as *const (),
|
| 640 |
)?;
|
| 641 |
|
| 642 |
let _ = hook::install(
|
| 643 |
"DrawSpriteLocal",
|
| 644 |
+
va::RQ_DRAW_SPRITE_LOCAL,
|
| 645 |
trampoline_draw_sprite_local as *const (),
|
| 646 |
)?;
|
| 647 |
|
| 648 |
let _ = hook::install(
|
| 649 |
"DrawSpriteOffset",
|
| 650 |
+
va::RQ_DRAW_SPRITE_OFFSET,
|
| 651 |
trampoline_draw_sprite_offset as *const (),
|
| 652 |
)?;
|
| 653 |
|
| 654 |
let _ = hook::install(
|
| 655 |
"DrawBitmapGlobal",
|
| 656 |
+
va::RQ_DRAW_BITMAP_GLOBAL,
|
| 657 |
trampoline_draw_bitmap_global as *const (),
|
| 658 |
)?;
|
| 659 |
|
| 660 |
let _ = hook::install(
|
| 661 |
"DrawTextboxLocal",
|
| 662 |
+
va::RQ_DRAW_TEXTBOX_LOCAL,
|
| 663 |
trampoline_draw_textbox_local as *const (),
|
| 664 |
)?;
|
| 665 |
|
crates/openwa-wormkit/src/validation/mod.rs
CHANGED
|
@@ -196,7 +196,7 @@ fn validate_addresses(result: &mut ValidationResult) {
|
|
| 196 |
("FireWeapon", va::FIRE_WEAPON),
|
| 197 |
("InitWeaponTable", va::INIT_WEAPON_TABLE),
|
| 198 |
("BlitScreen", va::BLIT_SCREEN),
|
| 199 |
-
("RenderDrawingQueue", va::
|
| 200 |
("DrawLandscape", va::DRAW_LANDSCAPE),
|
| 201 |
("ConstructPCLandscape", va::CONSTRUCT_PC_LANDSCAPE),
|
| 202 |
("ConstructDSSound", va::CONSTRUCT_DS_SOUND),
|
|
|
|
| 196 |
("FireWeapon", va::FIRE_WEAPON),
|
| 197 |
("InitWeaponTable", va::INIT_WEAPON_TABLE),
|
| 198 |
("BlitScreen", va::BLIT_SCREEN),
|
| 199 |
+
("RenderDrawingQueue", va::RQ_RENDER_DRAWING_QUEUE),
|
| 200 |
("DrawLandscape", va::DRAW_LANDSCAPE),
|
| 201 |
("ConstructPCLandscape", va::CONSTRUCT_PC_LANDSCAPE),
|
| 202 |
("ConstructDSSound", va::CONSTRUCT_DS_SOUND),
|
docs/re-notes/render-queue.md
ADDED
|
@@ -0,0 +1,107 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
# RenderQueue System
|
| 2 |
+
|
| 3 |
+
## Overview
|
| 4 |
+
|
| 5 |
+
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.
|
| 6 |
+
|
| 7 |
+
The RenderQueue lives at DDGame+0x524 (see `ddgame_offsets::RENDER_QUEUE`).
|
| 8 |
+
|
| 9 |
+
## RenderQueue struct (0x12008 bytes)
|
| 10 |
+
|
| 11 |
+
| Offset | Size | Field |
|
| 12 |
+
|--------|------|-------|
|
| 13 |
+
| 0x00000 | 4 | `buffer_offset` — write position (grows downward from 0x10000) |
|
| 14 |
+
| 0x00004 | 0x10000 | `_buffer` — command data storage |
|
| 15 |
+
| 0x10004 | 4 | `entry_count` — number of enqueued commands |
|
| 16 |
+
| 0x10008 | 0x2000 | `entry_ptrs[0x800]` — pointers to command entries |
|
| 17 |
+
|
| 18 |
+
Max 2048 (0x800) entries per frame. Buffer grows downward; each alloc subtracts from `buffer_offset`.
|
| 19 |
+
|
| 20 |
+
## Command Types (0–14)
|
| 21 |
+
|
| 22 |
+
The dequeue function uses a switch on command type (first DWORD of each entry).
|
| 23 |
+
|
| 24 |
+
### Enqueue functions (standalone, all ported to Rust)
|
| 25 |
+
|
| 26 |
+
| Type | Function | Address | DDDisplay vtable | Purpose |
|
| 27 |
+
|------|----------|---------|------------------|---------|
|
| 28 |
+
| 0 | RQ_DrawRect | 0x541F40 | [0x48] | Filled rectangle (clipped) |
|
| 29 |
+
| 1 | RQ_DrawBitmapGlobal | 0x542170 | [0x50] | Bitmap at world position |
|
| 30 |
+
| 2 | RQ_DrawTextboxLocal | 0x542200 | [0x50] | Text box (optional clipping) |
|
| 31 |
+
| 4 | RQ_DrawSpriteGlobal | 0x541FE0 | [0x4C] | Sprite at world position |
|
| 32 |
+
| 5 | RQ_DrawSpriteLocal | 0x542060 | [0x4C] | Sprite at screen position (camera-adjusted) |
|
| 33 |
+
| 6 | RQ_DrawSpriteOffset | 0x5420E0 | [0x4C] | Sprite with optional clipping/rotation |
|
| 34 |
+
| 8 | RQ_DrawLineStrip | 0x541DD0 | [0x38] | Connected line segments (variable-size) |
|
| 35 |
+
| 9 | RQ_DrawPolygon | 0x541E50 | [0x34] | Filled polygon edges (variable-size) |
|
| 36 |
+
| 0xB | RQ_DrawScaled | 0x541ED0 | [0x40] | Scaled sprite |
|
| 37 |
+
| 0xD | RQ_DrawPixel | 0x541D60 | [0x2C] | Single pixel |
|
| 38 |
+
| 0xE | RQ_DrawClippedSprite_Maybe | 0x5422A0 | [0x58] | Sprite with complex clipping (like type 6 but different vtable slot) |
|
| 39 |
+
|
| 40 |
+
### Types without standalone enqueue functions
|
| 41 |
+
|
| 42 |
+
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.
|
| 43 |
+
|
| 44 |
+
| Type | DDDisplay vtable | Dequeue behavior |
|
| 45 |
+
|------|------------------|------------------|
|
| 46 |
+
| 3 | [0x54] | Coord-clipped, 5 params |
|
| 47 |
+
| 7 | [0x30] | Direct command struct pass, 3 params |
|
| 48 |
+
| 10 | [0x3C] | Camera-adjusted + pixel offset, 6 params |
|
| 49 |
+
| 12 | [0x44] | Like type 0xB but different vtable slot |
|
| 50 |
+
|
| 51 |
+
## DDDisplay Drawing Vtable
|
| 52 |
+
|
| 53 |
+
The dequeue function dispatches draw calls through a DDDisplay vtable. Slot offsets:
|
| 54 |
+
|
| 55 |
+
| Offset | Method | Used by types |
|
| 56 |
+
|--------|--------|---------------|
|
| 57 |
+
| 0x2C | PutPixel | 0xD |
|
| 58 |
+
| 0x30 | (unknown) | 7 |
|
| 59 |
+
| 0x34 | DrawPolygonEdge | 9 |
|
| 60 |
+
| 0x38 | DrawLineSegment | 8 |
|
| 61 |
+
| 0x3C | (unknown) | 10 |
|
| 62 |
+
| 0x40 | DrawScaledSprite | 0xB |
|
| 63 |
+
| 0x44 | (unknown) | 12 |
|
| 64 |
+
| 0x48 | DrawClippedRect | 0 |
|
| 65 |
+
| 0x4C | DrawSprite | 4, 5, 6 |
|
| 66 |
+
| 0x50 | DrawBitmap | 1, 2 |
|
| 67 |
+
| 0x54 | (unknown) | 3 |
|
| 68 |
+
| 0x58 | DrawClippedSprite | 0xE |
|
| 69 |
+
|
| 70 |
+
## Helper Functions
|
| 71 |
+
|
| 72 |
+
| Address | Name | Purpose |
|
| 73 |
+
|---------|------|---------|
|
| 74 |
+
| 0x542B10 | RQ_GetCameraOffset_Maybe | Returns camera/viewport offset for screen-space conversion |
|
| 75 |
+
| 0x542BA0 | RQ_ClipCoordinates | Main 16.16 fixed-point coordinate clipping |
|
| 76 |
+
| 0x542C70 | RQ_ClipWithRefOffset_Maybe | Clipping with reference offset transform (type 6 flag 0x04) |
|
| 77 |
+
| 0x542D50 | RQ_TransformWithZoom_Maybe | Coordinate transformation with zoom/scale |
|
| 78 |
+
| 0x542E60 | RQ_SmoothInterpolate_Maybe | Linear interpolation with threshold (smooth scrolling) |
|
| 79 |
+
| 0x542F10 | RQ_UpdateClipBounds_Maybe | Viewport bounding box constraint updater |
|
| 80 |
+
| 0x542F70 | RQ_SaturateClipBounds_Maybe | Clipping with overflow saturation |
|
| 81 |
+
|
| 82 |
+
## Render Pipeline
|
| 83 |
+
|
| 84 |
+
| Address | Name | Role |
|
| 85 |
+
|---------|------|------|
|
| 86 |
+
| 0x56E040 | RenderFrame_Maybe | Top-level render frame dispatcher |
|
| 87 |
+
| 0x533DC0 | GameRender_Maybe | Core game render: resets queue, processes scene, calls RQ_RenderDrawingQueue |
|
| 88 |
+
| 0x535000 | RenderTerrain_Maybe | Terrain/landscape viewport rendering |
|
| 89 |
+
| 0x534F20 | RenderHUD_Maybe | HUD/timer display |
|
| 90 |
+
| 0x534E00 | RenderTurnStatus_Maybe | Turn state/status text |
|
| 91 |
+
| 0x533C80 | PaletteManage_Maybe | Palette/color management |
|
| 92 |
+
| 0x533A80 | PaletteAnimate_Maybe | Palette animation/cycling (3 color palettes) |
|
| 93 |
+
|
| 94 |
+
## Higher-Level Drawing Functions
|
| 95 |
+
|
| 96 |
+
These are not RenderQueue enqueue methods but call them:
|
| 97 |
+
|
| 98 |
+
| Address | Name | Notes |
|
| 99 |
+
|---------|------|-------|
|
| 100 |
+
| 0x500720 | DrawBungeeTrail | Uses DrawSpriteLocal + DrawPolygon/DrawLineStrip |
|
| 101 |
+
| 0x5197D0 | DrawCrosshairLine | Uses DrawPolygon + DrawSpriteLocal |
|
| 102 |
+
|
| 103 |
+
## Dequeue Processing (0x542350)
|
| 104 |
+
|
| 105 |
+
`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.
|
| 106 |
+
|
| 107 |
+
Fixed-point coordinates (16.16) are right-shifted to pixel values (`>> 0x10`) before passing to DDDisplay methods.
|