read() less, dont use as_mut when as_ref is fine, simplify types by using & instead of *const where applicable

This commit is contained in:
bgkillas 2025-07-09 19:27:27 -04:00
parent 2d1ccfcb43
commit 1ab79d6cb7
4 changed files with 68 additions and 43 deletions

View file

@ -71,12 +71,13 @@ fn get_function_start(func: *const c_void) -> eyre::Result<*const c_void> {
loop {
unsafe {
if it as isize % 16 == 0
&& (it.offset(-1).read() == 0xcc
|| it.offset(-1).read() == 0xc3
|| it.offset(-3).read() == 0xc2)
&& (it.read() >= 0x50 && it.read() < 0x58)
&& ((it.offset(1).read() >= 0x50 && it.offset(1).read() < 0x58)
|| (it.offset(1).read() == 0x8b && it.offset(2).read() == 0xec))
&& (it.offset(-1).as_ref() == Some(&0xcc)
|| it.offset(-1).as_ref() == Some(&0xc3)
|| it.offset(-3).as_ref() == Some(&0xc2))
&& (it.as_ref() >= Some(&0x50) && it.as_ref() < Some(&0x58))
&& ((it.offset(1).as_ref() >= Some(&0x50) && it.offset(1).as_ref() < Some(&0x58))
|| (it.offset(1).as_ref() == Some(&0x8b)
&& it.offset(2).as_ref() == Some(&0xec)))
{
return Ok(it.cast::<c_void>());
}

View file

@ -53,25 +53,18 @@ fn init_particle_world_state(_: LuaState) -> eyre::Result<()> {
let mut state = state.try_borrow_mut()?;
let (construct_ptr, remove_ptr, global_ptr) = init_data::get_functions()?;
let global = unsafe { global_ptr.as_ref() }.wrap_err("no global?")?;
let world_ptr = global.m_game_world.grid_world;
let world_ptr = global.m_grid_world;
let chunk_map = world_ptr.chunk_map.cell_array;
let cell_factory = unsafe {
global
.m_cell_factory
.as_ref()
.wrap_err("no cell factory??")?
let material_list_ptr = global.m_cell_factory.cell_data_ptr;
let material_list = unsafe {
std::slice::from_raw_parts(material_list_ptr, global.m_cell_factory.cell_data_len)
};
let material_list_ptr = cell_factory.cell_data_ptr;
let material_list =
unsafe { std::slice::from_raw_parts(material_list_ptr, cell_factory.cell_data_len) };
let blob_guy = noita_api::raw::cell_factory_get_type("blob_guy".into())? as u16;
state.blob_guy = blob_guy;
let pws = ParticleWorldState {
world_ptr,
chunk_map,
blob_ptr: unsafe { material_list_ptr.offset(blob_guy as isize) },
material_list_ptr,
material_list,
construct_ptr,
remove_ptr,

View file

@ -6,10 +6,10 @@ use rayon::iter::{IndexedParallelIterator, IntoParallelIterator, ParallelIterato
use std::arch::asm;
use std::ffi::c_void;
pub mod ntypes;
#[derive(Debug)]
pub struct ParticleWorldState {
pub world_ptr: *const ntypes::GridWorld,
pub world_ptr: &'static ntypes::GridWorld,
pub chunk_map: &'static [ntypes::ChunkPtr; 512 * 512],
pub material_list_ptr: *const ntypes::CellData,
pub material_list: &'static [ntypes::CellData],
pub blob_ptr: *const ntypes::CellData,
pub construct_ptr: *const c_void,
@ -116,28 +116,25 @@ impl ParticleWorldState {
&mut pixel_array[index as usize].0
}
pub fn get_cell_material_id(&self, cell: &ntypes::Cell) -> u16 {
let offset = unsafe { cell.material_ptr.offset_from(self.material_list_ptr) };
let offset = unsafe {
(cell.material_ptr as *const ntypes::CellData).offset_from(self.material_list.as_ptr())
};
offset as u16
}
pub fn get_cell_type(&self, cell: &ntypes::Cell) -> Option<ntypes::CellType> {
unsafe { Some(cell.material_ptr.as_ref()?.cell_type) }
}
///# Safety
pub unsafe fn encode_area(&self, x: isize, y: isize, chunk: &mut Chunk) -> Result<(), ()> {
let (shift_x, shift_y, pixel_array) = self.set_chunk(x, y)?;
let pixel_array = unsafe { pixel_array.as_mut() }.unwrap();
let pixel_array = unsafe { pixel_array.as_ref() }.unwrap();
let mut modified = false;
for ((i, j), pixel) in (0..CHUNK_SIZE as isize)
.flat_map(|i| (0..CHUNK_SIZE as isize).map(move |j| (i, j)))
.zip(chunk.iter_mut())
{
*pixel = if let Some(cell) = self.get_cell_raw(shift_x + i, shift_y + j, pixel_array)
&& let Some(cell_type) = self.get_cell_type(cell)
{
match cell_type {
*pixel = if let Some(cell) = self.get_cell_raw(shift_x + i, shift_y + j, pixel_array) {
match cell.material_ptr.cell_type {
ntypes::CellType::Liquid => {
if cell.material_ptr == self.blob_ptr {
if std::ptr::eq(cell.material_ptr, self.blob_ptr) {
modified = true;
CellType::Remove
} else {
@ -246,11 +243,11 @@ impl ParticleWorldState {
if let Some(cell) = self.get_cell_raw(
(x.floor() as isize).rem_euclid(512),
(y.floor() as isize).rem_euclid(512),
unsafe { pixel_array.as_mut() }.unwrap(),
unsafe { pixel_array.as_ref() }.unwrap(),
) {
let full = ntypes::FullCell::from(*cell);
noita_api::print!("{full:?}");
noita_api::print!("{:?}", unsafe { cell.material_ptr.as_ref() });
noita_api::print!("{:?}", cell.material_ptr);
} else {
noita_api::print!("mat nil");
}

View file

@ -72,10 +72,16 @@ struct AABB {
bottom_right: Position,
}
#[repr(C)]
#[derive(Debug)]
pub struct GridWorldThreadedVTable {
//TODO find some data maybe
}
#[repr(C)]
#[derive(Debug)]
struct GridWorldThreaded {
grid_world_threaded_vtable: *const c_void,
grid_world_threaded_vtable: &'static GridWorldThreadedVTable,
unknown: [isize; 287],
update_region: AABB,
}
@ -158,6 +164,30 @@ pub enum CellType {
Fire = 4,
}
#[repr(C)]
#[derive(Debug)]
pub struct ExplosionConfig {
//TODO find some data maybe
}
#[allow(clippy::derivable_impls)]
impl Default for ExplosionConfig {
fn default() -> Self {
Self {}
}
}
#[repr(C)]
#[derive(Debug)]
pub struct GridCosmeticParticleConfig {
//TODO find some data maybe
}
#[allow(clippy::derivable_impls)]
impl Default for GridCosmeticParticleConfig {
fn default() -> Self {
Self {}
}
}
#[repr(C)]
#[derive(Debug)]
pub struct CellData {
@ -191,7 +221,7 @@ pub struct CellData {
pub on_fire_flame_material_id: isize,
pub on_fire_smoke_material: StdString,
pub on_fire_smoke_material_id: isize,
pub explosion_config: *const c_void,
pub explosion_config: *const ExplosionConfig,
pub durability: isize,
pub crackability: isize,
pub electrical_conductivity: bool,
@ -274,7 +304,7 @@ pub struct CellData {
pub show_in_creative_mode: bool,
pub is_just_particle_fx: bool,
padding9: [u8; 2],
pub grid_cosmetic_particle_config: *const c_void,
pub grid_cosmetic_particle_config: *const GridCosmeticParticleConfig,
}
impl Default for CellData {
fn default() -> Self {
@ -631,13 +661,13 @@ impl CellVTable {
#[repr(C)]
#[derive(Debug, Clone, Copy)]
pub struct Cell {
pub vtable: *const CellVTable,
pub vtable: &'static CellVTable,
pub hp: isize,
unknown1: [isize; 2],
pub is_burning: bool,
unknown2: [u8; 3],
pub material_ptr: *const CellData,
pub material_ptr: &'static CellData,
}
unsafe impl Sync for Cell {}
unsafe impl Send for Cell {}
@ -651,9 +681,7 @@ pub enum FullCell {
}
impl From<Cell> for FullCell {
fn from(value: Cell) -> Self {
if let Some(mat) = unsafe { value.material_ptr.as_ref() }
&& mat.cell_type == CellType::Liquid
{
if value.material_ptr.cell_type == CellType::Liquid {
FullCell::LiquidCell(*unsafe { value.get_liquid() })
} else {
FullCell::Cell(value)
@ -709,15 +737,21 @@ pub struct CellFactory {
//likely more data
}
#[repr(C)]
#[derive(Debug)]
pub struct Textures {
//TODO find some data maybe
}
#[repr(C)]
#[derive(Debug)]
pub struct GameGlobal {
pub frame_num: usize,
unknown1: [isize; 2],
pub m_game_world: &'static GameWorld,
pub m_grid_world: *const c_void,
pub m_textures: *const c_void,
pub m_cell_factory: *const CellFactory,
pub m_grid_world: &'static GridWorld,
pub m_textures: &'static Textures,
pub m_cell_factory: &'static CellFactory,
unknown2: [isize; 11],
pub pause_state: isize,
}