use std::{borrow::Cow, ptr::NonNull, sync::atomic::AtomicI32};
use shared::{FromStatic, OwnedPtr, Subclass, Superclass, UnknownPtr, UnknownStruct};
use crate::{DLVector, dlkr::DLAllocator, dlut::DLFixedVector, rva, sprj::SprjScaleformValue};
#[repr(C)]
pub struct NewMenuSystem {
pub vftable: usize,
_array_menu_window_job_1: usize,
_unk10: DLFixedVector<u64, 4>,
pub windows: DLFixedVector<OwnedPtr<MenuWindow>, 16>,
_array_menu_window_job_2: usize,
_unkd8: u64,
_menu_window_job_1: UnknownPtr,
_menu_window_job_2: UnknownPtr,
_menu_window_job_3: UnknownPtr,
_menu_window_job_4: UnknownPtr,
finalize_callback_job: UnknownPtr,
_unk108: u64,
_unk110: u64,
_unk118: u64,
_unk120: u64,
_menu_window_job_5: UnknownPtr,
_unk130: [u8; 0x38],
_unk168: u64,
_unk170: DLFixedVector<UnknownPtr, 8>,
_unk1c0: u32,
_unk1c4: u32,
_unk1c8: u32,
_unk1d0: u64,
_unk1d8: u16,
_unk1da: u8,
_unk1e0: UnknownStruct<0x40e0>,
_unk3428: UnknownStruct<0xc3428>,
_unkc76e8: [u8; 0x6c1c8],
}
impl NewMenuSystem {
pub fn is_menu_open(&self) -> bool {
!self.finalize_callback_job.is_null()
}
}
impl FromStatic for NewMenuSystem {
fn name() -> Cow<'static, str> {
"NewMenuSystem".into()
}
fn instance_ptr() -> fromsoftware_shared::InstanceResult<*mut Self> {
unsafe { shared::load_static_indirect(rva::get().app_menu_new_menu_system_ptr) }
}
}
#[repr(C)]
#[derive(Superclass)]
pub struct MenuWindow {
_vftable: usize,
pub ref_count: AtomicI32,
_unk10: u64,
_unk18: [u8; 0x28],
_unk40: u64,
_unk48: [u8; 0x88],
_unkd0: u64,
_unkd8: [u8; 0x38],
_unk110: u64,
_unk118: [u8; 0x38],
_unk150: u64,
_scene_obj_proxy_1: SceneObjProxy,
_scene_obj_proxy_2: SceneObjProxy,
_unk218: u64,
_allocator: &'static DLAllocator,
_unk228: u64,
_unk230: u64,
_unk238: u64,
_unk240: DLVector<u8>,
_component_holder: ComponentProxy,
_scaleform_value: SprjScaleformValue,
_scene_obj_proxy_3: SceneObjProxy,
_scene_obj_proxy_4: SceneObjProxy,
_scene_obj_proxy_5: SceneObjProxy,
_scene_obj_proxy_6: SceneObjProxy,
_unk428: u8,
_scene_obj_proxy_7: SceneObjProxy,
_unk4a0: [u8; 0x608],
_unkaa8: u64,
_unkab0: u64,
}
#[repr(C)]
#[derive(Superclass)]
#[superclass(children(SceneObjProxy))]
pub struct ComponentProxy {
_vftable: usize,
_unk08: NonNull<ComponentProxy>,
_unk10: NonNull<ComponentProxy>,
_unk18: NonNull<ComponentProxy>,
}
#[repr(C)]
#[derive(Subclass)]
pub struct SceneObjProxy {
pub component_proxy: ComponentProxy,
_scene_proxy: UnknownPtr,
pub scaleform_value: SprjScaleformValue,
}
#[cfg(test)]
mod test {
use super::*;
#[test]
fn proper_sizes() {
assert_eq!(0x20, size_of::<ComponentProxy>());
assert_eq!(0x60, size_of::<SceneObjProxy>());
assert_eq!(0xab8, size_of::<MenuWindow>());
assert_eq!(0x1338b0, size_of::<NewMenuSystem>());
}
}