Skip to content

Commit

Permalink
add source engine allocator
Browse files Browse the repository at this point in the history
  • Loading branch information
catornot committed Jan 18, 2024
1 parent 17b36f1 commit 46e2493
Show file tree
Hide file tree
Showing 4 changed files with 116 additions and 5 deletions.
13 changes: 8 additions & 5 deletions src/high/convars.rs
Original file line number Diff line number Diff line change
Expand Up @@ -368,18 +368,21 @@ impl ConVarStruct {
///
/// only safe on the titanfall thread
pub fn get_value_i32(&self) -> i32 {
let value = &self.inner.m_Value;
self.inner.m_Value.m_nValue
}

value.m_nValue
/// get the value as a bool
///
/// only safe on the titanfall thread
pub fn get_value_bool(&self) -> bool {
self.inner.m_Value.m_nValue != 0
}

/// get the value as a f32
///
/// only safe on the titanfall thread
pub fn get_value_f32(&self) -> f32 {
let value = &self.inner.m_Value;

value.m_fValue
self.inner.m_Value.m_fValue
}

// todo: add exclusive access set_value s aka &mut self
Expand Down
1 change: 1 addition & 0 deletions src/mid/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -4,5 +4,6 @@ pub mod concommands;
pub mod convars;
pub mod engine;
pub mod northstar;
pub mod source_alloc;
pub mod squirrel;
pub mod utils;
2 changes: 2 additions & 0 deletions src/mid/northstar.rs
Original file line number Diff line number Diff line change
Expand Up @@ -54,4 +54,6 @@ pub unsafe fn init_northstar_interfaces(dll_ptr: HMODULE, plugin_data: &PluginNo
},
})
.expect("northstar interfaces don't exist????????");

super::source_alloc::SOURCE_ALLOC.init();
}
105 changes: 105 additions & 0 deletions src/mid/source_alloc.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,105 @@
use std::{
alloc::GlobalAlloc,
ffi::{c_char, c_void},
};

use once_cell::sync::OnceCell;
use windows::{
core::PCSTR,
Win32::System::LibraryLoader::{GetModuleHandleA, GetProcAddress},
};

use crate::{create_external_interface, high::UnsafeHandle};

type CreateGlobalMemAlloc = extern "C" fn() -> *const IMemAlloc;

pub static SOURCE_ALLOC: SourceAlloc = SourceAlloc(OnceCell::new());

pub struct SourceAlloc(OnceCell<UnsafeHandle<&'static IMemAlloc>>);

impl SourceAlloc {
pub(crate) fn init(&self) {
let create_global_mem_alloc = unsafe {
std::mem::transmute::<_, CreateGlobalMemAlloc>(
GetProcAddress(
GetModuleHandleA(PCSTR("tier0.dll\0".as_ptr())).expect("couldn't find tier0"),
PCSTR("CreateGlobalMemAlloc\0".as_ptr()),
)
.expect("couldn't find CreateGlobalMemAlloc"),
)
};
_ = self.0.set(unsafe {
UnsafeHandle::new(
create_global_mem_alloc()
.as_ref()
.expect("IMemAlloc is invalid"),
)
})
}
}

unsafe impl GlobalAlloc for SourceAlloc {
unsafe fn alloc(&self, layout: std::alloc::Layout) -> *mut u8 {
debug_assert!(
self.0.get().is_some(),
"cannot use SourceAlloc before entry::new"
);
unsafe { self.0.get_unchecked().copy().Alloc(layout.size()) as *mut u8 }
}

unsafe fn dealloc(&self, ptr: *mut u8, _layout: std::alloc::Layout) {
debug_assert!(
self.0.get().is_some(),
"cannot use SourceAlloc before entry::new"
);
unsafe { self.0.get_unchecked().copy().Free(ptr as *mut c_void) }
}

unsafe fn realloc(
&self,
ptr: *mut u8,
_layout: std::alloc::Layout,
new_size: usize,
) -> *mut u8 {
debug_assert!(
self.0.get().is_some(),
"cannot use SourceAlloc before entry::new"
);
unsafe {
self.0
.get_unchecked()
.copy()
.Realloc(ptr as *mut c_void, new_size) as *mut u8
}
}
}

create_external_interface! {
pub IMemAlloc + IMemAllocMod => {
pub(self) fn unk0() -> ();
pub fn Alloc(Size: usize) -> *const c_void;
pub(self) fn unk2() -> ();
pub fn Realloc(Mem: *mut c_void, Size: usize) -> *const c_void;
pub(self) fn unk4() -> ();
pub fn Free(Mem: *mut c_void) -> ();
pub(self) fn unk6() -> ();
pub(self) fn unk7() -> ();
pub fn GetSize(Mem: *const c_void) -> usize;
pub(self) fn unk9() -> ();
pub(self) fn unk10() -> ();
pub(self) fn unk11() -> ();
pub(self) fn unk12() -> ();
pub(self) fn unk13() -> ();
pub(self) fn unk14() -> ();
pub(self) fn unk15() -> ();
pub(self) fn unk16() -> ();
pub(self) fn unk17() -> ();
pub fn DumpStats() -> ();
pub fn DumpStatsFileBase(FileBase: *const c_char) -> ();
pub(self) fn unk19() -> ();
pub(self) fn unk20() -> ();
pub(self) fn unk21() -> ();
pub(self) fn unk22() -> ();
pub fn heapchk() -> i32;
}
}

0 comments on commit 46e2493

Please sign in to comment.