paavohtl Claude Opus 4.6 (1M context) commited on
Commit
96a786b
Β·
1 Parent(s): 17e3bdc

refactor: add WABox::from_value and struct constructors for DDKeyboard/Palette

Browse files

Add WABox::from_value(val) to allocate on WA's heap and write a
fully-initialized value in one step. Add DDKeyboard::new() and
Palette::new() that return Self with all fields set, replacing
multi-line alloc+field-write sequences with one-liners.

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

crates/openwa-core/src/ddkeyboard.rs CHANGED
@@ -41,3 +41,27 @@ pub struct DDKeyboard {
41
  }
42
 
43
  const _: () = assert!(core::mem::size_of::<DDKeyboard>() == 0x33C);
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
41
  }
42
 
43
  const _: () = assert!(core::mem::size_of::<DDKeyboard>() == 0x33C);
44
+
45
+ impl DDKeyboard {
46
+ /// Create a new DDKeyboard with inline construction (no native C++ ctor).
47
+ ///
48
+ /// All fields are zero-initialized, then known fields are set.
49
+ ///
50
+ /// # Safety
51
+ /// `vtable_addr` must be a valid rebased vtable pointer.
52
+ /// `input_ptr` must be the address of `GameInfo.input_state_f918`.
53
+ pub unsafe fn new(vtable_addr: u32, input_ptr: u32) -> Self {
54
+ Self {
55
+ vtable: vtable_addr as *mut u8,
56
+ game_info_input_ptr: input_ptr,
57
+ _field_008: 1,
58
+ _unknown_00c: [0; 8],
59
+ _field_014: 0,
60
+ _field_018: 0,
61
+ _unknown_01c: [0; 0x100],
62
+ key_state: [0; 256],
63
+ prev_state: [0; 256],
64
+ _unknown_31c: [0; 0x20],
65
+ }
66
+ }
67
+ }
crates/openwa-core/src/palette.rs CHANGED
@@ -36,6 +36,18 @@ pub struct PaletteVtable {
36
  }
37
 
38
  impl Palette {
 
 
 
 
 
 
 
 
 
 
 
 
39
  /// Vtable[4]: Reset palette state.
40
  pub unsafe fn reset(&mut self) { vcall!(self, reset) }
41
  /// Vtable[3]: Initialize palette.
 
36
  }
37
 
38
  impl Palette {
39
+ /// Create a new Palette with inline construction (no native C++ ctor).
40
+ ///
41
+ /// # Safety
42
+ /// `vtable_addr` must be a valid rebased vtable pointer.
43
+ pub unsafe fn new(vtable_addr: u32) -> Self {
44
+ Self {
45
+ vtable: vtable_addr as *const PaletteVtable,
46
+ _field_004: 0xFFFF_FFFF,
47
+ _unknown_008: [0; 0x20],
48
+ }
49
+ }
50
+
51
  /// Vtable[4]: Reset palette state.
52
  pub unsafe fn reset(&mut self) { vcall!(self, reset) }
53
  /// Vtable[3]: Initialize palette.
crates/openwa-core/src/wa_alloc.rs CHANGED
@@ -56,6 +56,26 @@ impl<T> WABox<T> {
56
  self.ptr.as_ptr()
57
  }
58
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
59
  /// Consume the box and return the raw pointer, relinquishing Rust ownership.
60
  ///
61
  /// The caller is now responsible for the memory β€” typically by storing the pointer
 
56
  self.ptr.as_ptr()
57
  }
58
 
59
+ /// Allocate space for `T` on WA's heap and write `val` into it.
60
+ ///
61
+ /// Equivalent to `alloc(size_of::<T>(), 0)` followed by `ptr::write(ptr, val)`.
62
+ /// The value is fully initialized on the stack first, then moved to the heap.
63
+ ///
64
+ /// # Safety
65
+ /// Must only be called from within the WA.exe process.
66
+ pub unsafe fn from_value(val: T) -> Self {
67
+ let size = core::mem::size_of::<T>() as u32;
68
+ let raw = wa_malloc(size);
69
+ if raw.is_null() {
70
+ panic!("wa_malloc({size}) returned null");
71
+ }
72
+ let ptr = raw as *mut T;
73
+ core::ptr::write(ptr, val);
74
+ Self {
75
+ ptr: core::ptr::NonNull::new_unchecked(ptr),
76
+ }
77
+ }
78
+
79
  /// Consume the box and return the raw pointer, relinquishing Rust ownership.
80
  ///
81
  /// The caller is now responsible for the memory β€” typically by storing the pointer
crates/openwa-wormkit/src/replacements/hardware_init.rs CHANGED
@@ -49,7 +49,7 @@ use openwa_core::ddgame_wrapper::DDGameWrapper;
49
  use openwa_core::ddkeyboard::DDKeyboard;
50
  use openwa_core::dddisplay::DDDisplay;
51
  use openwa_core::dssound::DSSound;
52
- use openwa_core::palette::{Palette, PaletteVtable};
53
  use openwa_core::input_ctrl::{InputCtrl, InputCtrlVtable};
54
  use openwa_core::game_timer::GameTimer;
55
  use openwa_core::game_stats::GameStats;
@@ -360,20 +360,14 @@ unsafe extern "cdecl" fn impl_init_hardware(
360
  }
361
 
362
  // ── DDKeyboard (inline construction) ──────────────────────────────────
363
- // WABox zeroes the first 0x31C bytes, covering key_state (+0x11C) and
364
- // prev_state (+0x21C) β€” no separate zeroing needed.
365
- let kb = WABox::<DDKeyboard>::alloc(0x33C, 0x31C).leak();
366
- (*kb).vtable = rb(va::DDKEYBOARD_VTABLE) as *mut u8;
367
- (*kb).game_info_input_ptr = &raw mut gi.input_state_f918 as u32;
368
- (*kb)._field_008 = 1;
369
- (*kb)._field_014 = 0;
370
- (*kb)._field_018 = 0;
371
  (*session).keyboard = kb;
372
 
373
  // ── Palette (inline construction) ─────────────────────────────────────
374
- let pal = WABox::<Palette>::alloc(0x28, 0).leak();
375
- (*pal).vtable = rb(va::PALETTE_VTABLE_MAYBE) as *const PaletteVtable;
376
- (*pal)._field_004 = 0xFFFF_FFFF;
377
  (*session).palette = pal;
378
 
379
  // ── DSSound ───────────────────────────────────────────────────────────
 
49
  use openwa_core::ddkeyboard::DDKeyboard;
50
  use openwa_core::dddisplay::DDDisplay;
51
  use openwa_core::dssound::DSSound;
52
+ use openwa_core::palette::Palette;
53
  use openwa_core::input_ctrl::{InputCtrl, InputCtrlVtable};
54
  use openwa_core::game_timer::GameTimer;
55
  use openwa_core::game_stats::GameStats;
 
360
  }
361
 
362
  // ── DDKeyboard (inline construction) ──────────────────────────────────
363
+ let kb = WABox::from_value(DDKeyboard::new(
364
+ rb(va::DDKEYBOARD_VTABLE),
365
+ &raw mut gi.input_state_f918 as u32,
366
+ )).leak();
 
 
 
 
367
  (*session).keyboard = kb;
368
 
369
  // ── Palette (inline construction) ─────────────────────────────────────
370
+ let pal = WABox::from_value(Palette::new(rb(va::PALETTE_VTABLE_MAYBE))).leak();
 
 
371
  (*session).palette = pal;
372
 
373
  // ── DSSound ───────────────────────────────────────────────────────────