feat: map DisplayGfx internal fields and expose DisplayBase dimensions
Browse filesMap ~30 named fields across the 0x24E28-byte DisplayGfx struct, replacing
the single opaque blob. Key regions: camera offset, display dimensions,
clip rect, HWND, 3 layer object pointers, palette entries (256x4),
sprite table (1024 entries), two 64KB color mixing LUTs (additive and
gamma-corrected blend), and blend mode flag.
Also expose display_width/height and clip rect fields in DisplayBase
(previously hidden in _pad_3540).
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
crates/openwa-core/src/display/base.rs
CHANGED
|
@@ -52,8 +52,22 @@ pub struct DisplayBase {
|
|
| 52 |
pub _field_352c: u32,
|
| 53 |
// +0x3530..0x3540: indices 0xD4C..0xD4F (4 entries), zeroed by ctor
|
| 54 |
pub _fields_3530: [u32; 4],
|
| 55 |
-
// +0x3540
|
| 56 |
-
pub
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 57 |
}
|
| 58 |
|
| 59 |
const _: () = assert!(core::mem::size_of::<DisplayBase>() == 0x3560);
|
|
|
|
| 52 |
pub _field_352c: u32,
|
| 53 |
// +0x3530..0x3540: indices 0xD4C..0xD4F (4 entries), zeroed by ctor
|
| 54 |
pub _fields_3530: [u32; 4],
|
| 55 |
+
// +0x3540: display initialized flag (set to 1 by DDDisplay__Init)
|
| 56 |
+
pub display_initialized: u32,
|
| 57 |
+
// +0x3544: unknown
|
| 58 |
+
pub _unknown_3544: u32,
|
| 59 |
+
// +0x3548: display width in pixels (set by DDDisplay__Init)
|
| 60 |
+
pub display_width: u32,
|
| 61 |
+
// +0x354C: display height in pixels
|
| 62 |
+
pub display_height: u32,
|
| 63 |
+
// +0x3550: clip rect x1 (left, init 0)
|
| 64 |
+
pub clip_x1: i32,
|
| 65 |
+
// +0x3554: clip rect y1 (top, init 0)
|
| 66 |
+
pub clip_y1: i32,
|
| 67 |
+
// +0x3558: clip rect x2 (right, init = width)
|
| 68 |
+
pub clip_x2: i32,
|
| 69 |
+
// +0x355C: clip rect y2 (bottom, init = height)
|
| 70 |
+
pub clip_y2: i32,
|
| 71 |
}
|
| 72 |
|
| 73 |
const _: () = assert!(core::mem::size_of::<DisplayBase>() == 0x3560);
|
crates/openwa-core/src/display/gfx.rs
CHANGED
|
@@ -1,20 +1,161 @@
|
|
|
|
|
|
|
|
|
|
|
| 1 |
/// DisplayGfx — full display/graphics subsystem (derived from DisplayBase).
|
| 2 |
///
|
| 3 |
/// Constructor: DisplayGfx__Constructor (0x569C10), stdcall(this) → DisplayGfx*.
|
|
|
|
| 4 |
/// Size: 0x24E28 bytes.
|
| 5 |
///
|
| 6 |
/// Inheritance: DisplayBase (0x3560) → DisplayGfx (0x24E28).
|
| 7 |
/// The constructor calls DisplayBase__Constructor first, then sets the
|
| 8 |
-
///
|
| 9 |
///
|
| 10 |
/// Created by GameEngine__InitHardware in normal (non-headless) mode.
|
| 11 |
/// Stored in the session's `display` field (shared with DisplayBase in headless).
|
| 12 |
///
|
| 13 |
-
///
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 14 |
#[repr(C)]
|
| 15 |
pub struct DisplayGfx {
|
| 16 |
-
|
| 17 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 18 |
}
|
| 19 |
|
| 20 |
const _: () = assert!(core::mem::size_of::<DisplayGfx>() == 0x24E28);
|
|
|
|
| 1 |
+
use super::base::DisplayBase;
|
| 2 |
+
use core::ffi::c_void;
|
| 3 |
+
|
| 4 |
/// DisplayGfx — full display/graphics subsystem (derived from DisplayBase).
|
| 5 |
///
|
| 6 |
/// Constructor: DisplayGfx__Constructor (0x569C10), stdcall(this) → DisplayGfx*.
|
| 7 |
+
/// Initializer: DDDisplay__Init (0x569D00), usercall.
|
| 8 |
/// Size: 0x24E28 bytes.
|
| 9 |
///
|
| 10 |
/// Inheritance: DisplayBase (0x3560) → DisplayGfx (0x24E28).
|
| 11 |
/// The constructor calls DisplayBase__Constructor first, then sets the
|
| 12 |
+
/// DDDisplay vtable (0x66A218) and initializes display-specific fields.
|
| 13 |
///
|
| 14 |
/// Created by GameEngine__InitHardware in normal (non-headless) mode.
|
| 15 |
/// Stored in the session's `display` field (shared with DisplayBase in headless).
|
| 16 |
///
|
| 17 |
+
/// ## Memory layout overview
|
| 18 |
+
///
|
| 19 |
+
/// ```text
|
| 20 |
+
/// 0x0000 - 0x355F : DisplayBase (sprite cache, slot table, etc.)
|
| 21 |
+
/// 0x3540 : display_initialized flag
|
| 22 |
+
/// 0x3548 - 0x355F : display dimensions and clip rect
|
| 23 |
+
/// 0x3560 - 0x3577 : camera offset, rendering state
|
| 24 |
+
/// 0x3578 : HWND
|
| 25 |
+
/// 0x3580 - 0x358B : bitmap vector
|
| 26 |
+
/// 0x358C - 0x398C : palette entry table (256 × 4 bytes)
|
| 27 |
+
/// 0x3D90 - 0x3D97 : palette metadata
|
| 28 |
+
/// 0x3D98 : render lock flag
|
| 29 |
+
/// 0x3D9C - 0x3DA7 : three layer object pointers (DisplayGfx vtable 0x664144)
|
| 30 |
+
/// 0x3DA8 - 0x3DD3 : DisplayGfx vtable ptr, layer config
|
| 31 |
+
/// 0x3DD4 - 0x4DD3 : sprite/bitmap table (1024 entries)
|
| 32 |
+
/// 0x4DD4 - 0x4DF3 : sprite table metadata
|
| 33 |
+
/// 0x4DF4 - 0x14DF3: color_add_table (256 × 256 additive mixing LUT)
|
| 34 |
+
/// 0x14DF4- 0x24DF3: color_blend_table (256 × 256 gamma-corrected blend LUT)
|
| 35 |
+
/// 0x24DF4- 0x24E27: tail fields (blend mode flag, object vector)
|
| 36 |
+
/// ```
|
| 37 |
#[repr(C)]
|
| 38 |
pub struct DisplayGfx {
|
| 39 |
+
// =========================================================================
|
| 40 |
+
// DisplayBase (0x0000 - 0x355F)
|
| 41 |
+
// =========================================================================
|
| 42 |
+
/// 0x0000: DisplayBase fields (vtable, sprite cache, slot table, etc.)
|
| 43 |
+
pub base: DisplayBase,
|
| 44 |
+
|
| 45 |
+
// =========================================================================
|
| 46 |
+
// Display dimensions and clip rect (0x3560 - 0x357F)
|
| 47 |
+
// =========================================================================
|
| 48 |
+
/// 0x3560: Camera X offset (pixels). DDDisplay methods add this to coordinates.
|
| 49 |
+
pub camera_x: i32,
|
| 50 |
+
/// 0x3564: Camera Y offset (pixels).
|
| 51 |
+
pub camera_y: i32,
|
| 52 |
+
/// 0x3568: Unknown (set to 0 in InitDisplayFinal)
|
| 53 |
+
pub _unknown_3568: u32,
|
| 54 |
+
/// 0x356C: Unknown (set from FUN_00541340 result in InitDisplayFinal)
|
| 55 |
+
pub _unknown_356c: u32,
|
| 56 |
+
/// 0x3570: Unknown (set to 0 in InitDisplayFinal)
|
| 57 |
+
pub _unknown_3570: u32,
|
| 58 |
+
/// 0x3574: Unknown (set to 0 in DDDisplay__Init)
|
| 59 |
+
pub _unknown_3574: u32,
|
| 60 |
+
/// 0x3578: Window handle (HWND), used for MoveWindow in DDDisplay__Init
|
| 61 |
+
pub hwnd: u32,
|
| 62 |
+
/// 0x357C: Unknown
|
| 63 |
+
pub _unknown_357c: u32,
|
| 64 |
+
|
| 65 |
+
// =========================================================================
|
| 66 |
+
// Bitmap/sprite storage (0x3580 - 0x358B)
|
| 67 |
+
// =========================================================================
|
| 68 |
+
/// 0x3580: Bitmap vector pointer (init 0)
|
| 69 |
+
pub bitmap_ptr: u32,
|
| 70 |
+
/// 0x3584: Bitmap vector end (init 0)
|
| 71 |
+
pub bitmap_end: u32,
|
| 72 |
+
/// 0x3588: Bitmap vector capacity (init 0)
|
| 73 |
+
pub bitmap_capacity: u32,
|
| 74 |
+
|
| 75 |
+
// =========================================================================
|
| 76 |
+
// Palette entry table (0x358C - 0x3D8F)
|
| 77 |
+
// =========================================================================
|
| 78 |
+
/// 0x358C: Palette entry count or lead byte
|
| 79 |
+
pub _unknown_358c: u8,
|
| 80 |
+
/// 0x358D - 0x398C: Palette entries (256 × 4 bytes = 0x400 bytes).
|
| 81 |
+
/// Each entry is 4 bytes (R, G, B, flags?). Entry 255 (0x3989) = white.
|
| 82 |
+
pub palette_entries: [u8; 0x400],
|
| 83 |
+
/// 0x398D - 0x3D8F: Unknown region between palette entries and palette metadata
|
| 84 |
+
pub _unknown_398d: [u8; 0x3D90 - 0x398D],
|
| 85 |
+
|
| 86 |
+
// =========================================================================
|
| 87 |
+
// Palette metadata and render state (0x3D90 - 0x3D97)
|
| 88 |
+
// =========================================================================
|
| 89 |
+
/// 0x3D90: Palette entry count (init 0x100 = 256)
|
| 90 |
+
pub palette_count: u32,
|
| 91 |
+
/// 0x3D94: Unknown (init 0xFFFFFFFF)
|
| 92 |
+
pub _unknown_3d94: u32,
|
| 93 |
+
|
| 94 |
+
// =========================================================================
|
| 95 |
+
// Render state and layer pointers (0x3D98 - 0x3DD3)
|
| 96 |
+
// =========================================================================
|
| 97 |
+
/// 0x3D98: Render lock flag. Set during rendering, cleared by FlushRender.
|
| 98 |
+
pub render_lock: u32,
|
| 99 |
+
/// 0x3D9C: Layer 0 pointer — 0x4C-byte object with DisplayGfx vtable (0x664144).
|
| 100 |
+
/// Allocated and initialized in DDDisplay__Init.
|
| 101 |
+
pub layer_0: *mut c_void,
|
| 102 |
+
/// 0x3DA0: Layer 1 pointer (same type as layer_0)
|
| 103 |
+
pub layer_1: *mut c_void,
|
| 104 |
+
/// 0x3DA4: Layer 2 pointer (same type, uses BitGrid__Init)
|
| 105 |
+
pub layer_2: *mut c_void,
|
| 106 |
+
/// 0x3DA8: DisplayGfx vtable pointer (0x664144). Set in constructor.
|
| 107 |
+
pub displaygfx_vtable: *const c_void,
|
| 108 |
+
/// 0x3DAC: Layer active flag (init 1)
|
| 109 |
+
pub layer_active: u32,
|
| 110 |
+
/// 0x3DB0: Unknown (init 0)
|
| 111 |
+
pub _unknown_3db0: u32,
|
| 112 |
+
/// 0x3DB4: Bit depth (init 8 in constructor — 8bpp paletted mode)
|
| 113 |
+
pub bit_depth: u32,
|
| 114 |
+
/// 0x3DB8 - 0x3DD3: Unknown fields (all init 0 in constructor)
|
| 115 |
+
pub _unknown_3db8: [u8; 0x3DD4 - 0x3DB8],
|
| 116 |
+
|
| 117 |
+
// =========================================================================
|
| 118 |
+
// Sprite/bitmap table (0x3DD4 - 0x4DD7)
|
| 119 |
+
// =========================================================================
|
| 120 |
+
/// 0x3DD4: Sprite table — 1024 DWORD entries, zeroed in DDDisplay__Init.
|
| 121 |
+
/// Used for tracking loaded sprites/bitmaps by ID.
|
| 122 |
+
pub sprite_table: [u32; 0x400],
|
| 123 |
+
/// 0x4DD4: Sprite table metadata field 1 (init 0)
|
| 124 |
+
pub sprite_meta_0: u32,
|
| 125 |
+
/// 0x4DD8: Sprite table metadata field 2 (init 0)
|
| 126 |
+
pub sprite_meta_1: u32,
|
| 127 |
+
/// 0x4DDC - 0x4DF3: Unknown gap
|
| 128 |
+
pub _unknown_4ddc: [u8; 0x4DF4 - 0x4DDC],
|
| 129 |
+
|
| 130 |
+
// =========================================================================
|
| 131 |
+
// Color mixing lookup tables (0x4DF4 - 0x24DF3)
|
| 132 |
+
// =========================================================================
|
| 133 |
+
/// 0x4DF4: Additive color mixing LUT (256 × 256 = 0x10000 bytes).
|
| 134 |
+
/// Maps (color_a, color_b) → blended palette index using additive saturation.
|
| 135 |
+
/// Built by DDGame__InitDisplayFinal (0x56A830).
|
| 136 |
+
pub color_add_table: [u8; 0x10000],
|
| 137 |
+
/// 0x14DF4: Gamma-corrected blend LUT (256 × 256 = 0x10000 bytes).
|
| 138 |
+
/// Uses gamma-space blending via sqrt approximation.
|
| 139 |
+
/// Built by DDGame__InitDisplayFinal (0x56A830).
|
| 140 |
+
pub color_blend_table: [u8; 0x10000],
|
| 141 |
+
|
| 142 |
+
// =========================================================================
|
| 143 |
+
// Tail fields (0x24DF4 - 0x24E27)
|
| 144 |
+
// =========================================================================
|
| 145 |
+
/// 0x24DF4: Blend mode flag. Controls color distance weighting in
|
| 146 |
+
/// InitDisplayFinal (1 = reduced red weight, else normal).
|
| 147 |
+
pub blend_mode_flag: u32,
|
| 148 |
+
/// 0x24DF8 - 0x24E07: Object vector (std::vector-like).
|
| 149 |
+
/// Holds palette/display objects pushed during DDDisplay__Init.
|
| 150 |
+
pub object_vector_start: u32,
|
| 151 |
+
/// 0x24DFC: Vector data pointer
|
| 152 |
+
pub object_vector_ptr: u32,
|
| 153 |
+
/// 0x24E00: Vector end pointer
|
| 154 |
+
pub object_vector_end: u32,
|
| 155 |
+
/// 0x24E04: Vector capacity pointer
|
| 156 |
+
pub object_vector_cap: u32,
|
| 157 |
+
/// 0x24E08 - 0x24E27: Remaining tail (0x20 bytes)
|
| 158 |
+
pub _tail: [u8; 0x24E28 - 0x24E08],
|
| 159 |
}
|
| 160 |
|
| 161 |
const _: () = assert!(core::mem::size_of::<DisplayGfx>() == 0x24E28);
|