use std::{borrow::Cow, ptr::NonNull};
use shared::{FromStatic, Subclass, Superclass, UnknownStruct};
use super::{GaitemSelectBaseMenu, GaitemSelectMenu};
use crate::{DLVector, dlut::DLFixedVector, rva, sprj::SprjScaleformValue};
#[repr(C)]
pub struct NewMenuSystem {
_vftable: usize,
_array_menu_window_job_1: usize,
_unk10: [u8; 0x30],
pub windows: DLFixedVector<NonNull<MenuWindow>, 8>,
_menu_window_job_1: usize,
_unk98: u64,
finalize_callback_job: usize,
_unka8: u64,
_unkb0: u64,
_unkb8: u64,
_unkc0: u64,
_menu_window_job_2: usize,
_unkd0: [u8; 0x18],
_callback: usize,
_finalize_callback_jobs: DLFixedVector<usize, 8>,
_unk140: bool,
_unk144: u32,
_unk148: u32,
_unk150: u64,
_unk158: u16,
_unk160: UnknownStruct<0x2ec8>,
_fe_emergency_notice: usize,
_fe_summon_message: usize,
_fade_screen: usize,
_fe_view: usize,
_unk3048: [u8; 0x28],
_unk3070: u64,
_array_menu_window_job_2: usize,
_unk3080: u8,
_unk3081: u8,
_unk3082: u8,
_unk3084: u16,
_unk3088: u64,
_unk3090: u32,
}
impl NewMenuSystem {
pub fn is_menu_open(&self) -> bool {
self.finalize_callback_job != 0
}
pub fn windows(&self) -> impl Iterator<Item = &MenuWindow> {
self.windows.iter().map(|p| unsafe { p.as_ref() })
}
}
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)]
#[superclass(children(GaitemSelectBaseMenu, GaitemSelectMenu))]
pub struct MenuWindow {
pub vftable: usize,
_unk08: u32,
_fix_order_job_sequence: usize,
_unk18: [u8; 0x28],
_unk40: u64,
_scene_obj_modifiers: DLFixedVector<usize, 8>,
_callback1: MenuWindowCallback,
_callback2: MenuWindowCallback,
_unkd8: SceneObjProxy,
_unk138: SceneObjProxy,
_unk198: u64,
_unk1a0: DLVector<u64>,
_unk1c0: DLVector<u64>,
_component_holder: usize,
_unk1e8: [u8; 0x18],
_unk200: SprjScaleformValue,
_unk238: SceneObjProxy,
_unk298: SceneObjProxy,
_unk2f8: SceneObjProxy,
_unk358: u8,
_unk360: SceneObjProxy,
_unk3c0: [u8; 0x608],
_unk9c8: u64,
_unk9d0: u64,
}
#[repr(C)]
pub struct MenuWindowCallback {
_vftable: usize,
pub menu_window: NonNull<MenuWindow>,
_unk10: [u8; 0x8],
_this: NonNull<MenuWindowCallback>,
}
#[repr(C)]
pub struct SceneObjProxy {
_vftable: usize,
_unk08: [u8; 0x18],
_scene_holder: usize,
pub scaleform_value: SprjScaleformValue,
}
#[cfg(test)]
mod test {
use super::*;
#[test]
fn proper_sizes() {
assert_eq!(0x60, size_of::<SceneObjProxy>());
assert_eq!(0x9d8, size_of::<MenuWindow>());
assert_eq!(0x3098, size_of::<NewMenuSystem>());
}
}