paavohtl Claude Opus 4.6 (1M context) commited on
Commit
eccd564
·
1 Parent(s): 547a858

feat: map DisplayGfx internal fields and expose DisplayBase dimensions

Browse files

Map ~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..0x3560: remaining padding to fill 0x3560 total
56
- pub _pad_3540: [u8; 0x3560 - 0x3540],
 
 
 
 
 
 
 
 
 
 
 
 
 
 
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
- /// DisplayGfx vtable (0x66A218) and initializes display-specific fields.
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
- /// OPAQUE: Internal layout not yet mapped.
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
14
  #[repr(C)]
15
  pub struct DisplayGfx {
16
- pub vtable: *mut u8,
17
- pub _unknown_004: [u8; 0x24E28 - 4],
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
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);