Skip to content

Commit

Permalink
Cleanup
Browse files Browse the repository at this point in the history
  • Loading branch information
Raytwo committed Apr 19, 2024
1 parent cc2a1d1 commit 759de6d
Show file tree
Hide file tree
Showing 3 changed files with 130 additions and 83 deletions.
4 changes: 2 additions & 2 deletions src/menu/config.rs
Original file line number Diff line number Diff line change
Expand Up @@ -187,9 +187,9 @@ pub trait ConfigBasicMenuItemCommandMethods {
}

extern "C" fn open_anime_all_ondispose(this: &mut ProcInst, _method_info: OptionalMethod) {
this.parent.get_class().get_virtual_method("OpenAnimeAll").map(|method| {
this.parent.as_ref().unwrap().get_class().get_virtual_method("OpenAnimeAll").map(|method| {
let open_anime_all = unsafe { std::mem::transmute::<_, extern "C" fn(&ProcInst, &MethodInfo)>(method.method_info.method_ptr) };
open_anime_all(this.parent, method.method_info);
open_anime_all(this.parent.as_ref().unwrap(), method.method_info);
});
}

Expand Down
101 changes: 20 additions & 81 deletions src/proc.rs
Original file line number Diff line number Diff line change
@@ -1,19 +1,28 @@
//! Methods and traits related to the [`ProcInst`] system.

use unity::prelude::*;
use std::cell::UnsafeCell;

pub mod desc;
use desc::*;

pub mod inst;
pub use inst::*;

#[repr(C)]
pub struct Proc;

impl Proc {
pub fn get_root_hi() -> &'static mut ProcInst {
unsafe { proc_getroothi(None) }
}
pub fn get_root_def() -> &'static mut ProcInst {
unsafe { proc_getrootdef(None) }
}

pub fn get_root_low() -> &'static mut ProcInst {
unsafe { proc_getrootlow(None) }
}

pub fn vsync(vsync_mode: i32) -> &'static mut ProcDesc {
unsafe { proc_vsync(vsync_mode, None) }
}
Expand All @@ -23,72 +32,6 @@ impl Proc {
}
}

/// Represents a Instruction unit for a [`Proc`].
///
/// The ProcInst is chained to other ProcInsts to be executed in order by one of the three Proc instances of the game.
///
/// They act as a high-level virtual machine to execute [instructions](crate::proc::ProcDesc) in sequence. Said instructions are queued in a ProcDesc array.
///
/// A lot of classes inherit from it, so implement [`IsProcInst`] on them to represent this relation.
///
/// If it is not possible for some reason, use the [cast](ProcInst::cast) methods to represent the chains as a ProcInst derivate of your choice.
///
/// Example:
///
/// ```
/// pub fn createmenubind_hook(proc: &mut Il2CppObject<ProcInst>) {
/// let casted_child = proc.child.cast_mut::<BasicMenu>();
/// }
/// ```
///
/// Keep in mind that [`IsProcInst`] is much more preferable, and [cast](ProcInst::cast) should only be used as a last resort.
#[repr(C)]
#[unity::class("App", "ProcInst")]
pub struct ProcInst {
descs: &'static mut UnsafeCell<Il2CppArray<&'static mut ProcDesc>>,
pub desc_index: i32,
pub name: Option<&'static Il2CppString>,
pub hashcode: i32,
/// The ProcInst this instance is attached to
pub parent: &'static mut ProcInst,
pub child: Option<&'static mut ProcInst>,
pub prev: Option<&'static mut ProcInst>,
pub next: Option<&'static mut ProcInst>,
/// Note: Observed a ProcVoidMethod being set here
persistent: *const u8,
/// Note: Actually a bitfield to mark ProcInsts for death (to be destroyed)
pub state: i32,
pub suspend: i32,
wait_time: f32,
tick_time: f32,
// RawValueStack
stack: &'static Il2CppObject<RawValueStack>,
}

impl Drop for ProcInst {
fn drop(&mut self) {
panic!("ProcInst dropped");
}
}

impl ProcInst {
pub fn get_descs(&self) -> &Il2CppArray<&'static mut ProcDesc> {
unsafe { &*self.descs.get() }
}

pub fn get_descs_mut(&self) -> &mut Il2CppArray<&'static mut ProcDesc> {
unsafe {&mut *self.descs.get() }
}

pub fn cast<T: AsRef<ProcInstFields>>(&self) -> &T {
unsafe { std::mem::transmute::<&ProcInst, &T>(self) }
}

pub fn cast_mut<T: AsMut<ProcInstFields>>(&mut self) -> &mut T {
unsafe { std::mem::transmute::<&mut ProcInst, &mut T>(self) }
}
}

/// Trait to simulate inheritance for [`ProcInst`].
///
/// If the trait is in scope, it is automatically implemented for objects that implement `AsMut<ProcInst>`.
Expand All @@ -100,9 +43,6 @@ pub trait Bindable {
}
}

impl Bindable for ProcInst { }


