refactor: add WABox::from_value and struct constructors for DDKeyboard/Palette
Browse filesAdd 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::
|
| 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 |
-
|
| 364 |
-
|
| 365 |
-
|
| 366 |
-
|
| 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::
|
| 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 βββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ
|