sekiro 0.13.0

Raw structures and bindings for From Software's title Sekiro: Shadows Die Twice
use std::{
    alloc::{GlobalAlloc, Layout},
    ptr::NonNull,
};

use vtable_rs::VPtr;

#[vtable_rs::vtable]
pub trait DLAllocatorVmt {
    fn destructor(&mut self, param_2: bool);

    fn unk08(&self);
    fn unk10(&self);
    fn unk18(&self);
    fn unk20(&self);
    fn unk28(&self);
    fn unk30(&self);
    fn unk38(&self);
    fn unk40(&self);

    fn allocate(&self, size: usize) -> *mut u8;

    fn allocate_aligned(&self, size: usize, alignment: usize) -> *mut u8;

    fn unk58(&self);
    fn unk60(&self);

    fn deallocate(&self, allocation: *mut u8);
}

pub struct DLAllocatorBase {
    pub vftable: VPtr<dyn DLAllocatorVmt, Self>,
}

#[repr(transparent)]
#[derive(Clone)]
pub struct DLAllocatorRef(NonNull<DLAllocatorBase>);

unsafe impl GlobalAlloc for DLAllocatorRef {
    unsafe fn alloc(&self, layout: Layout) -> *mut u8 {
        let allocator = self.0.as_ptr();
        unsafe { ((*allocator).vftable.allocate)(&mut *allocator, layout.size()) }
    }

    unsafe fn dealloc(&self, ptr: *mut u8, _layout: Layout) {
        let allocator = self.0.as_ptr();
        unsafe {
            ((*allocator).vftable.deallocate)(&mut *allocator, ptr);
        }
    }
}

impl From<NonNull<DLAllocatorBase>> for DLAllocatorRef {
    fn from(ptr: NonNull<DLAllocatorBase>) -> Self {
        Self(ptr)
    }
}