paavohtl commited on
Commit
e7c9ec5
Β·
1 Parent(s): 8300566

refactor: type DisplayGfx hook_vec fields + add destructor addresses

Browse files

Renames the four `object_vector_*` fields at +0x24DF8..+0x24E07 to
`hook_vec_proxy/first/last/end` and documents the underlying MSVC 2005
`std::vector<FramePostProcessHook*>` layout. The proxy field at offset
0 (the iterator-debug `_Container_proxy*`) was previously labelled as
the start pointer, a latent off-by-one. The pointee type is left as
`*mut u8` until the FramePostProcessHook struct lands.

Adds new `define_addresses!` entries to `display/gfx.rs` for the
destructor port:

- DISPLAY_GFX_DESTRUCTOR (0x569CE0, slot 0 thunk)
- DISPLAY_GFX_DESTRUCTOR_IMPL (0x56A010, body)
- DISPLAY_GFX_FREE_LAYER_SPRITE_TABLE (0x56A280)
- DISPLAY_GFX_DISPATCH_FRAME_POST_PROCESS_HOOKS (0x56CDB0)
- TILE_BITMAP_SET_DESTRUCTOR (0x569BC0)
- DISPLAY_BASE_DESTRUCTOR_IMPL (0x522F60, parent dtor)

Re-exported via `mod va`.

Pre-work for porting DisplayGfx::Destructor (slot 0). Note: the plan's
`DD_DISPLAY_VTABLE` constant turned out to be bogus β€” the destructor's
self-rebind at 0x56A030 writes the most-derived DisplayGfx vtable
(0x66A218), the standard MSVC C++ destructor pattern. There is no
separate "DDDisplay" parent vtable; the Ghidra `DDDisplay_vtable`
label is just the legacy name for `DisplayGfxVtable` itself.

crates/openwa-core/src/address.rs CHANGED
@@ -82,6 +82,11 @@ pub mod va {
82
  };
83
  pub use crate::render::display::base::DISPLAY_BASE_VTABLE;
84
  pub use crate::render::display::context::{RenderContextVtable, RENDER_CONTEXT_VTABLE};
 
 
 
 
 
85
  pub use crate::render::display::palette::PALETTE_VTABLE;
86
  pub use crate::render::display::vtable::DISPLAY_GFX_VTABLE;
87
  pub use crate::task::game_task::SOUND_EMITTER_VTABLE;
 
82
  };
83
  pub use crate::render::display::base::DISPLAY_BASE_VTABLE;
84
  pub use crate::render::display::context::{RenderContextVtable, RENDER_CONTEXT_VTABLE};
85
+ pub use crate::render::display::gfx::{
86
+ DISPLAY_BASE_DESTRUCTOR_IMPL, DISPLAY_GFX_DESTRUCTOR, DISPLAY_GFX_DESTRUCTOR_IMPL,
87
+ DISPLAY_GFX_DISPATCH_FRAME_POST_PROCESS_HOOKS, DISPLAY_GFX_FREE_LAYER_SPRITE_TABLE,
88
+ TILE_BITMAP_SET_DESTRUCTOR,
89
+ };
90
  pub use crate::render::display::palette::PALETTE_VTABLE;
91
  pub use crate::render::display::vtable::DISPLAY_GFX_VTABLE;
92
  pub use crate::task::game_task::SOUND_EMITTER_VTABLE;
crates/openwa-core/src/render/display/gfx.rs CHANGED
@@ -3,6 +3,43 @@ use super::vtable::DisplayGfxVtable;
3
  use crate::bitgrid::{BitGrid, BitGridBaseVtable, DisplayBitGrid};
4
  use crate::render::sprite::sprite::{CBitmap, LayerSprite};
5
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
6
  /// DisplayGfx β€” full display/graphics subsystem (derived from DisplayBase).
7
  ///
8
  /// Constructor: DisplayGfx__Constructor (0x569C10), stdcall(this) β†’ DisplayGfx*.
@@ -174,15 +211,29 @@ pub struct DisplayGfx {
174
  /// 0x24DF4: Blend mode flag. Controls color distance weighting in
175
  /// InitDisplayFinal (1 = reduced red weight, else normal).
176
  pub blend_mode_flag: u32,
177
- /// 0x24DF8 - 0x24E07: Object vector (std::vector-like).
178
- /// Holds palette/display objects pushed during DisplayGfx__Init.
179
- pub object_vector_start: u32,
180
- /// 0x24DFC: Vector data pointer
181
- pub object_vector_ptr: u32,
182
- /// 0x24E00: Vector end pointer
183
- pub object_vector_end: u32,
184
- /// 0x24E04: Vector capacity pointer
185
- pub object_vector_cap: u32,
 
 
 
 
 
 
 
 
 
 
 
 
 
 
186
  /// 0x24E08 - 0x24E27: Remaining tail (0x20 bytes)
187
  pub _tail: [u8; 0x24E28 - 0x24E08],
188
  }
 
3
  use crate::bitgrid::{BitGrid, BitGridBaseVtable, DisplayBitGrid};
4
  use crate::render::sprite::sprite::{CBitmap, LayerSprite};
5
 