#[unity::from_offset("App", "Proc", "WaitIsLoading")]
fn proc_waitisloading(
method_info: OptionalMethod,
Expand All @@ -114,11 +54,21 @@ fn proc_vsync(
method_info: OptionalMethod,
) -> &'static mut ProcDesc;

#[unity::from_offset("App", "Proc", "GetRootHi")]
fn proc_getroothi(
method_info: OptionalMethod,
) -> &'static mut ProcInst;

#[unity::from_offset("App", "Proc", "GetRootDef")]
fn proc_getrootdef(
method_info: OptionalMethod,
) -> &'static mut ProcInst;

#[unity::from_offset("App", "Proc", "GetRootLow")]
fn proc_getrootlow(
method_info: OptionalMethod,
) -> &'static mut ProcInst;

#[unity::from_offset("App", "Proc", "Label")]
fn proc_label(
label: i32,
Expand Down Expand Up @@ -148,17 +98,6 @@ fn proc_end(
method_info: OptionalMethod,
) -> &'static mut ProcDesc;

#[unity::from_offset("App", "ProcInst", "CreateBind")]
pub fn procinst_createbind<T: Bindable + ?Sized, P: Bindable>(
this: &T,
parent: &P,
descs: &'static Il2CppArray<&'static mut ProcDesc>,
name: &'static Il2CppString,
method_info: OptionalMethod,
);

#[unity::from_offset("App", "ProcInst", "OnDispose")]
pub fn procinst_ondispose(this: &ProcInst, method_info: OptionalMethod);

/// A structure representing a call to a method that returns nothing.
#[repr(C)]
Expand Down
108 changes: 108 additions & 0 deletions src/proc/inst.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,108 @@
use std::cell::UnsafeCell;

use unity::prelude::*;

use super::{Bindable, ProcDesc, RawValueStack};

/// Represents a Instruction unit for a [`Proc`].
///
/// The ProcInst is chained to other ProcInsts to be executed in order by one of the three Proc instances of the game.
///
/// They act as a high-level virtual machine to execute [instructions](crate::proc::ProcDesc) in sequence. Said instructions are queued in a ProcDesc array.
///
/// A lot of classes inherit from it, so implement [`IsProcInst`] on them to represent this relation.
///
/// If it is not possible for some reason, use the [cast](ProcInst::cast) methods to represent the chains as a ProcInst derivate of your choice.
///
/// Example:
///
/// ```
/// pub fn createmenubind_hook(proc: &mut Il2CppObject<ProcInst>) {
/// let casted_child = proc.child.cast_mut::<BasicMenu>();
/// }
/// ```
///
/// Keep in mind that [`IsProcInst`] is much more preferable, and [cast](ProcInst::cast) should only be used as a last resort.
#[repr(C)]
#[unity::class("App", "ProcInst")]
pub struct ProcInst {
descs: &'static mut UnsafeCell<Il2CppArray<&'static mut ProcDesc>>,
pub desc_index: i32,
pub name: Option<&'static Il2CppString>,
/// Unique ID derived from the name of the ProcInst.
pub hashcode: i32,
/// The ProcInst this instance is attached to
pub parent: Option<&'static mut ProcInst>,
/// The next ProcInst to process. ProcInsts are processed from child to parent.
pub child: Option<&'static mut ProcInst>,
pub prev: Option<&'static mut ProcInst>,
pub next: Option<&'static mut ProcInst>,
/// Note: Observed a ProcVoidMethod being set here
persistent: *const u8,
/// Note: Actually a bitfield to mark ProcInsts for death (to be destroyed)
pub state: i32,
/// This is supposed to be a bool, but struct alignment said otherwise.
pub suspend: i32,
wait_time: f32,
tick_time: f32,
// RawValueStack
stack: &'static Il2CppObject<RawValueStack>,
}

impl Drop for ProcInst {
fn drop(&mut self) {
panic!("ProcInst dropped");
}
}

impl ProcInst {
pub fn get_child(&'static self) -> &'static ProcInst {
// Ray: yes, this'd crash if null. I'll fix later.
*self.child.as_ref().unwrap()
}

pub fn get_child_mut(&'static mut self) -> &'static mut ProcInst {
// Ray: yes, this'd crash if null. I'll fix later.
*self.child.as_mut().unwrap()
}

pub fn get_next(&'static self) -> &'static ProcInst {
// Ray: yes, this'd crash if null. I'll fix later.
*self.next.as_ref().unwrap()
}

pub fn get_next_mut(&'static mut self) -> &'static mut ProcInst {
// Ray: yes, this'd crash if null. I'll fix later.
*self.next.as_mut().unwrap()
}

pub fn get_descs(&self) -> &Il2CppArray<&'static mut ProcDesc> {
unsafe { &*self.descs.get() }
}

pub fn get_descs_mut(&self) -> &mut Il2CppArray<&'static mut ProcDesc> {
unsafe {&mut *self.descs.get() }
}

pub fn cast<T: AsRef<ProcInstFields>>(&self) -> &T {
unsafe { std::mem::transmute::<&ProcInst, &T>(self) }
}

pub fn cast_mut<T: AsMut<ProcInstFields>>(&mut self) -> &mut T {
unsafe { std::mem::transmute::<&mut ProcInst, &mut T>(self) }
}
}

impl Bindable for ProcInst { }

#[unity::from_offset("App", "ProcInst", "CreateBind")]
pub fn procinst_createbind<T: Bindable + ?Sized, P: Bindable>(
this: &T,
parent: &P,
descs: &'static Il2CppArray<&'static mut ProcDesc>,
name: &'static Il2CppString,
method_info: OptionalMethod,
);

#[unity::from_offset("App", "ProcInst", "OnDispose")]
pub fn procinst_ondispose(this: &ProcInst, method_info: OptionalMethod);

0 comments on commit 759de6d

Please sign in to comment.