paavohtl Claude Opus 4.6 (1M context) commited on
Commit
e8a34a7
·
1 Parent(s): dd5434f

feat: port DDDisplay::GetDimensions to Rust, hook via vtable_replace

Browse files

First DDDisplay vtable method ported to Rust. Reads display_width/height
from DisplayBase and writes to output pointers. Hooked via vtable_replace
on slot 1 of the DDDisplay vtable (0x66A218).

FlushRender (slot 26) attempted but reverted — DDDisplayWrapper methods
use a non-standard fastcall convention (EDX = result pointer) that the
thiscall bind wrappers can't handle. Documented for future work.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>

crates/openwa-core/src/display/dd_display.rs CHANGED
@@ -270,3 +270,33 @@ pub struct DDDisplayVtable {
270
 
271
  // Generate calling wrappers: DDDisplay::set_layer_color(), etc.
272
  bind_DDDisplayVtable!(DDDisplay, vtable);
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
270
 
271
  // Generate calling wrappers: DDDisplay::set_layer_color(), etc.
272
  bind_DDDisplayVtable!(DDDisplay, vtable);
273
+
274
+ // =========================================================================
275
+ // Ported DDDisplay vtable methods
276
+ // =========================================================================
277
+
278
+ use super::gfx::DisplayGfx;
279
+
280
+ /// Port of DDDisplay::GetDimensions (vtable slot 1, 0x56A460).
281
+ ///
282
+ /// Reads display_width/display_height from DisplayBase and writes them
283
+ /// to the output pointers.
284
+ ///
285
+ /// # Safety
286
+ /// `this` must be a valid `*mut DDDisplay` (actually a `*mut DisplayGfx`).
287
+ pub unsafe extern "thiscall" fn get_dimensions(
288
+ this: *mut DDDisplay,
289
+ out_w: *mut u32,
290
+ out_h: *mut u32,
291
+ ) {
292
+ let gfx = this as *mut DisplayGfx;
293
+ *out_w = (*gfx).base.display_width;
294
+ *out_h = (*gfx).base.display_height;
295
+ }
296
+
297
+ // FlushRender (vtable slot 26, 0x56A580) — NOT YET PORTED.
298
+ //
299
+ // Calls DDDisplayWrapper::unlock_surface_write and ::get_renderer_surface,
300
+ // which use a non-standard fastcall convention (EDX = result pointer, not
301
+ // standard thiscall). Needs a naked asm bridge or corrected vtable typing
302
+ // for the DDDisplayWrapper methods before this can be ported.
crates/openwa-dll/src/replacements/display.rs CHANGED
@@ -7,9 +7,11 @@
7
 
8
  use crate::log_line;
9
  use openwa_core::address::va;
 
10
  use openwa_core::display::{DisplayBase, SpriteBufferCtrl, SpriteCacheWrapper};
11
  use openwa_core::rebase::rb;
12
  use openwa_core::vtable::patch_vtable;
 
13
  use openwa_core::wa_alloc::wa_free;
14
 
15
  /// The _purecall function address (calls abort).
@@ -76,6 +78,12 @@ pub fn install() -> Result<(), String> {
76
  *vt = headless_destructor as *const () as u32;
77
  let _ = log_line("[Display] Headless: patched slot 0 (destructor) → Rust");
78
  })?;
 
 
 
 
 
 
79
  }
80
 
81
  Ok(())
 
7
 
8
  use crate::log_line;
9
  use openwa_core::address::va;
10
+ use openwa_core::display::dd_display::{self, DDDisplayVtable};
11
  use openwa_core::display::{DisplayBase, SpriteBufferCtrl, SpriteCacheWrapper};
12
  use openwa_core::rebase::rb;
13
  use openwa_core::vtable::patch_vtable;
14
+ use openwa_core::vtable_replace;
15
  use openwa_core::wa_alloc::wa_free;
16
 
17
  /// The _purecall function address (calls abort).
 
78
  *vt = headless_destructor as *const () as u32;
79
  let _ = log_line("[Display] Headless: patched slot 0 (destructor) → Rust");
80
  })?;
81
+
82
+ // Patch DDDisplay vtable (0x66A218): replace ported methods with Rust.
83
+ vtable_replace!(DDDisplayVtable, va::DD_DISPLAY_VTABLE, {
84
+ get_dimensions => dd_display::get_dimensions,
85
+ })?;
86
+ let _ = log_line("[Display] DDDisplay: patched get_dimensions → Rust");
87
  }
88
 
89
  Ok(())