6
+ crate::define_addresses! {
7
+ class "DisplayGfx" {
8
+ /// `DisplayGfx::Destructor` (vtable slot 0 thunk, 0x569CE0) β€” thiscall.
9
+ /// Calls `DestructorImpl` then `_free(this)` if `flags & 1`.
10
+ fn/Thiscall DISPLAY_GFX_DESTRUCTOR = 0x0056_9CE0;
11
+ /// `DisplayGfx::DestructorImpl` (0x56A010) β€” fastcall(ECX=this).
12
+ /// The actual cleanup body. Wrapped in C++ SEH; rebinds vtable to
13
+ /// the most-derived DisplayGfx vtable (standard MSVC pattern), then
14
+ /// frees layer sprites, tile bitmap set, CBitmap vec, layers, hook
15
+ /// vec, embedded BitGrid, and chains to `DisplayBase::Destructor`.
16
+ fn/Fastcall DISPLAY_GFX_DESTRUCTOR_IMPL = 0x0056_A010;
17
+ /// `DisplayGfx::FreeLayerSpriteTable` (0x56A280) β€” fastcall(ECX=this).
18
+ /// Iterates `sprite_table[1..0x3FF]` at `+0x3DD4` and frees each
19
+ /// `LayerSprite` + its `frame_array`.
20
+ fn/Fastcall DISPLAY_GFX_FREE_LAYER_SPRITE_TABLE = 0x0056_A280;
21
+ /// `DisplayGfx::DispatchFramePostProcessHooks` (0x56CDB0) β€” per-frame
22
+ /// poll/dispatch over the FramePostProcessHook* vector at `+0x24DF8`.
23
+ /// Called from `RenderFrame_Maybe` (0x56E06C) which is still bridged.
24
+ fn/Thiscall DISPLAY_GFX_DISPATCH_FRAME_POST_PROCESS_HOOKS = 0x0056_CDB0;
25
+ }
26
+
27
+ class "TileBitmapSet" {
28
+ /// `TileBitmapSet::Destructor` (0x569BC0) β€” fastcall(ECX=this).
29
+ /// Iterates `bitmap_ptrs[0..count]`, calls `vtable[0](1)` on each,
30
+ /// frees `bitmap_ptrs`.
31
+ fn/Fastcall TILE_BITMAP_SET_DESTRUCTOR = 0x0056_9BC0;
32
+ }
33
+
34
+ class "DisplayBase" {
35
+ /// `DisplayBase::Destructor` (0x522F60) β€” thiscall(ECX=this).
36
+ /// Parent class destructor; rebinds vtable to DisplayBase
37
+ /// (`0x6645F8`) and tears down sprite cache, palette slots, etc.
38
+ /// Chained from `DisplayGfx::DestructorImpl` as the final step.
39
+ fn/Thiscall DISPLAY_BASE_DESTRUCTOR_IMPL = 0x0052_2F60;
40
+ }
41
+ }
42
+
43
  /// DisplayGfx β€” full display/graphics subsystem (derived from DisplayBase).
44
  ///
45
  /// Constructor: DisplayGfx__Constructor (0x569C10), stdcall(this) β†’ DisplayGfx*.
 
211
  /// 0x24DF4: Blend mode flag. Controls color distance weighting in
212
  /// InitDisplayFinal (1 = reduced red weight, else normal).
213
  pub blend_mode_flag: u32,
214
+ /// 0x24DF8 - 0x24E07: `std::vector<FramePostProcessHook*>` (16-byte
215
+ /// MSVC 2005 layout with the iterator-debug proxy at offset 0).
216
+ ///
217
+ /// ```text
218
+ /// +0x00 (= +0x24DF8) _Myproxy : *const c_void β€” debug iterator container proxy
219
+ /// +0x04 (= +0x24DFC) _Myfirst : *mut *mut FramePostProcessHook β€” start
220
+ /// +0x08 (= +0x24E00) _Mylast : *mut *mut FramePostProcessHook β€” end
221
+ /// +0x0C (= +0x24E04) _Myend : *mut *mut FramePostProcessHook β€” capacity end
222
+ /// ```
223
+ ///
224
+ /// Populated during `DisplayGfx::Init` with the registered post-process
225
+ /// hooks (the only known shipping entry is `ScreenshotHook`, which writes
226
+ /// the rendered frame as a numbered PNG when a screenshot is requested).
227
+ /// Iterated every frame by `DispatchFramePostProcessHooks` (0x56CDB0).
228
+ /// Until the FramePostProcessHook type lands the entry pointer is left
229
+ /// as `*mut u8`.
230
+ pub hook_vec_proxy: *const core::ffi::c_void,
231
+ /// 0x24DFC: hook vec `_Myfirst` β€” start pointer.
232
+ pub hook_vec_first: *mut *mut u8,
233
+ /// 0x24E00: hook vec `_Mylast` β€” end pointer.
234
+ pub hook_vec_last: *mut *mut u8,
235
+ /// 0x24E04: hook vec `_Myend` β€” capacity end pointer.
236
+ pub hook_vec_end: *mut *mut u8,
237
  /// 0x24E08 - 0x24E27: Remaining tail (0x20 bytes)
238
  pub _tail: [u8; 0x24E28 - 0x24E08],
239
  }